Repository: keikoproj/instance-manager (go)

Issue:
Conditional restricted fields are not applied if the last applicable rule did not set the field. 
**Is this a BUG REPORT or FEATURE REQUEST?**:
BUG
**What happened**:
When there are multiple conditional rules, fields are set from the default rule if the field was not set in the last conditional rule.
 
**What you expected to happen**:

**How to reproduce it (as minimally and precisely as possible)**:
```yaml
mockBoundaries := `
    restricted:
    - spec.eks.configuration.keyPairName
    - spec.eks.configuration.taints
    - spec.eks.configuration.labels
    - spec.eks.configuration.securityGroups
    - spec.eks.configuration.instanceType
    - spec.eks.configuration.image
    - spec.strategy`

mockConditionals := `
- annotationSelector: "instancemgr.keikoproj.io/os-family=windows"
  defaults:
    spec:
      eks:
        configuration:
          image: ami-22222222222
- annotationSelector: "instancemgr.keikoproj.io/arch in (arm64), instancemgr.keikoproj.io/os-family in (windows)"
  defaults:
    spec:
      eks:
        configuration:
          image: ami-33333333333
- annotationSelector: "instancemgr.keikoproj.io/arch in (arm64), instancemgr.keikoproj.io/os-family in (windows)"
  defaults:
    spec:
      eks:
        configuration:
          foo: bar

mockDefaults := `
spec:
  strategy:
    type: rollingUpdate
    rollingUpdate:
      maxUnavailable: 30%
  eks:
    configuration:
      keyPairName: TestKeyPair
      image: ami-025bf02d663404bbc
      securityGroups:
      - sg-123456789012
      instanceType: m5.large
      labels:
        label-key: label-value
      taints:
      - key: taint-key
        value: taint-value
        effect: NoSchedule`
```          
With the following setup, a IG that passes the `instancemgr.keikoproj.io/arch in (arm64), instancemgr.keikoproj.io/os-family in (windows)` selector would have the base image, ami-025bf02d663404bbc, applied - which is not expected. It is expected in this case that ami-33333333333 would be applied. 


Pull request:
fix: only set restricted field to default value if none of the conditionals set it
fixes #283 

Signed-off-by: Jonah Back <jonah@jonahback.com>

Patch:
diff --git a/controllers/provisioners/config.go b/controllers/provisioners/config.go
index a9eb382..dd2da00 100644
--- a/controllers/provisioners/config.go
+++ b/controllers/provisioners/config.go
@@ -168,17 +168,17 @@ func (c *ProvisionerConfiguration) setRestrictedFields(unstructuredInstanceGroup
 	for _, pathStr := range c.Boundaries.Restricted {
 		path := common.FieldPath(pathStr)
 		// if a default value exists for the path, set it on the instance group
-		var setField = false
-		var field interface{}
+		var setFieldInAnyConditional = false
 		for _, conditional := range applicableConditionals {
-			if field, setField, _ = unstructured.NestedFieldCopy(conditional.Defaults, path...); setField {
+			if field, setField, _ := unstructured.NestedFieldCopy(conditional.Defaults, path...); setField {
+				setFieldInAnyConditional = true
 				err := unstructured.SetNestedField(unstructuredInstanceGroup, field, path...)
 				if err != nil {
 					errors.Wrap(err, "failed to set nested field")
 				}
 			}
 		}
-		if setField {
+		if setFieldInAnyConditional {
 			continue
 		}
 		if field, ok, _ := unstructured.NestedFieldCopy(c.Defaults, path...); ok {


Test patch:
diff --git a/controllers/provisioners/config_test.go b/controllers/provisioners/config_test.go
index caa1fa9..c03e51c 100644
--- a/controllers/provisioners/config_test.go
+++ b/controllers/provisioners/config_test.go
@@ -193,12 +193,18 @@ func TestSetDefaultsWithRestrictedConditional(t *testing.T) {
       eks:
         configuration:
           image: ami-22222222222
-- annotationSelector: "instancemgr.keikoproj.io/arch=arm64"
+- annotationSelector: "instancemgr.keikoproj.io/arch in (arm64), instancemgr.keikoproj.io/os-family in (windows)"
   defaults:
     spec:
       eks:
         configuration:
           image: ami-33333333333
+- annotationSelector: "instancemgr.keikoproj.io/arch in (arm64), instancemgr.keikoproj.io/os-family in (windows)"
+  defaults:
+    spec:
+      eks:
+        configuration:
+          foo: bar
 `
 
 	mockDefaults := `