Repository: keikoproj/instance-manager (go)

Issue:
Add node label referencing the AMI
Nodes payload currently does not reference the AMI in use, it might be nice to add a label to the node objects referencing the AMI it is using.

e.g. `instancemgr.keikoproj.io/image-id: ami-123456789012`

We should evaluate how to make this change considering `--node-relabel` flag, which turns off the watch on nodes.

Pull request description:
feat: add image default label to nodes
Signed-off-by: Eytan Avisror <eytan_avisror@intuit.com>

Fixes #262

Patch:
diff --git a/api/v1alpha1/instancegroup_types.go b/api/v1alpha1/instancegroup_types.go
index 89a5e0e..196d25f 100644
--- a/api/v1alpha1/instancegroup_types.go
+++ b/api/v1alpha1/instancegroup_types.go
@@ -700,6 +700,9 @@ func (h LifecycleHookSpec) ExistInSlice(hooks []LifecycleHookSpec) bool {
 	}
 	return false
 }
+func (c *EKSConfiguration) GetImage() string {
+	return c.Image
+}
 func (c *EKSConfiguration) GetInstanceProfileName() string {
 	return c.ExistingInstanceProfileName
 }
diff --git a/controllers/provisioners/eks/eks.go b/controllers/provisioners/eks/eks.go
index 98917b5..cf27041 100644
--- a/controllers/provisioners/eks/eks.go
+++ b/controllers/provisioners/eks/eks.go
@@ -50,7 +50,7 @@ var (
 	RoleOldLabel              = "node-role.kubernetes.io/%s"
 	RoleOldLabelFmt           = "node-role.kubernetes.io/%s=\"\""
 	InstanceMgrLifecycleLabel = "instancemgr.keikoproj.io/lifecycle"
-	InstanceMgrLabelFmt       = "instancemgr.keikoproj.io/%s=%s"
+	InstanceMgrImageLabel     = "instancemgr.keikoproj.io/image"
 
 	DefaultManagedPolicies = []string{"AmazonEKSWorkerNodePolicy", "AmazonEC2ContainerRegistryReadOnly"}
 	CNIManagedPolicy       = "AmazonEKS_CNI_Policy"
diff --git a/controllers/provisioners/eks/helpers.go b/controllers/provisioners/eks/helpers.go
index aea37bf..b5e422d 100644
--- a/controllers/provisioners/eks/helpers.go
+++ b/controllers/provisioners/eks/helpers.go
@@ -440,6 +440,8 @@ func (ctx *EksInstanceGroupContext) GetComputedLabels() map[string]string {
 		labelMap[InstanceMgrLifecycleLabel] = v1alpha1.LifecycleStateMixed
 	}
 
+	labelMap[InstanceMgrImageLabel] = configuration.GetImage()
+
 	return labelMap
 }
 


Test patch:
diff --git a/controllers/provisioners/eks/eks_test.go b/controllers/provisioners/eks/eks_test.go
index 3f81cc4..c9fe0d5 100644
--- a/controllers/provisioners/eks/eks_test.go
+++ b/controllers/provisioners/eks/eks_test.go
@@ -133,6 +133,7 @@ func MockInstanceGroup() *v1alpha1.InstanceGroup {
 				MaxSize: 3,
 				MinSize: 1,
 				EKSConfiguration: &v1alpha1.EKSConfiguration{
+					Image:          "ami-123456789012",
 					EksClusterName: "my-cluster",
 					InstanceType:   "m5.large",
 					SuspendedProcesses: []string{
diff --git a/controllers/provisioners/eks/helpers_test.go b/controllers/provisioners/eks/helpers_test.go
index 36de578..304fa8a 100644
--- a/controllers/provisioners/eks/helpers_test.go
+++ b/controllers/provisioners/eks/helpers_test.go
@@ -145,7 +145,7 @@ mkdir /mnt/foo
 mount /dev/xvda /mnt/foo
 mount
 set -o xtrace
-/etc/eks/bootstrap.sh foo --use-max-pods false --kubelet-extra-args '--node-labels=foo=bar,node.kubernetes.io/role=instance-group-1 --register-with-taints=foo=bar:NoSchedule --eviction-hard=memory.available<300Mi,nodefs.available<5% --system-reserved=memory=2.5Gi --v=2 --max-pods=4'
+/etc/eks/bootstrap.sh foo --use-max-pods false --kubelet-extra-args '--node-labels=foo=bar,instancemgr.keikoproj.io/image=ami-123456789012,node.kubernetes.io/role=instance-group-1 --register-with-taints=foo=bar:NoSchedule --eviction-hard=memory.available<300Mi,nodefs.available<5% --system-reserved=memory=2.5Gi --v=2 --max-pods=4'
 set +o xtrace
 bar`
 	userData := ctx.GetBasicUserData("foo", args, kubeletArgs, userDataPayload, mounts)
@@ -447,13 +447,14 @@ func TestGetLabelList(t *testing.T) {
 		eksMock                    = NewEksMocker()
 		ec2Mock                    = NewEc2Mocker()
 		defaultLifecycleLabel      = "instancemgr.keikoproj.io/lifecycle=normal"
-		expectedLabels115          = []string{defaultLifecycleLabel, "node-role.kubernetes.io/instance-group-1=\"\"", "node.kubernetes.io/role=instance-group-1"}
-		expectedLabels116          = []string{defaultLifecycleLabel, "node.kubernetes.io/role=instance-group-1"}
-		expectedLabelsWithCustom   = []string{defaultLifecycleLabel, "custom.kubernetes.io=customlabel", "node.kubernetes.io/role=instance-group-1"}
-		expectedLabelsWithOverride = []string{defaultLifecycleLabel, "custom.kubernetes.io=customlabel", "override.kubernetes.io=instance-group-1", "override2.kubernetes.io=instance-group-1"}
+		defaultImageLabel          = fmt.Sprintf("instancemgr.keikoproj.io/image=%v", configuration.GetImage())
+		expectedLabels115          = []string{defaultImageLabel, defaultLifecycleLabel, "node-role.kubernetes.io/instance-group-1=\"\"", "node.kubernetes.io/role=instance-group-1"}
+		expectedLabels116          = []string{defaultImageLabel, defaultLifecycleLabel, "node.kubernetes.io/role=instance-group-1"}
+		expectedLabelsWithCustom   = []string{defaultImageLabel, defaultLifecycleLabel, "custom.kubernetes.io=customlabel", "node.kubernetes.io/role=instance-group-1"}
+		expectedLabelsWithOverride = []string{defaultImageLabel, defaultLifecycleLabel, "custom.kubernetes.io=customlabel", "override.kubernetes.io=instance-group-1", "override2.kubernetes.io=instance-group-1"}
 		overrideAnnotation         = map[string]string{OverrideDefaultLabelsAnnotation: "override.kubernetes.io=instance-group-1,override2.kubernetes.io=instance-group-1"}
-		expectedSpotLabel          = []string{"instancemgr.keikoproj.io/lifecycle=spot", "node-role.kubernetes.io/instance-group-1=\"\"", "node.kubernetes.io/role=instance-group-1"}
-		expectedMixedLabel         = []string{"instancemgr.keikoproj.io/lifecycle=mixed", "node-role.kubernetes.io/instance-group-1=\"\"", "node.kubernetes.io/role=instance-group-1"}
+		expectedSpotLabel          = []string{defaultImageLabel, "instancemgr.keikoproj.io/lifecycle=spot", "node-role.kubernetes.io/instance-group-1=\"\"", "node.kubernetes.io/role=instance-group-1"}
+		expectedMixedLabel         = []string{defaultImageLabel, "instancemgr.keikoproj.io/lifecycle=mixed", "node-role.kubernetes.io/instance-group-1=\"\"", "node.kubernetes.io/role=instance-group-1"}
 	)
 
 	w := MockAwsWorker(asgMock, iamMock, eksMock, ec2Mock)