From f5bd074026b2c0dd2ff7b13b413bb983fb8af5dd Mon Sep 17 00:00:00 2001 From: ahreehong <46465244+ahreehong@users.noreply.github.com> Date: Fri, 19 May 2023 16:29:08 -0400 Subject: [PATCH 31/34] Add support for custom cert bundles in BR (#21) * add support for custom cert bundles br * take in non base-64 encoded data for cert Signed-off-by: Ahree Hong --- .../api/v1alpha4/zz_generated.conversion.go | 2 + .../kubeadm/api/v1beta1/kubeadm_types.go | 17 ++++++ .../api/v1beta1/zz_generated.deepcopy.go | 25 +++++++++ ...strap.cluster.x-k8s.io_kubeadmconfigs.yaml | 32 +++++++++++ ...uster.x-k8s.io_kubeadmconfigtemplates.yaml | 34 ++++++++++++ .../internal/bottlerocket/bootstrap.go | 16 ++++++ .../internal/bottlerocket/bootstrap_test.go | 53 +++++++++++++++++++ .../internal/bottlerocket/bottlerocket.go | 14 +++++ .../controllers/kubeadmconfig_controller.go | 9 ++++ .../zz_generated.conversion.go | 2 + .../zz_generated.conversion.go | 2 + .../zz_generated.conversion.go | 2 + ...cluster.x-k8s.io_kubeadmcontrolplanes.yaml | 32 +++++++++++ ...x-k8s.io_kubeadmcontrolplanetemplates.yaml | 34 ++++++++++++ 14 files changed, 274 insertions(+) diff --git a/bootstrap/kubeadm/api/v1alpha4/zz_generated.conversion.go b/bootstrap/kubeadm/api/v1alpha4/zz_generated.conversion.go index 43971cb70..d43c45841 100644 --- a/bootstrap/kubeadm/api/v1alpha4/zz_generated.conversion.go +++ b/bootstrap/kubeadm/api/v1alpha4/zz_generated.conversion.go @@ -731,6 +731,7 @@ func autoConvert_v1beta1_ClusterConfiguration_To_v1alpha4_ClusterConfiguration(i // WARNING: in.BottlerocketHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } @@ -1139,6 +1140,7 @@ func autoConvert_v1beta1_JoinConfiguration_To_v1alpha4_JoinConfiguration(in *v1b // WARNING: in.BottlerocketCustomHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } diff --git a/bootstrap/kubeadm/api/v1beta1/kubeadm_types.go b/bootstrap/kubeadm/api/v1beta1/kubeadm_types.go index 434d2c088..ed965709a 100644 --- a/bootstrap/kubeadm/api/v1beta1/kubeadm_types.go +++ b/bootstrap/kubeadm/api/v1beta1/kubeadm_types.go @@ -190,6 +190,10 @@ type ClusterConfiguration struct { // This is only for bottlerocket. // +optional Bottlerocket *BottlerocketSettings `json:"bottlerocket,omitempty"` + + // CertBundles holds additional trusted cert bundles. + // +optional + CertBundles []CertBundle `json:"certBundles,omitempty"` } // BottlerocketSettings define bottlerocket settings that can be configured on bottlerocket nodes. @@ -621,6 +625,10 @@ type JoinConfiguration struct { // This is only for bottlerocket. // +optional Bottlerocket *BottlerocketSettings `json:"bottlerocket,omitempty"` + + // CertBundles holds additional trusted cert bundles. + // +optional + CertBundles []CertBundle `json:"certBundles,omitempty"` } // BottlerocketHostContainer describes a host image for Bottlerocket @@ -661,6 +669,15 @@ type BottlerocketBootstrapContainer struct { UserData string `json:"userData,omitempty"` } +// CertBundle holds the cert data. +type CertBundle struct { + // Name is the name of the cert bundle. + Name string `json:"name"` + + // Data is the actual cert. + Data string `json:"data"` +} + // JoinControlPlane contains elements describing an additional control plane instance to be deployed on the joining node. type JoinControlPlane struct { // LocalAPIEndpoint represents the endpoint of the API server instance to be deployed on this node. diff --git a/bootstrap/kubeadm/api/v1beta1/zz_generated.deepcopy.go b/bootstrap/kubeadm/api/v1beta1/zz_generated.deepcopy.go index 306ba8931..6b722fd0f 100644 --- a/bootstrap/kubeadm/api/v1beta1/zz_generated.deepcopy.go +++ b/bootstrap/kubeadm/api/v1beta1/zz_generated.deepcopy.go @@ -330,6 +330,21 @@ func (in *BottlerocketSettings) DeepCopy() *BottlerocketSettings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CertBundle) DeepCopyInto(out *CertBundle) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertBundle. +func (in *CertBundle) DeepCopy() *CertBundle { + if in == nil { + return nil + } + out := new(CertBundle) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { *out = *in @@ -368,6 +383,11 @@ func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { *out = new(BottlerocketSettings) (*in).DeepCopyInto(*out) } + if in.CertBundles != nil { + in, out := &in.CertBundles, &out.CertBundles + *out = make([]CertBundle, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfiguration. @@ -802,6 +822,11 @@ func (in *JoinConfiguration) DeepCopyInto(out *JoinConfiguration) { *out = new(BottlerocketSettings) (*in).DeepCopyInto(*out) } + if in.CertBundles != nil { + in, out := &in.CertBundles, &out.CertBundles + *out = make([]CertBundle, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JoinConfiguration. diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml index df745e7f2..a41d3aa0b 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml @@ -2544,6 +2544,22 @@ spec: - superpowered type: object type: array + certBundles: + description: CertBundles holds additional trusted cert bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array certificatesDir: description: 'CertificatesDir specifies where to store or look for all required certificates. NB: if not provided, this will @@ -3390,6 +3406,22 @@ spec: Defaults to "/etc/kubernetes/pki/ca.crt". TODO: revisit when there is defaulting from k/k' type: string + certBundles: + description: CertBundles holds additional trusted cert bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array controlPlane: description: ControlPlane defines the additional control plane instance to be deployed on the joining node. If nil, no additional diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml index 9c4514353..984715e30 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml @@ -2585,6 +2585,23 @@ spec: - superpowered type: object type: array + certBundles: + description: CertBundles holds additional trusted cert + bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array certificatesDir: description: 'CertificatesDir specifies where to store or look for all required certificates. NB: if not provided, @@ -3488,6 +3505,23 @@ spec: and control-plane. Defaults to "/etc/kubernetes/pki/ca.crt". TODO: revisit when there is defaulting from k/k' type: string + certBundles: + description: CertBundles holds additional trusted cert + bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array controlPlane: description: ControlPlane defines the additional control plane instance to be deployed on the joining node. If diff --git a/bootstrap/kubeadm/internal/bottlerocket/bootstrap.go b/bootstrap/kubeadm/internal/bottlerocket/bootstrap.go index 901db1cb7..df222b943 100644 --- a/bootstrap/kubeadm/internal/bottlerocket/bootstrap.go +++ b/bootstrap/kubeadm/internal/bottlerocket/bootstrap.go @@ -128,6 +128,18 @@ reboot-to-reconcile = true [settings.boot.kernel-parameters] {{.BootKernel}} {{- end -}} +` + certsTemplate = `{{ define "certsSettings" -}} +[settings.pki.{{.Name}}] +data = "{{.Data}}" +trusted = true +{{- end -}} +` + certBundlesSliceTemplate = `{{ define "certBundlesSlice" -}} +{{- range $cBundle := .CertBundles }} +{{template "certsSettings" $cBundle }} +{{- end -}} +{{- end -}} ` bottlerocketNodeInitSettingsTemplate = `{{template "hostContainerSlice" .}} @@ -172,5 +184,9 @@ reboot-to-reconcile = true {{- if .BootKernel}} {{template "bootSettings" .}} {{- end -}} + +{{- if .CertBundles}} +{{template "certBundlesSlice" .}} +{{- end -}} ` ) diff --git a/bootstrap/kubeadm/internal/bottlerocket/bootstrap_test.go b/bootstrap/kubeadm/internal/bottlerocket/bootstrap_test.go index 5846524be..2ee2d942b 100644 --- a/bootstrap/kubeadm/internal/bottlerocket/bootstrap_test.go +++ b/bootstrap/kubeadm/internal/bottlerocket/bootstrap_test.go @@ -310,6 +310,36 @@ reboot-to-reconcile = true "abc" = ["def","123"] "foo" = ["bar"] ` + + userDataWithCertBundle = ` +[settings.host-containers.admin] +enabled = true +superpowered = true +source = "ADMIN_REPO:ADMIN_TAG" +user-data = "CnsKCSJzc2giOiB7CgkJImF1dGhvcml6ZWQta2V5cyI6IFsic3NoLXJzYSBBQUEuLi4iXQoJfQp9" +[settings.host-containers.kubeadm-bootstrap] +enabled = true +superpowered = true +source = "BOOTSTRAP_REPO:BOOTSTRAP_TAG" +user-data = "Qk9UVExFUk9DS0VUX0JPT1RTVFJBUF9VU0VSREFUQQ==" + +[settings.kubernetes] +cluster-domain = "cluster.local" +standalone-mode = true +authentication-mode = "tls" +server-tls-bootstrap = false +pod-infra-container-image = "PAUSE_REPO:PAUSE_TAG" +provider-id = "PROVIDERID" + +[settings.network] +hostname = "hostname" + +[settings.pki.bundle1] +data = "QUJDREVG" +trusted = true +[settings.pki.bundle2] +data = "MTIzNDU2" +trusted = true` ) var ( @@ -569,6 +599,29 @@ func TestGetBottlerocketNodeUserData(t *testing.T) { }, output: BootSettingsUserData, }, + { + name: "with custom cert bundle settings", + config: &BottlerocketConfig{ + BottlerocketAdmin: brAdmin, + BottlerocketBootstrap: brBootstrap, + Hostname: hostname, + Pause: pause, + KubeletExtraArgs: map[string]string{ + "provider-id": "PROVIDERID", + }, + CertBundle: []bootstrapv1.CertBundle{ + { + Name: "bundle1", + Data: "ABCDEF", + }, + { + Name: "bundle2", + Data: "123456", + }, + }, + }, + output: userDataWithCertBundle, + }, } for _, testcase := range testcases { t.Run(testcase.name, func(t *testing.T) { diff --git a/bootstrap/kubeadm/internal/bottlerocket/bottlerocket.go b/bootstrap/kubeadm/internal/bottlerocket/bottlerocket.go index b588f943e..13eb02007 100644 --- a/bootstrap/kubeadm/internal/bottlerocket/bottlerocket.go +++ b/bootstrap/kubeadm/internal/bottlerocket/bottlerocket.go @@ -36,6 +36,7 @@ type BottlerocketConfig struct { BottlerocketCustomBootstrapContainers []bootstrapv1.BottlerocketBootstrapContainer NTPServers []string Hostname string + CertBundle []bootstrapv1.CertBundle RegistryMirrorCredentials } @@ -60,6 +61,7 @@ type BottlerocketSettingsInput struct { HostContainers []bootstrapv1.BottlerocketHostContainer BootstrapContainers []bootstrapv1.BottlerocketBootstrapContainer SysctlSettings string + CertBundles []bootstrapv1.CertBundle } // HostPath holds the path and type of a host path volume. @@ -163,6 +165,12 @@ func generateNodeUserData(kind string, tpl string, data interface{}) ([]byte, er if _, err := tm.Parse(bootSettingsTemplate); err != nil { return nil, errors.Wrapf(err, "failed to parse boot settings %s template", kind) } + if _, err := tm.Parse(certsTemplate); err != nil { + return nil, errors.Wrapf(err, "failed to parse certs %s template", kind) + } + if _, err := tm.Parse(certBundlesSliceTemplate); err != nil { + return nil, errors.Wrapf(err, "failed to parse cert bundles %s template", kind) + } t, err := tm.Parse(tpl) if err != nil { return nil, errors.Wrapf(err, "failed to parse %s template", kind) @@ -265,6 +273,12 @@ func getBottlerocketNodeUserData(bootstrapContainerUserData []byte, users []boot } } + if config.CertBundle != nil { + for _, cert := range config.CertBundle { + cert.Data = base64.StdEncoding.EncodeToString([]byte(cert.Data)) + bottlerocketInput.CertBundles = append(bottlerocketInput.CertBundles, cert) + } + } return generateNodeUserData("InitBottlerocketNode", bottlerocketNodeInitSettingsTemplate, bottlerocketInput) } diff --git a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go index c5895224d..c724d41d8 100644 --- a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go +++ b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go @@ -501,6 +501,9 @@ func (r *KubeadmConfigReconciler) handleClusterNotInitialized(ctx context.Contex if scope.Config.Spec.NTP != nil && scope.Config.Spec.NTP.Enabled != nil && *scope.Config.Spec.NTP.Enabled { bottlerocketConfig.NTPServers = scope.Config.Spec.NTP.Servers } + if scope.Config.Spec.ClusterConfiguration.CertBundles != nil { + bottlerocketConfig.CertBundle = scope.Config.Spec.ClusterConfiguration.CertBundles + } } clusterdata, err := kubeadmtypes.MarshalClusterConfigurationForVersion(scope.Config.Spec.ClusterConfiguration, parsedVersion) @@ -723,6 +726,9 @@ func (r *KubeadmConfigReconciler) joinWorker(ctx context.Context, scope *Scope) if scope.Config.Spec.NTP != nil && scope.Config.Spec.NTP.Enabled != nil && *scope.Config.Spec.NTP.Enabled { bottlerocketConfig.NTPServers = scope.Config.Spec.NTP.Servers } + if scope.Config.Spec.JoinConfiguration.CertBundles != nil { + bottlerocketConfig.CertBundle = scope.Config.Spec.JoinConfiguration.CertBundles + } bootstrapJoinData, err = bottlerocket.NewNode(nodeInput, bottlerocketConfig) if err != nil { scope.Error(err, "Failed to create a worker bottlerocket join configuration") @@ -869,6 +875,9 @@ func (r *KubeadmConfigReconciler) joinControlplane(ctx context.Context, scope *S if scope.Config.Spec.NTP != nil && scope.Config.Spec.NTP.Enabled != nil && *scope.Config.Spec.NTP.Enabled { bottlerocketConfig.NTPServers = scope.Config.Spec.NTP.Servers } + if scope.Config.Spec.JoinConfiguration.CertBundles != nil { + bottlerocketConfig.CertBundle = scope.Config.Spec.JoinConfiguration.CertBundles + } bootstrapJoinData, err = bottlerocket.NewJoinControlPlane(controlPlaneJoinInput, bottlerocketConfig) if err != nil { scope.Error(err, "Failed to generate cloud init for bottlerocket bootstrap control plane") diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go b/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go index d07a9dff3..137b19a80 100644 --- a/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go +++ b/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go @@ -565,6 +565,7 @@ func autoConvert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfigur // WARNING: in.BottlerocketHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } @@ -865,6 +866,7 @@ func autoConvert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration( // WARNING: in.BottlerocketCustomHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } diff --git a/bootstrap/kubeadm/types/upstreamv1beta2/zz_generated.conversion.go b/bootstrap/kubeadm/types/upstreamv1beta2/zz_generated.conversion.go index 8b1acbb57..3b12557c4 100644 --- a/bootstrap/kubeadm/types/upstreamv1beta2/zz_generated.conversion.go +++ b/bootstrap/kubeadm/types/upstreamv1beta2/zz_generated.conversion.go @@ -565,6 +565,7 @@ func autoConvert_v1beta1_ClusterConfiguration_To_upstreamv1beta2_ClusterConfigur // WARNING: in.BottlerocketHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } @@ -877,6 +878,7 @@ func autoConvert_v1beta1_JoinConfiguration_To_upstreamv1beta2_JoinConfiguration( // WARNING: in.BottlerocketCustomHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } diff --git a/bootstrap/kubeadm/types/upstreamv1beta3/zz_generated.conversion.go b/bootstrap/kubeadm/types/upstreamv1beta3/zz_generated.conversion.go index c613bdd12..6d812f516 100644 --- a/bootstrap/kubeadm/types/upstreamv1beta3/zz_generated.conversion.go +++ b/bootstrap/kubeadm/types/upstreamv1beta3/zz_generated.conversion.go @@ -569,6 +569,7 @@ func autoConvert_v1beta1_ClusterConfiguration_To_upstreamv1beta3_ClusterConfigur // WARNING: in.BottlerocketHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } @@ -869,6 +870,7 @@ func autoConvert_v1beta1_JoinConfiguration_To_upstreamv1beta3_JoinConfiguration( // WARNING: in.BottlerocketCustomHostContainers requires manual conversion: does not exist in peer-type // WARNING: in.BottlerocketCustomBootstrapContainers requires manual conversion: does not exist in peer-type // WARNING: in.Bottlerocket requires manual conversion: does not exist in peer-type + // WARNING: in.CertBundles requires manual conversion: does not exist in peer-type return nil } diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml index 7b74847bc..2063177dc 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml @@ -3024,6 +3024,22 @@ spec: - superpowered type: object type: array + certBundles: + description: CertBundles holds additional trusted cert bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array certificatesDir: description: 'CertificatesDir specifies where to store or look for all required certificates. NB: if not provided, @@ -3905,6 +3921,22 @@ spec: control-plane. Defaults to "/etc/kubernetes/pki/ca.crt". TODO: revisit when there is defaulting from k/k' type: string + certBundles: + description: CertBundles holds additional trusted cert bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array controlPlane: description: ControlPlane defines the additional control plane instance to be deployed on the joining node. If nil, no diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml index a79e90dea..7821a39d5 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml @@ -1665,6 +1665,23 @@ spec: - superpowered type: object type: array + certBundles: + description: CertBundles holds additional trusted + cert bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array certificatesDir: description: 'CertificatesDir specifies where to store or look for all required certificates. NB: if not @@ -2606,6 +2623,23 @@ spec: and control-plane. Defaults to "/etc/kubernetes/pki/ca.crt". TODO: revisit when there is defaulting from k/k' type: string + certBundles: + description: CertBundles holds additional trusted + cert bundles. + items: + description: CertBundle holds the cert data. + properties: + data: + description: Data is the actual cert. + type: string + name: + description: Name is the name of the cert bundle. + type: string + required: + - data + - name + type: object + type: array controlPlane: description: ControlPlane defines the additional control plane instance to be deployed on the joining node. -- 2.40.0