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.
This commit is contained in:
Dario Tranchitella
2022-07-08 22:17:57 +02:00
parent 3d1bfc42f1
commit a67e0f51c7
14 changed files with 43 additions and 44 deletions

View File

@@ -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"`

View File

@@ -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))

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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,

View File

@@ -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",

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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,
}

View File

@@ -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,

View File

@@ -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(),
}

View File

@@ -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
}