Skip to content

Commit d1112d3

Browse files
committed
Add support for customizing additional provider deployments
1 parent d2d1dad commit d1112d3

15 files changed

+24435
-4809
lines changed

Diff for: api/v1alpha1/provider_conversion.go

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func (src *BootstrapProvider) ConvertTo(dstRaw conversion.Hub) error {
4646
}
4747

4848
dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
49+
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
4950

5051
return nil
5152
}
@@ -107,6 +108,7 @@ func (src *ControlPlaneProvider) ConvertTo(dstRaw conversion.Hub) error {
107108
}
108109

109110
dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
111+
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
110112

111113
return nil
112114
}
@@ -168,6 +170,7 @@ func (src *CoreProvider) ConvertTo(dstRaw conversion.Hub) error {
168170
}
169171

170172
dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
173+
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
171174

172175
return nil
173176
}
@@ -229,6 +232,7 @@ func (src *InfrastructureProvider) ConvertTo(dstRaw conversion.Hub) error {
229232
}
230233

231234
dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
235+
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
232236

233237
return nil
234238
}

Diff for: api/v1alpha1/zz_generated.conversion.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: api/v1alpha2/provider_types.go

+18
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,24 @@ type ProviderSpec struct {
7373
// This should be an inline yaml blob-string https://datatracker.ietf.org/doc/html/rfc7396
7474
// +optional
7575
ManifestPatches []string `json:"manifestPatches,omitempty"`
76+
77+
// AdditionalDeployments is a map of additional deployments that the provider
78+
// should manage. The key is the name of the deployment and the value is the
79+
// DeploymentSpec.
80+
// +optional
81+
AdditionalDeployments map[string]AdditionalDeployments `json:"additionalDeployments,omitempty"`
82+
}
83+
84+
// AdditionalDeployments defines the properties that can be enabled on the controller
85+
// manager and deployment for the provider if the provider is managing additional deployments.
86+
type AdditionalDeployments struct {
87+
// Manager defines the properties that can be enabled on the controller manager for the additional provider deployment.
88+
// +optional
89+
Manager *ManagerSpec `json:"manager,omitempty"`
90+
91+
// Deployment defines the properties that can be enabled on the deployment for the additional provider deployment.
92+
// +optional
93+
Deployment *DeploymentSpec `json:"deployment,omitempty"`
7694
}
7795

7896
// ConfigmapReference contains enough information to locate the configmap.

Diff for: api/v1alpha2/zz_generated.deepcopy.go

+32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_addonproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_bootstrapproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_controlplaneproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_coreproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_infrastructureproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_ipamproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: config/crd/bases/operator.cluster.x-k8s.io_runtimeextensionproviders.yaml

+1,393
Large diffs are not rendered by default.

Diff for: hack/charts/cluster-api-operator/templates/infra.yaml

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
{{- define "recursivePrinter" }}
2+
{{- range $key, $value := . }}
3+
{{- if kindIs "map" $value }}
4+
{{ $key }}:
5+
{{- include "recursivePrinter" $value | indent 2 }}
6+
{{- else }}
7+
{{ $key }}: {{ $value }}
8+
{{- end }}
9+
{{- end }}
10+
{{- end }}
111
# Infrastructure providers
212
{{- if .Values.infrastructure }}
313
{{- $infrastructures := split ";" .Values.infrastructure }}
@@ -40,7 +50,7 @@ metadata:
4050
"helm.sh/hook": "post-install"
4151
"helm.sh/hook-weight": "2"
4252
"argocd.argoproj.io/sync-wave": "2"
43-
{{- if or $infrastructureVersion $.Values.configSecret.name $.Values.manager }}
53+
{{- if or $infrastructureVersion $.Values.configSecret.name $.Values.manager $.Values.additionalDeployments }}
4454
spec:
4555
{{- end }}
4656
{{- if $infrastructureVersion }}
@@ -66,5 +76,9 @@ spec:
6676
namespace: {{ $.Values.configSecret.namespace }}
6777
{{- end }}
6878
{{- end }}
79+
{{- if $.Values.additionalDeployments }}
80+
additionalDeployments:
81+
{{- include "recursivePrinter" $.Values.additionalDeployments | indent 2 }}
82+
{{- end }}
6983
{{- end }}
7084
{{- end }}

Diff for: internal/controller/component_customizer.go

+34-20
Original file line numberDiff line numberDiff line change
@@ -73,25 +73,41 @@ func customizeObjectsFn(provider operatorv1.GenericProvider) func(objs []unstruc
7373
}))
7474
}
7575

76+
//nolint:nestif
7677
if o.GetKind() == deploymentKind {
78+
d := &appsv1.Deployment{}
79+
if err := scheme.Scheme.Convert(&o, d, nil); err != nil {
80+
return nil, err
81+
}
82+
83+
providerDeployment := provider.GetSpec().Deployment
84+
providerManager := provider.GetSpec().Manager
85+
86+
// If there are multiple deployments, check if we specify customizations for those deployments.
7787
// We need to skip the deployment customization if there are several deployments available
78-
// and the deployment name doesn't follow "ca*-controller-manager" pattern.
79-
// Currently it is applicable only for CAPZ manifests, which contain 2 deployments:
80-
// capz-controller-manager and azureserviceoperator-controller-manager
88+
// and the deployment name doesn't follow "ca*-controller-manager" pattern, or the provider
89+
// doesn't specify customizations for the deployment.
8190
// This is a temporary fix until CAPI provides a contract to distinguish provider deployments.
8291
// TODO: replace this check and just compare labels when CAPI provides the contract for that.
8392
if isMultipleDeployments && !isProviderManagerDeploymentName(o.GetName()) {
84-
results = append(results, o)
85-
86-
continue
93+
additionalDeployments := provider.GetSpec().AdditionalDeployments
94+
// Skip the deployment if there are no additional deployments specified.
95+
if additionalDeployments == nil {
96+
results = append(results, o)
97+
continue
98+
}
99+
100+
additionalProviderCustomization, ok := additionalDeployments[o.GetName()]
101+
if !ok {
102+
results = append(results, o)
103+
continue
104+
}
105+
106+
providerDeployment = additionalProviderCustomization.Deployment
107+
providerManager = additionalProviderCustomization.Manager
87108
}
88109

89-
d := &appsv1.Deployment{}
90-
if err := scheme.Scheme.Convert(&o, d, nil); err != nil {
91-
return nil, err
92-
}
93-
94-
if err := customizeDeployment(provider.GetSpec(), d); err != nil {
110+
if err := customizeDeployment(providerDeployment, providerManager, d); err != nil {
95111
return nil, err
96112
}
97113

@@ -108,28 +124,26 @@ func customizeObjectsFn(provider operatorv1.GenericProvider) func(objs []unstruc
108124
}
109125

110126
// customizeDeployment customize provider deployment base on provider spec input.
111-
func customizeDeployment(pSpec operatorv1.ProviderSpec, d *appsv1.Deployment) error {
127+
func customizeDeployment(dSpec *operatorv1.DeploymentSpec, mSpec *operatorv1.ManagerSpec, d *appsv1.Deployment) error {
112128
// Customize deployment spec first.
113-
if pSpec.Deployment != nil {
114-
customizeDeploymentSpec(pSpec, d)
129+
if dSpec != nil {
130+
customizeDeploymentSpec(*dSpec, d)
115131
}
116132

117133
// Run the customizeManagerContainer after, so it overrides anything in the deploymentSpec.
118-
if pSpec.Manager != nil {
134+
if mSpec != nil {
119135
container := findManagerContainer(&d.Spec)
120136
if container == nil {
121137
return fmt.Errorf("cannot find %q container in deployment %q", managerContainerName, d.Name)
122138
}
123139

124-
customizeManagerContainer(pSpec.Manager, container)
140+
customizeManagerContainer(mSpec, container)
125141
}
126142

127143
return nil
128144
}
129145

130-
func customizeDeploymentSpec(pSpec operatorv1.ProviderSpec, d *appsv1.Deployment) {
131-
dSpec := pSpec.Deployment
132-
146+
func customizeDeploymentSpec(dSpec operatorv1.DeploymentSpec, d *appsv1.Deployment) {
133147
if dSpec.Replicas != nil {
134148
d.Spec.Replicas = ptr.To(int32(*dSpec.Replicas))
135149
}

Diff for: internal/controller/component_customizer_test.go

+46-5
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,7 @@ func TestCustomizeDeployment(t *testing.T) {
557557
for _, tc := range tests {
558558
t.Run(tc.name, func(t *testing.T) {
559559
deployment := managerDepl.DeepCopy()
560-
if err := customizeDeployment(operatorv1.ProviderSpec{
561-
Deployment: tc.inputDeploymentSpec,
562-
Manager: tc.inputManagerSpec,
563-
}, deployment); err != nil {
560+
if err := customizeDeployment(tc.inputDeploymentSpec, tc.inputManagerSpec, deployment); err != nil {
564561
t.Error(err)
565562
}
566563

@@ -575,6 +572,7 @@ func TestCustomizeMultipleDeployment(t *testing.T) {
575572
tests := []struct {
576573
name string
577574
nonManagerDeploymentName string
575+
shouldCustomize bool
578576
}{
579577
{
580578
name: "name without suffix and prefix",
@@ -588,6 +586,11 @@ func TestCustomizeMultipleDeployment(t *testing.T) {
588586
name: "name with suffix",
589587
nonManagerDeploymentName: "non-manager-controller-manager",
590588
},
589+
{
590+
name: "name with azureserviceoperator controller-manager",
591+
nonManagerDeploymentName: "azureserviceoperator-controller-manager",
592+
shouldCustomize: true,
593+
},
591594
{
592595
name: "empty name",
593596
nonManagerDeploymentName: "",
@@ -603,6 +606,17 @@ func TestCustomizeMultipleDeployment(t *testing.T) {
603606
},
604607
Spec: appsv1.DeploymentSpec{
605608
Replicas: ptr.To(int32(3)),
609+
Template: corev1.PodTemplateSpec{
610+
Spec: corev1.PodSpec{
611+
Containers: []corev1.Container{
612+
{
613+
Name: "manager",
614+
Image: "registry.k8s.io/a-manager:1.6.2",
615+
Args: []string{},
616+
},
617+
},
618+
},
619+
},
606620
},
607621
}
608622

@@ -629,6 +643,23 @@ func TestCustomizeMultipleDeployment(t *testing.T) {
629643
Deployment: &operatorv1.DeploymentSpec{
630644
Replicas: ptr.To(10),
631645
},
646+
AdditionalDeployments: map[string]operatorv1.AdditionalDeployments{
647+
"azureserviceoperator-controller-manager": {
648+
Deployment: &operatorv1.DeploymentSpec{
649+
Containers: []operatorv1.ContainerSpec{
650+
{
651+
Name: "manager",
652+
Args: map[string]string{
653+
"--crd-pattern": ".*",
654+
},
655+
},
656+
},
657+
},
658+
Manager: &operatorv1.ManagerSpec{
659+
Verbosity: 1,
660+
},
661+
},
662+
},
632663
},
633664
},
634665
}
@@ -657,8 +688,18 @@ func TestCustomizeMultipleDeployment(t *testing.T) {
657688
t.Errorf("expected 10 replicas, got %d", *managerDepl.Spec.Replicas)
658689
}
659690

691+
if tc.shouldCustomize {
692+
// non-manager container should have been customized
693+
container := findManagerContainer(&nonManagerDepl.Spec)
694+
if container == nil {
695+
t.Error("expected container to be found")
696+
} else if container.Args != nil && container.Args[0] != "--crd-pattern=.*" {
697+
t.Errorf("expected --crd-pattern=.*, got %s", container.Args[0])
698+
}
699+
}
700+
660701
// non-manager deployment should not have been customized
661-
if *nonManagerDepl.Spec.Replicas != 3 {
702+
if *nonManagerDepl.Spec.Replicas != 3 && !tc.shouldCustomize {
662703
t.Errorf("expected 3 replicas, got %d", *nonManagerDepl.Spec.Replicas)
663704
}
664705
})

0 commit comments

Comments
 (0)