Repository: rancher/fleet
Pull request #1143 (2022-11-30 17:29:50)

Limit recursion depth for cluster label replacement in values
Let's merge this after https://github.com/rancher/fleet/pull/671 is in.

* adds recursion depth check to cluster label replacement
* rename "next" to "custom", because it is the value from  the current "targetCustomization"
* extract cluster label replacement string "global.fleet.clusterLabels." into a constant to make it more visible


Patch:
diff --git a/go.mod b/go.mod
index a4d77bee..55611af4 100644
--- a/go.mod
+++ b/go.mod
@@ -33,8 +33,8 @@ replace (
 )
 
 require (
-	github.com/Masterminds/semver/v3 v3.2.0
-	github.com/Masterminds/sprig/v3 v3.2.3
+	github.com/Masterminds/semver/v3 v3.1.1
+	github.com/Masterminds/sprig/v3 v3.2.2
 	github.com/cheggaaa/pb v1.0.29
 	github.com/davecgh/go-spew v1.1.1
 	github.com/evanphx/json-patch v5.6.0+incompatible
@@ -171,7 +171,7 @@ require (
 	github.com/hashicorp/vault/sdk v0.5.2 // indirect
 	github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
 	github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef // indirect
-	github.com/huandu/xstrings v1.3.3 // indirect
+	github.com/huandu/xstrings v1.3.2 // indirect
 	github.com/imdario/mergo v0.3.13 // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -233,7 +233,7 @@ require (
 	go.opencensus.io v0.23.0 // indirect
 	go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect
 	go.uber.org/atomic v1.9.0 // indirect
-	golang.org/x/crypto v0.3.0 // indirect
+	golang.org/x/crypto v0.1.0 // indirect
 	golang.org/x/mod v0.6.0 // indirect
 	golang.org/x/net v0.2.0 // indirect
 	golang.org/x/oauth2 v0.1.0 // indirect
diff --git a/go.sum b/go.sum
index 78541208..af2f808c 100644
--- a/go.sum
+++ b/go.sum
@@ -115,11 +115,11 @@ github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy86
 github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
-github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
-github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
+github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
+github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
 github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc=
 github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
 github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -634,9 +634,9 @@ github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7U
 github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM=
 github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
 github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
-github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@@ -1043,7 +1043,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
 github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
 github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
@@ -1108,6 +1107,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -1117,8 +1117,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
-golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1165,7 +1165,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1228,7 +1227,6 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
@@ -1269,7 +1267,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1375,7 +1372,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1466,7 +1462,6 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
 golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
 golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/pkg/options/calculate.go b/pkg/options/calculate.go
index 6c72a496..df8a86a3 100644
--- a/pkg/options/calculate.go
+++ b/pkg/options/calculate.go
@@ -26,85 +26,85 @@ func DeploymentID(manifest *manifest.Manifest, opts fleet.BundleDeploymentOption
 	return digest + ":" + hex.EncodeToString(h.Sum(nil)), nil
 }
 
-// Merge overrides the 'base' options with the 'next' options, if 'next' is present (pure function)
-func Merge(base, next fleet.BundleDeploymentOptions) fleet.BundleDeploymentOptions { // nolint: gocyclo // business logic
+// Merge overrides the 'base' options with the 'target customization' options, if 'custom' is present (pure function)
+func Merge(base, custom fleet.BundleDeploymentOptions) fleet.BundleDeploymentOptions { // nolint: gocyclo // business logic
 	result := *base.DeepCopy()
-	if next.DefaultNamespace != "" {
-		result.DefaultNamespace = next.DefaultNamespace
-	} else if next.DefaultNamespace == "-" {
+	if custom.DefaultNamespace != "" {
+		result.DefaultNamespace = custom.DefaultNamespace
+	} else if custom.DefaultNamespace == "-" {
 		result.DefaultNamespace = ""
 	}
-	if next.TargetNamespace != "" {
-		result.TargetNamespace = next.TargetNamespace
-	} else if next.TargetNamespace == "-" {
+	if custom.TargetNamespace != "" {
+		result.TargetNamespace = custom.TargetNamespace
+	} else if custom.TargetNamespace == "-" {
 		result.TargetNamespace = ""
 	}
-	if next.ServiceAccount != "" {
-		result.ServiceAccount = next.ServiceAccount
-	} else if next.ServiceAccount == "-" {
+	if custom.ServiceAccount != "" {
+		result.ServiceAccount = custom.ServiceAccount
+	} else if custom.ServiceAccount == "-" {
 		result.ServiceAccount = ""
 	}
-	if next.ServiceAccount != "" {
-		result.ServiceAccount = next.ServiceAccount
-	} else if next.ServiceAccount == "-" {
+	if custom.ServiceAccount != "" {
+		result.ServiceAccount = custom.ServiceAccount
+	} else if custom.ServiceAccount == "-" {
 		result.ServiceAccount = ""
 	}
-	if next.Helm != nil {
+	if custom.Helm != nil {
 		if result.Helm == nil {
 			result.Helm = &fleet.HelmOptions{}
 		}
-		if next.Helm.TimeoutSeconds > 0 {
-			result.Helm.TimeoutSeconds = next.Helm.TimeoutSeconds
-		} else if next.Helm.TimeoutSeconds < 0 {
+		if custom.Helm.TimeoutSeconds > 0 {
+			result.Helm.TimeoutSeconds = custom.Helm.TimeoutSeconds
+		} else if custom.Helm.TimeoutSeconds < 0 {
 			result.Helm.TimeoutSeconds = 0
 		}
 		if result.Helm.Values == nil {
-			result.Helm.Values = next.Helm.Values
-		} else if next.Helm.Values != nil {
-			result.Helm.Values.Data = data.MergeMaps(result.Helm.Values.Data, next.Helm.Values.Data)
+			result.Helm.Values = custom.Helm.Values
+		} else if custom.Helm.Values != nil {
+			result.Helm.Values.Data = data.MergeMaps(result.Helm.Values.Data, custom.Helm.Values.Data)
 		}
-		if next.Helm.ValuesFrom != nil {
-			result.Helm.ValuesFrom = append(result.Helm.ValuesFrom, next.Helm.ValuesFrom...)
+		if custom.Helm.ValuesFrom != nil {
+			result.Helm.ValuesFrom = append(result.Helm.ValuesFrom, custom.Helm.ValuesFrom...)
 		}
-		if next.Helm.Repo != "" {
-			result.Helm.Repo = next.Helm.Repo
+		if custom.Helm.Repo != "" {
+			result.Helm.Repo = custom.Helm.Repo
 		}
-		if next.Helm.Chart != "" {
-			result.Helm.Chart = next.Helm.Chart
+		if custom.Helm.Chart != "" {
+			result.Helm.Chart = custom.Helm.Chart
 		}
-		if next.Helm.Version != "" {
-			result.Helm.Version = next.Helm.Version
+		if custom.Helm.Version != "" {
+			result.Helm.Version = custom.Helm.Version
 		}
-		if next.Helm.ReleaseName != "" {
-			result.Helm.ReleaseName = next.Helm.ReleaseName
+		if custom.Helm.ReleaseName != "" {
+			result.Helm.ReleaseName = custom.Helm.ReleaseName
 		}
-		result.Helm.Force = result.Helm.Force || next.Helm.Force
-		result.Helm.Atomic = result.Helm.Atomic || next.Helm.Atomic
-		result.Helm.TakeOwnership = result.Helm.TakeOwnership || next.Helm.TakeOwnership
-		result.Helm.DisablePreProcess = result.Helm.DisablePreProcess || next.Helm.DisablePreProcess
+		result.Helm.Force = result.Helm.Force || custom.Helm.Force
+		result.Helm.Atomic = result.Helm.Atomic || custom.Helm.Atomic
+		result.Helm.TakeOwnership = result.Helm.TakeOwnership || custom.Helm.TakeOwnership
+		result.Helm.DisablePreProcess = result.Helm.DisablePreProcess || custom.Helm.DisablePreProcess
 	}
-	if next.Kustomize != nil {
+	if custom.Kustomize != nil {
 		if result.Kustomize == nil {
 			result.Kustomize = &fleet.KustomizeOptions{}
 		}
-		if next.Kustomize.Dir != "" {
-			result.Kustomize.Dir = next.Kustomize.Dir
+		if custom.Kustomize.Dir != "" {
+			result.Kustomize.Dir = custom.Kustomize.Dir
 		}
 	}
-	if next.Diff != nil {
+	if custom.Diff != nil {
 		if result.Diff == nil {
 			result.Diff = &fleet.DiffOptions{}
 		}
-		result.Diff.ComparePatches = append(result.Diff.ComparePatches, next.Diff.ComparePatches...)
+		result.Diff.ComparePatches = append(result.Diff.ComparePatches, custom.Diff.ComparePatches...)
 	}
-	if next.YAML != nil {
+	if custom.YAML != nil {
 		if result.YAML == nil {
 			result.YAML = &fleet.YAMLOptions{}
 		}
-		result.YAML.Overlays = append(result.YAML.Overlays, next.YAML.Overlays...)
+		result.YAML.Overlays = append(result.YAML.Overlays, custom.YAML.Overlays...)
 	}
-	if next.ForceSyncGeneration > 0 {
-		result.ForceSyncGeneration = next.ForceSyncGeneration
+	if custom.ForceSyncGeneration > 0 {
+		result.ForceSyncGeneration = custom.ForceSyncGeneration
 	}
 	return result
 }
diff --git a/pkg/target/target.go b/pkg/target/target.go
index 89984370..6c886cd3 100644
--- a/pkg/target/target.go
+++ b/pkg/target/target.go
@@ -42,7 +42,10 @@ var (
 	defMaxUnavailablePartitions = intstr.FromInt(0)
 )
 
-const maxTemplateRecursionDepth = 50
+const (
+	maxTemplateRecursionDepth = 50
+	clusterLabelPrefix        = "global.fleet.clusterLabels."
+)
 
 type Manager struct {
 	clusters                    fleetcontrollers.ClusterCache
@@ -321,7 +324,7 @@ func preprocessHelmValues(opts *fleet.BundleDeploymentOptions, cluster *fleet.Cl
 		return nil
 	}
 
-	if err := processLabelValues(opts.Helm.Values.Data, clusterLabels); err != nil {
+	if err := processLabelValues(opts.Helm.Values.Data, clusterLabels, 0); err != nil {
 		return err
 	}
 
@@ -661,12 +664,15 @@ func templateSubstitutions(src interface{}, templateContext map[string]interface
 	}
 }
 
-func processLabelValues(valuesMap map[string]interface{}, clusterLabels map[string]string) error {
-	prefix := "global.fleet.clusterLabels."
+func processLabelValues(valuesMap map[string]interface{}, clusterLabels map[string]string, recursionDepth int) error {
+	if recursionDepth > maxTemplateRecursionDepth {
+		return fmt.Errorf("maximum recursion depth of %v exceeded for cluster label prefix processing, too many nested values", maxTemplateRecursionDepth)
+	}
+
 	for key, val := range valuesMap {
 		valStr, ok := val.(string)
-		if ok && strings.HasPrefix(valStr, prefix) {
-			label := strings.TrimPrefix(valStr, prefix)
+		if ok && strings.HasPrefix(valStr, clusterLabelPrefix) {
+			label := strings.TrimPrefix(valStr, clusterLabelPrefix)
 			labelVal, labelPresent := clusterLabels[label]
 			if labelPresent {
 				valuesMap[key] = labelVal
@@ -677,7 +683,7 @@ func processLabelValues(valuesMap map[string]interface{}, clusterLabels map[stri
 		}
 
 		if valMap, ok := val.(map[string]interface{}); ok {
-			err := processLabelValues(valMap, clusterLabels)
+			err := processLabelValues(valMap, clusterLabels, recursionDepth+1)
 			if err != nil {
 				return err
 			}
@@ -686,7 +692,7 @@ func processLabelValues(valuesMap map[string]interface{}, clusterLabels map[stri
 		if valArr, ok := val.([]interface{}); ok {
 			for _, item := range valArr {
 				if itemMap, ok := item.(map[string]interface{}); ok {
-					err := processLabelValues(itemMap, clusterLabels)
+					err := processLabelValues(itemMap, clusterLabels, recursionDepth+1)
 					if err != nil {
 						return err
 					}


Test patch:
diff --git a/pkg/target/target_test.go b/pkg/target/target_test.go
index 55b4c5ad..16f3de52 100644
--- a/pkg/target/target_test.go
+++ b/pkg/target/target_test.go
@@ -46,7 +46,7 @@ func TestProcessLabelValues(t *testing.T) {
 		t.Fatalf("error during yaml parsing %v", err)
 	}
 
-	err = processLabelValues(bundle.Helm.Values.Data, clusterLabels)
+	err = processLabelValues(bundle.Helm.Values.Data, clusterLabels, 0)
 	if err != nil {
 		t.Fatalf("error during label processing %v", err)
 	}