From a67e0f51c73df2671d64628771a3f9a02d4a43f8 Mon Sep 17 00:00:00 2001 From: Dario Tranchitella Date: Fri, 8 Jul 2022 22:17:57 +0200 Subject: [PATCH] refactor!(api): support for additional certificate SANs Removing the field tcp.spec.networkProfile.domain in favor of the tcp.spec.networkProfile.certSANs which allows specifying additional extra domains that could be used to reach out to the tenant control plane. --- api/v1alpha1/tenantcontrolplane_types.go | 5 +++-- api/v1alpha1/zz_generated.deepcopy.go | 5 +++++ .../kamaji.clastix.io_tenantcontrolplanes.yaml | 13 ++++++++----- config/install.yaml | 10 +++++----- .../samples/kamaji_v1alpha1_tenantcontrolplane.yaml | 3 ++- controllers/resources.go | 1 - e2e/tenant_control_plane_ready_test.go | 7 +------ helm/kamaji/crds/tenantcontrolplane.yaml | 13 ++++++++----- internal/kubeadm/configuration.go | 5 ++--- internal/kubeadm/types.go | 2 +- internal/resources/k8s_ingress_resource.go | 8 +++++--- internal/resources/kubeadm_config.go | 9 ++------- internal/resources/kubeadm_utils.go | 1 + internal/resources/utils.go | 5 ----- 14 files changed, 43 insertions(+), 44 deletions(-) diff --git a/api/v1alpha1/tenantcontrolplane_types.go b/api/v1alpha1/tenantcontrolplane_types.go index 5e61708..5fc765b 100644 --- a/api/v1alpha1/tenantcontrolplane_types.go +++ b/api/v1alpha1/tenantcontrolplane_types.go @@ -23,8 +23,9 @@ type NetworkProfileSpec struct { // Port where API server of will be exposed // +kubebuilder:default=6443 Port int32 `json:"port,omitempty"` - // Domain of the tenant control plane - Domain string `json:"domain"` + // CertSANs sets extra Subject Alternative Names (SANs) for the API Server signing certificate. + // Use this field to add additional hostnames when exposing the Tenant Control Plane with third solutions. + CertSANs []string `json:"certSANs,omitempty"` // Kubernetes Service // +kubebuilder:default="10.96.0.0/16" ServiceCIDR string `json:"serviceCidr,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index fc40903..2a436e2 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -578,6 +578,11 @@ func (in *KubernetesVersion) DeepCopy() *KubernetesVersion { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkProfileSpec) DeepCopyInto(out *NetworkProfileSpec) { *out = *in + if in.CertSANs != nil { + in, out := &in.CertSANs, &out.CertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.DNSServiceIPs != nil { in, out := &in.DNSServiceIPs, &out.DNSServiceIPs *out = make([]string, len(*in)) diff --git a/config/crd/bases/kamaji.clastix.io_tenantcontrolplanes.yaml b/config/crd/bases/kamaji.clastix.io_tenantcontrolplanes.yaml index 846882a..14aaa5e 100644 --- a/config/crd/bases/kamaji.clastix.io_tenantcontrolplanes.yaml +++ b/config/crd/bases/kamaji.clastix.io_tenantcontrolplanes.yaml @@ -294,15 +294,20 @@ spec: in the section of ExternalIPs of the Kubernetes Service (only ClusterIP or NodePort) type: boolean + certSANs: + description: CertSANs sets extra Subject Alternative Names (SANs) + for the API Server signing certificate. Use this field to add + additional hostnames when exposing the Tenant Control Plane + with third solutions. + items: + type: string + type: array dnsServiceIPs: default: - 10.96.0.10 items: type: string type: array - domain: - description: Domain of the tenant control plane - type: string podCidr: default: 10.244.0.0/16 description: CIDR for Kubernetes Pods @@ -316,8 +321,6 @@ spec: default: 10.96.0.0/16 description: Kubernetes Service type: string - required: - - domain type: object required: - controlPlane diff --git a/config/install.yaml b/config/install.yaml index 25dd8fa..c18e274 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -270,15 +270,17 @@ spec: allowAddressAsExternalIP: description: AllowAddressAsExternalIP will include tenantControlPlane.Spec.NetworkProfile.Address in the section of ExternalIPs of the Kubernetes Service (only ClusterIP or NodePort) type: boolean + certSANs: + description: CertSANs sets extra Subject Alternative Names (SANs) for the API Server signing certificate. Use this field to add additional hostnames when exposing the Tenant Control Plane with third solutions. + items: + type: string + type: array dnsServiceIPs: default: - 10.96.0.10 items: type: string type: array - domain: - description: Domain of the tenant control plane - type: string podCidr: default: 10.244.0.0/16 description: CIDR for Kubernetes Pods @@ -292,8 +294,6 @@ spec: default: 10.96.0.0/16 description: Kubernetes Service type: string - required: - - domain type: object required: - controlPlane diff --git a/config/samples/kamaji_v1alpha1_tenantcontrolplane.yaml b/config/samples/kamaji_v1alpha1_tenantcontrolplane.yaml index 877a0d9..1bfa0aa 100644 --- a/config/samples/kamaji_v1alpha1_tenantcontrolplane.yaml +++ b/config/samples/kamaji_v1alpha1_tenantcontrolplane.yaml @@ -41,7 +41,8 @@ spec: networkProfile: address: "127.0.0.1" port: 6443 - domain: "clastix.labs" + certSANs: + - "test.clastix.labs" serviceCidr: "10.96.0.0/16" podCidr: "10.244.0.0/16" dnsServiceIPs: diff --git a/controllers/resources.go b/controllers/resources.go index 9f19118..123ecc2 100644 --- a/controllers/resources.go +++ b/controllers/resources.go @@ -119,7 +119,6 @@ func getKubeadmConfigResources(c client.Client, tcpReconcilerConfig TenantContro KubernetesVersion: tenantControlPlane.Spec.Kubernetes.Version, PodCIDR: tenantControlPlane.Spec.NetworkProfile.PodCIDR, ServiceCIDR: tenantControlPlane.Spec.NetworkProfile.ServiceCIDR, - Domain: tenantControlPlane.Spec.NetworkProfile.Domain, ETCDs: getArrayFromString(tcpReconcilerConfig.ETCDEndpoints), ETCDCompactionInterval: tcpReconcilerConfig.ETCDCompactionInterval, Client: c, diff --git a/e2e/tenant_control_plane_ready_test.go b/e2e/tenant_control_plane_ready_test.go index 4a15e59..02a93d3 100644 --- a/e2e/tenant_control_plane_ready_test.go +++ b/e2e/tenant_control_plane_ready_test.go @@ -36,12 +36,7 @@ var _ = Describe("Deploy a TenantControlPlane resource", func() { }, }, NetworkProfile: kamajiv1alpha1.NetworkProfileSpec{ - Address: "172.18.0.2", - DNSServiceIPs: []string{"10.96.0.10"}, - Domain: "clastix.labs", - PodCIDR: "10.244.0.0/16", - Port: 31443, - ServiceCIDR: "10.96.0.0/16", + Address: "172.18.0.2", }, Kubernetes: kamajiv1alpha1.KubernetesSpec{ Version: "v1.23.6", diff --git a/helm/kamaji/crds/tenantcontrolplane.yaml b/helm/kamaji/crds/tenantcontrolplane.yaml index 846882a..14aaa5e 100644 --- a/helm/kamaji/crds/tenantcontrolplane.yaml +++ b/helm/kamaji/crds/tenantcontrolplane.yaml @@ -294,15 +294,20 @@ spec: in the section of ExternalIPs of the Kubernetes Service (only ClusterIP or NodePort) type: boolean + certSANs: + description: CertSANs sets extra Subject Alternative Names (SANs) + for the API Server signing certificate. Use this field to add + additional hostnames when exposing the Tenant Control Plane + with third solutions. + items: + type: string + type: array dnsServiceIPs: default: - 10.96.0.10 items: type: string type: array - domain: - description: Domain of the tenant control plane - type: string podCidr: default: 10.244.0.0/16 description: CIDR for Kubernetes Pods @@ -316,8 +321,6 @@ spec: default: 10.96.0.0/16 description: Kubernetes Service type: string - required: - - domain type: object required: - controlPlane diff --git a/internal/kubeadm/configuration.go b/internal/kubeadm/configuration.go index 90ec5c4..1bf45ca 100644 --- a/internal/kubeadm/configuration.go +++ b/internal/kubeadm/configuration.go @@ -80,15 +80,14 @@ func getKubeadmClusterConfiguration(params Parameters) kubeadmapi.ClusterConfigu }, }, APIServer: kubeadmapi.APIServer{ - CertSANs: []string{ + CertSANs: append([]string{ "127.0.0.1", "localhost", - fmt.Sprintf("%s.%s", params.TenantControlPlaneName, params.TenantControlPlaneDomain), params.TenantControlPlaneName, fmt.Sprintf("%s.%s.svc", params.TenantControlPlaneName, params.TenantControlPlaneNamespace), fmt.Sprintf("%s.%s.svc.cluster.local", params.TenantControlPlaneName, params.TenantControlPlaneNamespace), params.TenantControlPlaneAddress, - }, + }, params.TenantControlPlaneCertSANs...), ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{ ExtraArgs: map[string]string{ "etcd-compaction-interval": params.ETCDCompactionInterval, diff --git a/internal/kubeadm/types.go b/internal/kubeadm/types.go index 6515fe3..f9009ba 100644 --- a/internal/kubeadm/types.go +++ b/internal/kubeadm/types.go @@ -20,8 +20,8 @@ type Parameters struct { TenantControlPlaneNamespace string TenantControlPlaneEndpoint string TenantControlPlaneAddress string + TenantControlPlaneCertSANs []string TenantControlPlanePort int32 - TenantControlPlaneDomain string TenantControlPlanePodCIDR string TenantControlPlaneServiceCIDR string TenantDNSServiceIPs []string diff --git a/internal/resources/k8s_ingress_resource.go b/internal/resources/k8s_ingress_resource.go index 4660f9d..de879c8 100644 --- a/internal/resources/k8s_ingress_resource.go +++ b/internal/resources/k8s_ingress_resource.go @@ -119,11 +119,13 @@ func (r *KubernetesIngressResource) CreateOrUpdate(ctx context.Context, tenantCo } rule.HTTP.Paths[0] = path - rule.Host = tenantControlPlane.Spec.ControlPlane.Ingress.Hostname - if rule.Host == "" { - rule.Host = fmt.Sprintf("%s.%s.%s", tenantControlPlane.GetName(), tenantControlPlane.GetNamespace(), tenantControlPlane.Spec.NetworkProfile.Domain) + + if len(tenantControlPlane.Spec.ControlPlane.Ingress.Hostname) == 0 { + return fmt.Errorf("missing hostname to expose the Tenant Control Plane using an Ingress resource") } + rule.Host = tenantControlPlane.Spec.ControlPlane.Ingress.Hostname + r.resource.Spec.Rules = []networkingv1.IngressRule{ rule, } diff --git a/internal/resources/kubeadm_config.go b/internal/resources/kubeadm_config.go index 0b5b382..d81fc99 100644 --- a/internal/resources/kubeadm_config.go +++ b/internal/resources/kubeadm_config.go @@ -23,7 +23,6 @@ type KubeadmConfigResource struct { Client client.Client Name string Port int32 - Domain string PodCIDR string ServiceCIDR string KubernetesVersion string @@ -91,15 +90,11 @@ func (r *KubeadmConfigResource) UpdateTenantControlPlaneStatus(ctx context.Conte } func (r *KubeadmConfigResource) getControlPlaneEndpoint(tenantControlPlane *kamajiv1alpha1.TenantControlPlane, address string) string { - if !tenantControlPlane.Spec.ControlPlane.Ingress.Enabled { - return fmt.Sprintf("%s:%d", address, tenantControlPlane.Spec.NetworkProfile.Port) - } - if tenantControlPlane.Spec.ControlPlane.Ingress.Hostname != "" { return tenantControlPlane.Spec.ControlPlane.Ingress.Hostname } - return getTenantControllerExternalFQDN(*tenantControlPlane) + return fmt.Sprintf("%s:%d", address, tenantControlPlane.Spec.NetworkProfile.Port) } func (r *KubeadmConfigResource) mutate(tenantControlPlane *kamajiv1alpha1.TenantControlPlane, address string) controllerutil.MutateFn { @@ -111,8 +106,8 @@ func (r *KubeadmConfigResource) mutate(tenantControlPlane *kamajiv1alpha1.Tenant TenantControlPlaneNamespace: tenantControlPlane.GetNamespace(), TenantControlPlaneEndpoint: r.getControlPlaneEndpoint(tenantControlPlane, address), TenantControlPlaneAddress: address, + TenantControlPlaneCertSANs: tenantControlPlane.Spec.NetworkProfile.CertSANs, TenantControlPlanePort: r.Port, - TenantControlPlaneDomain: r.Domain, TenantControlPlanePodCIDR: r.PodCIDR, TenantControlPlaneServiceCIDR: r.ServiceCIDR, TenantControlPlaneVersion: r.KubernetesVersion, diff --git a/internal/resources/kubeadm_utils.go b/internal/resources/kubeadm_utils.go index 58f34b7..242d058 100644 --- a/internal/resources/kubeadm_utils.go +++ b/internal/resources/kubeadm_utils.go @@ -31,6 +31,7 @@ func KubeadmPhaseCreate(ctx context.Context, r KubeadmPhaseResource, tenantContr TenantControlPlaneVersion: tenantControlPlane.Spec.Kubernetes.Version, TenantControlPlanePodCIDR: tenantControlPlane.Spec.NetworkProfile.PodCIDR, TenantControlPlaneAddress: tenantControlPlane.Spec.NetworkProfile.Address, + TenantControlPlaneCertSANs: tenantControlPlane.Spec.NetworkProfile.CertSANs, TenantControlPlanePort: tenantControlPlane.Spec.NetworkProfile.Port, TenantControlPlaneCGroupDriver: tenantControlPlane.Spec.Kubernetes.Kubelet.CGroupFS.String(), } diff --git a/internal/resources/utils.go b/internal/resources/utils.go index 298597d..fbd889f 100644 --- a/internal/resources/utils.go +++ b/internal/resources/utils.go @@ -4,7 +4,6 @@ package resources import ( - "fmt" "math/rand" "time" @@ -64,10 +63,6 @@ func randomString(n int) string { return string(b) } -func getTenantControllerExternalFQDN(tenantControlPlane kamajiv1alpha1.TenantControlPlane) string { - return fmt.Sprintf("%s.%s.%s", tenantControlPlane.GetName(), tenantControlPlane.GetNamespace(), tenantControlPlane.Spec.NetworkProfile.Domain) -} - func getLatestConfigRV(tenantControlPlane kamajiv1alpha1.TenantControlPlane) string { return tenantControlPlane.Status.KubeadmConfig.ResourceVersion }