From 79bb7112d6906e9664649351bbf0d11e42a8f4f7 Mon Sep 17 00:00:00 2001 From: Jim Ntosas Date: Tue, 20 Feb 2024 16:34:30 +0200 Subject: [PATCH] fix: eks structs allow to be empty Signed-off-by: Jim Ntosas --- charts/capi2argo-cluster-operator/Chart.yaml | 4 +- charts/capi2argo-cluster-operator/values.yaml | 2 +- controllers/argo_cluster.go | 50 ++++++++-------- controllers/argo_cluster_test.go | 59 ++++++++++--------- controllers/capi_cluster.go | 6 +- controllers/capi_cluster_test.go | 27 ++++++--- controllers/constructs_test.go | 11 ++-- tests/capi-kubeconfig-eks.yaml | 8 +-- 8 files changed, 90 insertions(+), 77 deletions(-) diff --git a/charts/capi2argo-cluster-operator/Chart.yaml b/charts/capi2argo-cluster-operator/Chart.yaml index 33a2519e..25443b9f 100644 --- a/charts/capi2argo-cluster-operator/Chart.yaml +++ b/charts/capi2argo-cluster-operator/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -appVersion: 0.2.0 +appVersion: 0.2.1 description: Capi-2-Argo Cluster Operator (CACO) converts ClusterAPI Cluster credentials into ArgoCD Cluster definitions and keep them synchronized. home: https://github.com/dntosas/capi2argo-cluster-operator keywords: @@ -11,7 +11,7 @@ maintainers: name: capi2argo-cluster-operator sources: - https://github.com/dntosas/capi2argo-cluster-operator -version: 0.2.0 +version: 0.2.1 dependencies: - name: common repository: "https://charts.bitnami.com/bitnami" diff --git a/charts/capi2argo-cluster-operator/values.yaml b/charts/capi2argo-cluster-operator/values.yaml index 321717c4..8f41f744 100644 --- a/charts/capi2argo-cluster-operator/values.yaml +++ b/charts/capi2argo-cluster-operator/values.yaml @@ -12,7 +12,7 @@ replicaCount: 1 image: registry: ghcr.io repository: dntosas/capi2argo-cluster-operator - tag: v0.2.0 + tag: v0.2.1 pullPolicy: Always pullSecrets: [] diff --git a/controllers/argo_cluster.go b/controllers/argo_cluster.go index f08ecd73..087a5a3b 100644 --- a/controllers/argo_cluster.go +++ b/controllers/argo_cluster.go @@ -3,9 +3,9 @@ package controllers import ( - b64 "encoding/base64" + // b64 "encoding/base64" "encoding/json" - "errors" + // "errors" "fmt" "strings" @@ -49,15 +49,15 @@ type ArgoCluster struct { // ArgoConfig represents Argo Cluster.JSON.config type ArgoConfig struct { - TLSClientConfig ArgoTLS `json:"tlsClientConfig"` - BearerToken string `json:"bearerToken"` + TLSClientConfig *ArgoTLS `json:"tlsClientConfig,omitempty"` + BearerToken *string `json:"bearerToken,omitempty"` } // ArgoTLS represents Argo Cluster.JSON.config.tlsClientConfig type ArgoTLS struct { - CaData string `json:"caData"` - CertData string `json:"certData"` - KeyData string `json:"keyData"` + CaData *string `json:"caData,omitempty"` + CertData *string `json:"certData,omitempty"` + KeyData *string `json:"keyData,omitempty"` } // NewArgoCluster return a new ArgoCluster @@ -83,8 +83,8 @@ func NewArgoCluster(c *CapiCluster, s *corev1.Secret, cluster *clusterv1.Cluster TakeAlongLabels: takeAlongLabels, ClusterConfig: ArgoConfig{ BearerToken: c.KubeConfig.Users[0].User.Token, - TLSClientConfig: ArgoTLS{ - CaData: c.KubeConfig.Clusters[0].Cluster.CaData, + TLSClientConfig: &ArgoTLS{ + CaData: &c.KubeConfig.Clusters[0].Cluster.CaData, CertData: c.KubeConfig.Users[0].User.CertData, KeyData: c.KubeConfig.Users[0].User.KeyData, }, @@ -162,9 +162,9 @@ func BuildClusterName(s string, namespace string) string { // ConvertToSecret converts an ArgoCluster into k8s native secret object. func (a *ArgoCluster) ConvertToSecret() (*corev1.Secret, error) { - if err := ValidateClusterTLSConfig(&a.ClusterConfig.TLSClientConfig); err != nil { - return nil, err - } + // if err := ValidateClusterTLSConfig(&a.ClusterConfig.TLSClientConfig); err != nil { + // return nil, err + // } c, err := json.Marshal(a.ClusterConfig) if err != nil { return nil, err @@ -201,16 +201,16 @@ func (a *ArgoCluster) ConvertToSecret() (*corev1.Secret, error) { } // ValidateClusterTLSConfig validates that we got proper based64 k/v fields. -func ValidateClusterTLSConfig(a *ArgoTLS) error { - for _, v := range []string{a.CaData, a.CertData, a.KeyData} { - // Check if field.value is empty - if v == "" { - return errors.New("missing key on ArgoTLS config") - } - // Check if field.value is valid b64 encoded string - if _, err := b64.StdEncoding.DecodeString(v); err != nil { - return err - } - } - return nil -} +// func ValidateClusterTLSConfig(a *ArgoTLS) error { +// for _, v := range []string{a.CaData, a.CertData, a.KeyData} { +// // Check if field.value is empty +// if v == "" { +// return errors.New("missing key on ArgoTLS config") +// } +// // Check if field.value is valid b64 encoded string +// if _, err := b64.StdEncoding.DecodeString(v); err != nil { +// return err +// } +// } +// return nil +// } diff --git a/controllers/argo_cluster_test.go b/controllers/argo_cluster_test.go index 0120aa90..bd4075ca 100644 --- a/controllers/argo_cluster_test.go +++ b/controllers/argo_cluster_test.go @@ -1,7 +1,7 @@ package controllers import ( - b64 "encoding/base64" + // b64 "encoding/base64" "fmt" "testing" @@ -160,7 +160,7 @@ func TestConvertToSecret(t *testing.T) { "NamespaceLabel": "test", }, }, - {"test type with non-valid fields", MockArgoCluster(!validMock), true, nil}, + // {"test type with non-valid fields", MockArgoCluster(!validMock), true, nil}, } for _, tt := range tests { tt := tt @@ -190,34 +190,35 @@ func TestConvertToSecret(t *testing.T) { } } -func TestValidateClusterTLSConfig(t *testing.T) { - // Create a dummy valid b64 string - enc := b64.StdEncoding.EncodeToString([]byte("test")) +// func TestValidateClusterTLSConfig(t *testing.T) { +// // Create a dummy valid b64 string +// enc := b64.StdEncoding.EncodeToString([]byte("test")) +// nonValid := "non-valid" - t.Parallel() - tests := []struct { - testName string - testMock *ArgoTLS - testExpectedError bool - }{ - {"test type with valid fields", &ArgoTLS{CaData: enc, CertData: enc, KeyData: enc}, false}, - {"test type with non-valid field", &ArgoTLS{CaData: "non-valid", CertData: enc, KeyData: enc}, true}, - {"test type with missing fields", &ArgoTLS{CaData: enc}, true}, - {"test empty type", &ArgoTLS{}, true}, - } - for _, tt := range tests { - tt := tt - t.Run(tt.testName, func(t *testing.T) { - t.Parallel() - err := ValidateClusterTLSConfig(tt.testMock) - if !tt.testExpectedError { - assert.Nil(t, err) - } else { - assert.NotNil(t, err) - } - }) - } -} +// t.Parallel() +// tests := []struct { +// testName string +// testMock *ArgoTLS +// testExpectedError bool +// }{ +// {"test type with valid fields", &ArgoTLS{CaData: &enc, CertData: &enc, KeyData: &enc}, false}, +// {"test type with non-valid field", &ArgoTLS{CaData: &nonValid, CertData: &enc, KeyData: &enc}, true}, +// {"test type with missing fields", &ArgoTLS{CaData: &enc}, true}, +// {"test empty type", &ArgoTLS{}, true}, +// } +// for _, tt := range tests { +// tt := tt +// t.Run(tt.testName, func(t *testing.T) { +// t.Parallel() +// err := ValidateClusterTLSConfig(tt.testMock) +// if !tt.testExpectedError { +// assert.Nil(t, err) +// } else { +// assert.NotNil(t, err) +// } +// }) +// } +// } func TestBuildNamespacedName(t *testing.T) { t.Parallel() diff --git a/controllers/capi_cluster.go b/controllers/capi_cluster.go index 1598af28..52de227c 100644 --- a/controllers/capi_cluster.go +++ b/controllers/capi_cluster.go @@ -46,9 +46,9 @@ type User struct { // UserInfo represents kubeconfig.[]Users.User fields. type UserInfo struct { - CertData string `yaml:"client-certificate-data"` - KeyData string `yaml:"client-key-data"` - Token string `yaml:"token"` + CertData *string `yaml:"client-certificate-data,omitempty"` + KeyData *string `yaml:"client-key-data,omitempty"` + Token *string `yaml:"token,omitempty"` } // NewCapiCluster returns an empty CapiCluster type. diff --git a/controllers/capi_cluster_test.go b/controllers/capi_cluster_test.go index 5f453404..97bfe04b 100644 --- a/controllers/capi_cluster_test.go +++ b/controllers/capi_cluster_test.go @@ -35,6 +35,7 @@ func TestUnmarshal(t *testing.T) { "CaData": "", "KeyData": "dGVzdGVyCg==", "Server": "https://kube-cluster-test.domain.com:6443", + "Token": "e", }, }, {"test type with wrong secret.Data[key]", MockCapiSecret(validMock, validType, !validKey, name, namespace), true, @@ -65,14 +66,24 @@ func TestUnmarshal(t *testing.T) { assert.Equal(t, tt.testExpectedValues["Server"], c.KubeConfig.Clusters[0].Cluster.Server) assert.Equal(t, tt.testExpectedValues["UserName"], c.KubeConfig.Users[0].Name) // Check that we get proper binary values for specific fields. - assert.Eventually(t, func() bool { - _, err := b64.StdEncoding.DecodeString(c.KubeConfig.Users[0].User.CertData) - return err == nil - }, time.Second, 100*time.Millisecond) - assert.Eventually(t, func() bool { - _, err := b64.StdEncoding.DecodeString(c.KubeConfig.Users[0].User.KeyData) - return err == nil - }, time.Second, 100*time.Millisecond) + if c.KubeConfig.Users[0].User.CertData != nil { + assert.Eventually(t, func() bool { + _, err := b64.StdEncoding.DecodeString(*c.KubeConfig.Users[0].User.CertData) + return err == nil + }, time.Second, 100*time.Millisecond) + } + if c.KubeConfig.Users[0].User.KeyData != nil { + assert.Eventually(t, func() bool { + _, err := b64.StdEncoding.DecodeString(*c.KubeConfig.Users[0].User.KeyData) + return err == nil + }, time.Second, 100*time.Millisecond) + } + if c.KubeConfig.Users[0].User.Token != nil { + assert.Eventually(t, func() bool { + _, err := b64.StdEncoding.DecodeString(*c.KubeConfig.Users[0].User.Token) + return err == nil + }, time.Second, 100*time.Millisecond) + } assert.Eventually(t, func() bool { _, err := b64.StdEncoding.DecodeString(c.KubeConfig.Clusters[0].Cluster.CaData) return err == nil diff --git a/controllers/constructs_test.go b/controllers/constructs_test.go index fece1523..41bb5633 100644 --- a/controllers/constructs_test.go +++ b/controllers/constructs_test.go @@ -12,7 +12,7 @@ import ( // MockCapiKubeConfig returns a based64-encoded string that // represents a valid KubeConfig definition. func MockCapiKubeConfig() string { - RawKubeConfig, err := os.ReadFile("../tests/capi-kubeconfig.yaml") + RawKubeConfig, err := os.ReadFile("../tests/capi-kubeconfig-eks.yaml") if err != nil { log.Fatal(err) } @@ -86,10 +86,11 @@ func MockArgoCluster(validMock bool) *ArgoCluster { "capi-to-argocd/cluster-namespace": "test", }, ClusterConfig: ArgoConfig{ - TLSClientConfig: ArgoTLS{ - CaData: v, - CertData: v, - KeyData: v, + BearerToken: &v, + TLSClientConfig: &ArgoTLS{ + CaData: &v, + CertData: &v, + KeyData: &v, }, }, } diff --git a/tests/capi-kubeconfig-eks.yaml b/tests/capi-kubeconfig-eks.yaml index 2b24877b..4304b6b9 100644 --- a/tests/capi-kubeconfig-eks.yaml +++ b/tests/capi-kubeconfig-eks.yaml @@ -2,10 +2,10 @@ apiVersion: v1 kind: Config clusters: - cluster: - certificate-authority-data: test - server: https://test.gr7.eu-west-1.eks.amazonaws.com - name: test-cluster + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZQakNDQXlZQ0NRQzdpdEhkeVZqN3ZUQU5CZ2txaGtpRzl3MEJBUXNGQURCaE1Rc3dDUVlEVlFRR0V3SngKY1RFTE1Ba0dBMVVFQ0F3Q2NYRXhDekFKQmdOVkJBY01BbkZ4TVFzd0NRWURWUVFLREFKeGNURUxNQWtHQTFVRQpDd3dDY1hFeEN6QUpCZ05WQkFNTUFuRnhNUkV3RHdZSktvWklodmNOQVFrQkZnSnhjVEFlRncweU1qQXlNVE14Ck56RXpNRGRhRncweU16QXlNVE14TnpFek1EZGFNR0V4Q3pBSkJnTlZCQVlUQW5GeE1Rc3dDUVlEVlFRSURBSngKY1RFTE1Ba0dBMVVFQnd3Q2NYRXhDekFKQmdOVkJBb01BbkZ4TVFzd0NRWURWUVFMREFKeGNURUxNQWtHQTFVRQpBd3dDY1hFeEVUQVBCZ2txaGtpRzl3MEJDUUVXQW5GeE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBCk1JSUNDZ0tDQWdFQWxwRVdMMmtMZVk0dndVWGlBVW9lOHpuRmhuSlBNK0lpSVpyREZab2VsRHp3QU1rWDIxK3kKVW84a1lFVUduWnYwZ3Q4dE03VlVZUE5qSjh0VUxzcXl3RWR5V0FKUUFDY2FaZU1XYzdqc2pUT0Z4dGwxaVJrTgpxNzkwSVNBMHlnbzU0eWIzVEk4T3pQNTcyRFVNODF5Y3NDSWxFYkhWeEZCanQvTVh6ZDc0S1hlTHh6cDB3L1NzCm82Vk12MXlpeDc0cCtxclJCSWJsMUovSm5TRWxrOFBjNXdQeC93VFY1alpLbUcvUkdmNDRPUHAxMGx0WEo0QmgKcHB3ZExsWUpIRlYzUmp4YXZTL2c1UjVWZE1tdUZHU3Y0Um1VY01xRTNTbDZpdlhya01iZHIzT0JZNUw0YTkzYQo5clBtUEpRalYrbVJLbXBDeW1iWTZERXllTkJxRzJYTjNpQW84UDhxZVI1akRMdldTZjlDZW1xaXNPT3Y5Y1pHCjI1WmJjM09wbHo3dmZnTHhsRTVZb0tySWQ3cE9WOGNkQVUrcHdyblRRZG9MSmI2RVd0dUdYK05ROEFpL2NvZVAKT2dJNG9KUHVJam90YXFHRm1MSW9QQU5uOGZrVElCdmpsNDFOaE1tTG1ENzU2OVFVcW94WW41MGl4YVpFZnl1Tgovd0lIWjFrTk01ZDBsNjhkcXpvL0Q1eXZFRDFQVWp1RWp6RUJaQUVvamhlM3VtU2s5KzVHOUxKSDNwZmZudXZzCjJpSm5JQ2hYWEFjd1JMNkN4c3QzQ3djbXBLekp1YWsxelhJQVgyTnJmSFRSLytpTHBHZStpL3NaQUIydGg2S1EKMTVPb1JjSG5KQnR4ZCt6Rk9UOWw2QzRVWnZwVzZmMlBaaVBacTlMOGM1elRQckNYZHA0anpQVUNBd0VBQVRBTgpCZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFEUHpTREwzNndzY2pBS3hKOVo1TVMvWVlSMWVqSXpRRnIweUlramowCjhjTzllaEVXZmswekprb1RLTDNRS1psRlkydGhURk5YamVmbXFoTDU0amF6V1lFQWlEdXRMREIyamdYRmZkV2MKVDJuUGZCUnlzeGE4YW5TQWNyaHArQXd2RWdoRUZiYitnTzlucEw1bXlXYytwcGlkbUh6bTBtZ0dZZ3pUWmYzdAp2dUsrVzdQbjBWY3NUVE4xd2w5SFRDS2RmU1FMVDIrM0wyWmg3cjN1T3JxR0ZIUU1BY2R1Z2svV0VpTEhhVjFOCkNPSG5nMENhUHlNR2pxOXRNT1ZPaWtGeEM5d1kvelJhM2pVQ2hpcW00VlU0dEc1VVR5U0RGZnRZQnpzMUhiREQKdWZlWGVmQWl0OWFyZjZ2VGtSR09QVVJTbS9xZUllQlU3WXJxUmlMVXp6K2hPOUs0TjlzNkhNK05YQ2tIUS9jUAorWkZnWVFHQ0E0WE9wM05GMlhud3QxMFZwVDdCU3Rva3BLZ2cwdTJ3a2hkYUVObjZJUXNkSzloeW5IMUZNRlNyClhsQVZZcnJvTDArOVMxblpOcTlSazRHVEV3WG0rWkIxRWF6R2dNYW1hVU5rN2lzUjR2QkpScUs2TVlZQWM5bmkKNzA3bzBLbHZKbW1hZDdrOVY1UnVwOWhLelRpem9jMzdiS1ZaVkE4aVE1eXRVSkVvdFZwMUd4RHVZcFlBb3lpYwpZNXQyaXhsYjVXOVYvSXhKaUlqTU9VamduZTJMR292NE82Mng2L3M2QjVtaUFIOVVIc0lTTjQyVW8rTThiNWJBCkh1bE8zb3F3bHBSaWQ5S0FDVHJBeDFwbjVXcWlsN2RzTXoyMzAwdVBGblgxVkxFZ1JJOXNzblA0UFpjKzl5VnIKLzZ3PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + server: https://kube-cluster-test.domain.com:6443 + name: kube-cluster-test users: -- name: test-cluster-capi-admin +- name: kube-cluster-test-admin user: token: test \ No newline at end of file