diff --git a/api/v1alpha1/clusterconfig_types.go b/api/v1alpha1/clusterconfig_types.go index 9e02d363e..3e238f2b2 100644 --- a/api/v1alpha1/clusterconfig_types.go +++ b/api/v1alpha1/clusterconfig_types.go @@ -31,12 +31,20 @@ const ( CCMProviderNutanix = "nutanix" ) -var DefaultDockerCertSANs = []string{ - "localhost", - "127.0.0.1", - "0.0.0.0", - "host.docker.internal", -} +var ( + DefaultDockerCertSANs = []string{ + "localhost", + "127.0.0.1", + "0.0.0.0", + "host.docker.internal", + } + + DefaultNutanixCertSANs = []string{ + "localhost", + "127.0.0.1", + "0.0.0.0", + } +) // +kubebuilder:object:root=true @@ -272,8 +280,10 @@ func (ExtraAPIServerCertSANs) VariableSchema() clusterv1.VariableSchema { return clusterv1.VariableSchema{ OpenAPIV3Schema: clusterv1.JSONSchemaProps{ Description: fmt.Sprintf( - "Extra Subject Alternative Names for the API Server signing cert. For Docker %s are injected automatically.", + //nolint:lll // its a user facing message + "Subject Alternative Names for the API Server signing cert. For Docker %s are injected automatically. For Nutanix %s are injected automatically.", strings.Join(DefaultDockerCertSANs, ","), + strings.Join(DefaultNutanixCertSANs, ","), ), Type: "array", UniqueItems: true, diff --git a/charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/nutanix-cluster-class.yaml b/charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/nutanix-cluster-class.yaml index 61c04f53d..9071330d4 100644 --- a/charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/nutanix-cluster-class.yaml +++ b/charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/nutanix-cluster-class.yaml @@ -122,10 +122,6 @@ spec: kubeadmConfigSpec: clusterConfiguration: apiServer: - certSANs: - - localhost - - 127.0.0.1 - - 0.0.0.0 extraArgs: cloud-provider: external tls-cipher-suites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 diff --git a/hack/examples/bases/nutanix/clusterclass/kustomization.yaml.tmpl b/hack/examples/bases/nutanix/clusterclass/kustomization.yaml.tmpl index 42ec27165..e837f403a 100644 --- a/hack/examples/bases/nutanix/clusterclass/kustomization.yaml.tmpl +++ b/hack/examples/bases/nutanix/clusterclass/kustomization.yaml.tmpl @@ -30,6 +30,12 @@ patches: - op: "remove" path: "/spec/variables" +- target: + kind: KubeadmControlPlaneTemplate + patch: |- + - op: "remove" + path: "/spec/template/spec/kubeadmConfigSpec/clusterConfiguration/apiServer/certSANs" + # FIXME: Debug why some of the patches are needed. # When the handler runs, it sends back multiple patches for individual fields. # But CAPI fails applying them because of missing value. diff --git a/pkg/handlers/generic/mutation/extraapiservercertsans/inject.go b/pkg/handlers/generic/mutation/extraapiservercertsans/inject.go index 3b5053014..c6b5b84dd 100644 --- a/pkg/handlers/generic/mutation/extraapiservercertsans/inject.go +++ b/pkg/handlers/generic/mutation/extraapiservercertsans/inject.go @@ -95,6 +95,10 @@ func (h *extraAPIServerCertSANsPatchHandler) Mutate( "variableValue", apiCertSANs, ) + if len(apiCertSANs) == 0 { + log.V(5).Info("No APIServerSANs to apply") + return nil + } return patches.MutateIfApplicable( obj, vars, &holderRef, selectors.ControlPlane(), log, @@ -117,6 +121,8 @@ func getDefaultAPIServerSANs(cluster *clusterv1.Cluster) []string { switch utils.GetProvider(cluster) { case "docker": return v1alpha1.DefaultDockerCertSANs + case "nutanix": + return v1alpha1.DefaultNutanixCertSANs default: return nil } diff --git a/pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go b/pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go index ba858e257..19a4d447e 100644 --- a/pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go +++ b/pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go @@ -130,6 +130,49 @@ var _ = Describe("Generate Extra API server certificate patches", func() { }, }, }, + { + patchTest: capitest.PatchTestDef{ + Name: "extra API server cert SANs set with Nutanix", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.ClusterConfigSpec{ + GenericClusterConfig: v1alpha1.GenericClusterConfig{ + ExtraAPIServerCertSANs: v1alpha1.ExtraAPIServerCertSANs{ + "a.b.c.example.com", + }, + }, + }, + ), + }, + RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/clusterConfiguration", + ValueMatcher: gomega.HaveKeyWithValue( + "apiServer", + gomega.HaveKeyWithValue( + "certSANs", + []interface{}{ + "0.0.0.0", + "127.0.0.1", + "a.b.c.example.com", + "localhost", + }, + ), + ), + }}, + }, + cluster: clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Namespace: metav1.NamespaceDefault, + Labels: map[string]string{ + clusterv1.ProviderNameLabel: "nutanix", + }, + }, + }, + }, } // create test node for each case