From ca0ecbd3ab2550a4cf41ddac25de0c9085c6534a Mon Sep 17 00:00:00 2001
From: Kostiantyn Kalynovskyi <kkalynovskyi@mirantis.com>
Date: Tue, 18 Feb 2020 23:53:06 +0000
Subject: [PATCH] Change document labeling

Now document labeling would allow to have same document to be deployed
to different clusters, ephemeral or target at the same type.

Change-Id: Ia1bb618c322c19c4db3c47b3d19c630b61125f5c
---
 pkg/bootstrap/cloudinit/cloud-init.go        | 10 ++++-----
 pkg/bootstrap/cloudinit/cloud-init_test.go   | 22 +++++++++++++-------
 pkg/bootstrap/cloudinit/testdata/secret.yaml | 22 +++++++++++++++-----
 pkg/bootstrap/isogen/command.go              |  3 ++-
 pkg/bootstrap/isogen/testdata/secret.yaml    |  4 ++--
 pkg/document/constants.go                    |  7 +++----
 pkg/document/errors.go                       |  6 +++---
 pkg/remote/remote_direct.go                  |  7 ++++---
 pkg/remote/testdata/base/baremetal.yaml      | 18 ++++++++--------
 pkg/remote/testdata/emptyurl/baremetal.yaml  | 14 ++++++-------
 10 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/pkg/bootstrap/cloudinit/cloud-init.go b/pkg/bootstrap/cloudinit/cloud-init.go
index 164475089..136d2b0d4 100644
--- a/pkg/bootstrap/cloudinit/cloud-init.go
+++ b/pkg/bootstrap/cloudinit/cloud-init.go
@@ -43,11 +43,11 @@ func getDataFromSecret(cfg document.Document, key string) ([]byte, error) {
 }
 
 // GetCloudData reads YAML document input and generates cloud-init data for
-// node (i.e. Cluster API Machine) with bootstrap annotation.
-func GetCloudData(docBundle document.Bundle, bsAnnotation string) ([]byte, []byte, error) {
+// node (i.e. Cluster API Machine) with bootstrap label.
+func GetCloudData(docBundle document.Bundle, bsSelector string) ([]byte, []byte, error) {
 	var userData []byte
 	var netConf []byte
-	docs, err := docBundle.GetByAnnotation(bsAnnotation)
+	docs, err := docBundle.GetByLabel(bsSelector)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -60,8 +60,8 @@ func GetCloudData(docBundle document.Bundle, bsAnnotation string) ([]byte, []byt
 	}
 	if ephemeralCfg == nil {
 		return nil, nil, document.ErrDocNotFound{
-			Annotation: bsAnnotation,
-			Kind:       EphemeralClusterConfKind,
+			Selector: bsSelector,
+			Kind:     EphemeralClusterConfKind,
 		}
 	}
 
diff --git a/pkg/bootstrap/cloudinit/cloud-init_test.go b/pkg/bootstrap/cloudinit/cloud-init_test.go
index 689ede885..5c256b983 100644
--- a/pkg/bootstrap/cloudinit/cloud-init_test.go
+++ b/pkg/bootstrap/cloudinit/cloud-init_test.go
@@ -16,22 +16,22 @@ func TestGetCloudData(t *testing.T) {
 	require.NoError(t, err, "Building Bundle Failed")
 
 	tests := []struct {
-		ann              string
+		selector         string
 		expectedUserData []byte
 		expectedNetData  []byte
 		expectedErr      error
 	}{
 		{
-			ann:              "test=test",
+			selector:         "test=test",
 			expectedUserData: nil,
 			expectedNetData:  nil,
 			expectedErr: document.ErrDocNotFound{
-				Annotation: "test=test",
-				Kind:       "Secret",
+				Selector: "test=test",
+				Kind:     "Secret",
 			},
 		},
 		{
-			ann:              "airshipit.org/clustertype=nodata",
+			selector:         "airshipit.org/ephemeral=false",
 			expectedUserData: nil,
 			expectedNetData:  nil,
 			expectedErr: ErrDataNotSupplied{
@@ -40,7 +40,7 @@ func TestGetCloudData(t *testing.T) {
 			},
 		},
 		{
-			ann:              "test=nodataforcfg",
+			selector:         "test=nodataforcfg",
 			expectedUserData: nil,
 			expectedNetData:  nil,
 			expectedErr: ErrDataNotSupplied{
@@ -49,7 +49,13 @@ func TestGetCloudData(t *testing.T) {
 			},
 		},
 		{
-			ann:              "airshipit.org/clustertype=ephemeral",
+			selector:         "airshipit.org/ephemeral=true",
+			expectedUserData: []byte("cloud-init"),
+			expectedNetData:  []byte("netconfig\n"),
+			expectedErr:      nil,
+		},
+		{
+			selector:         "some-data in (true, True)",
 			expectedUserData: []byte("cloud-init"),
 			expectedNetData:  []byte("netconfig\n"),
 			expectedErr:      nil,
@@ -57,7 +63,7 @@ func TestGetCloudData(t *testing.T) {
 	}
 
 	for _, tt := range tests {
-		actualUserData, actualNetData, actualErr := GetCloudData(bundle, tt.ann)
+		actualUserData, actualNetData, actualErr := GetCloudData(bundle, tt.selector)
 
 		assert.Equal(t, tt.expectedUserData, actualUserData)
 		assert.Equal(t, tt.expectedNetData, actualNetData)
diff --git a/pkg/bootstrap/cloudinit/testdata/secret.yaml b/pkg/bootstrap/cloudinit/testdata/secret.yaml
index d0563b0e4..d6abc1196 100644
--- a/pkg/bootstrap/cloudinit/testdata/secret.yaml
+++ b/pkg/bootstrap/cloudinit/testdata/secret.yaml
@@ -1,8 +1,8 @@
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: ephemeral
+  labels:
+    airshipit.org/ephemeral: "true"
   name: node1-bmc-secret
 type: Opaque
 data:
@@ -13,17 +13,29 @@ stringData:
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: nodata
+  labels:
+    airshipit.org/ephemeral: "false"
   name: node1-bmc-secret1
 type: Opaque
 ---
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
+  labels:
     test: nodataforcfg
   name: node1-bmc-secret2
 type: Opaque
 data:
   foo: bmV0Y29uZmlnCg==
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  labels:
+    some-data: "True"
+  name: node1-bmc-in-secret2
+type: Opaque
+data:
+  netconfig: bmV0Y29uZmlnCg==
+stringData:
+  userdata: cloud-init
diff --git a/pkg/bootstrap/isogen/command.go b/pkg/bootstrap/isogen/command.go
index 80bc92dad..adbf19f4a 100644
--- a/pkg/bootstrap/isogen/command.go
+++ b/pkg/bootstrap/isogen/command.go
@@ -118,7 +118,8 @@ func generateBootstrapIso(
 ) error {
 	cntVol := strings.Split(cfg.Container.Volume, ":")[1]
 	log.Print("Creating cloud-init for ephemeral K8s")
-	userData, netConf, err := cloudinit.GetCloudData(docBundle, document.EphemeralClusterMarker)
+	label := document.EphemeralClusterSelector
+	userData, netConf, err := cloudinit.GetCloudData(docBundle, label)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/bootstrap/isogen/testdata/secret.yaml b/pkg/bootstrap/isogen/testdata/secret.yaml
index ebc6976c3..08a451624 100644
--- a/pkg/bootstrap/isogen/testdata/secret.yaml
+++ b/pkg/bootstrap/isogen/testdata/secret.yaml
@@ -1,8 +1,8 @@
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: ephemeral
+  labels:
+    airshipit.org/ephemeral: "true"
   name: node1-bmc-secret
 type: Opaque
 data:
diff --git a/pkg/document/constants.go b/pkg/document/constants.go
index b5315f747..64a4ddc6e 100644
--- a/pkg/document/constants.go
+++ b/pkg/document/constants.go
@@ -2,8 +2,7 @@ package document
 
 // Document labels and annotations
 const (
-	ClusterType = "clustertype"
-	// TODO (dukov) Replace with constants defined in config module once
-	// module dependency loop has been resolved
-	EphemeralClusterMarker = "airshipit.org/clustertype=ephemeral"
+	BaseAirshipSelector      = "airshipit.org"
+	EphemeralClusterSelector = BaseAirshipSelector + "/ephemeral in (True, true)"
+	TargetClusterSelector    = BaseAirshipSelector + "/target in (True, true)"
 )
diff --git a/pkg/document/errors.go b/pkg/document/errors.go
index 38a4c95fa..be6e09a5f 100644
--- a/pkg/document/errors.go
+++ b/pkg/document/errors.go
@@ -6,10 +6,10 @@ import (
 
 // ErrDocNotFound returned if desired document not found
 type ErrDocNotFound struct {
-	Annotation string
-	Kind       string
+	Selector string
+	Kind     string
 }
 
 func (e ErrDocNotFound) Error() string {
-	return fmt.Sprintf("Document annotated by %s with Kind %s not found", e.Annotation, e.Kind)
+	return fmt.Sprintf("Document filtered by selector %s with Kind %s not found", e.Selector, e.Kind)
 }
diff --git a/pkg/remote/remote_direct.go b/pkg/remote/remote_direct.go
index b31326e28..958be4d3f 100644
--- a/pkg/remote/remote_direct.go
+++ b/pkg/remote/remote_direct.go
@@ -84,9 +84,10 @@ func getRemoteDirectConfig(settings *environment.AirshipCTLSettings) (*config.Re
 		return nil, "", err
 	}
 
+	label := document.EphemeralClusterSelector
 	filter := types.Selector{
 		Gvk:           gvk.FromKind(AirshipHostKind),
-		LabelSelector: document.EphemeralClusterMarker,
+		LabelSelector: label,
 	}
 	docs, err := docBundle.Select(filter)
 	if err != nil {
@@ -94,8 +95,8 @@ func getRemoteDirectConfig(settings *environment.AirshipCTLSettings) (*config.Re
 	}
 	if len(docs) == 0 {
 		return nil, "", document.ErrDocNotFound{
-			Annotation: document.EphemeralClusterMarker,
-			Kind:       AirshipHostKind,
+			Selector: label,
+			Kind:     AirshipHostKind,
 		}
 	}
 
diff --git a/pkg/remote/testdata/base/baremetal.yaml b/pkg/remote/testdata/base/baremetal.yaml
index d74ec0776..f5806fe95 100644
--- a/pkg/remote/testdata/base/baremetal.yaml
+++ b/pkg/remote/testdata/base/baremetal.yaml
@@ -3,7 +3,7 @@ apiVersion: metal3.io/v1alpha1
 kind: BareMetalHost
 metadata:
   labels:
-    airshipit.org/clustertype: ephemeral
+    airshipit.org/ephemeral: "true"
   name: master-0
 spec:
   online: true
@@ -15,8 +15,8 @@ spec:
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: ephemeral
+  labels:
+    airshipit.org/ephemeral: "true"
   name: master-0-bmc-secret
 type: Opaque
 data:
@@ -26,11 +26,11 @@ data:
 apiVersion: metal3.io/v1alpha1
 kind: BareMetalHost
 metadata:
-  annotations:
-    airshipit.org/clustertype: target
+  labels:
+    airshipit.org/target: "true"
   name: master-1
 spec:
-  online: true
+  online: "true"
   bootMACAddress: 01:3b:8b:0c:ec:8b
   bmc:
     address: ipmi://192.168.111.2:6230
@@ -39,11 +39,11 @@ spec:
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: target
+  labels:
+    airshipit.org/target: "true"
   name: master-1-bmc-secret
 type: Opaque
 data:
   username: YWRtaW4=
   password: cGFzc3dvcmQ=
-...
\ No newline at end of file
+...
diff --git a/pkg/remote/testdata/emptyurl/baremetal.yaml b/pkg/remote/testdata/emptyurl/baremetal.yaml
index 6ca921572..51be180ea 100644
--- a/pkg/remote/testdata/emptyurl/baremetal.yaml
+++ b/pkg/remote/testdata/emptyurl/baremetal.yaml
@@ -3,7 +3,7 @@ apiVersion: metal3.io/v1alpha1
 kind: BareMetalHost
 metadata:
   labels:
-    airshipit.org/clustertype: ephemeral
+    airshipit.org/ephemeral: "true"
   name: master-0
 spec:
   online: true
@@ -15,8 +15,8 @@ spec:
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: ephemeral
+  labels:
+    airshipit.org/ephemeral: "true"
   name: master-0-bmc-secret
 type: Opaque
 data:
@@ -26,8 +26,8 @@ data:
 apiVersion: metal3.io/v1alpha1
 kind: BareMetalHost
 metadata:
-  annotations:
-    airshipit.org/clustertype: target
+  labels:
+    airshipit.org/target: "true"
   name: master-1
 spec:
   online: true
@@ -39,8 +39,8 @@ spec:
 apiVersion: v1
 kind: Secret
 metadata:
-  annotations:
-    airshipit.org/clustertype: target
+  labels:
+    airshipit.org/target: "true"
   name: master-1-bmc-secret
 type: Opaque
 data: