Skip to content

Commit 3263c2a

Browse files
committed
feat: add new CoreDNSUpdateStrategy API
1 parent 07c7ebe commit 3263c2a

9 files changed

+130
-26
lines changed

api/v1alpha1/clusterconfig_types.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ import (
1212
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables"
1313
)
1414

15+
const (
16+
CoreDNSUpdateStrategyAutomatic CoreDNSUpdateStrategy = "Automatic"
17+
CoreDNSUpdateStrategyManual CoreDNSUpdateStrategy = "Manual"
18+
)
19+
1520
var (
1621
DefaultDockerCertSANs = []string{
1722
"localhost",
@@ -320,12 +325,20 @@ type DNS struct {
320325
CoreDNS *CoreDNS `json:"coreDNS,omitempty"`
321326
}
322327

328+
// +kubebuilder:validation:Optional
329+
// +kubebuilder:validation:Enum=Manual;Automatic
330+
type CoreDNSUpdateStrategy string
331+
323332
type CoreDNS struct {
324333
// Image required for overriding Kubernetes DNS image details.
325-
// If the image version is not specified,
326-
// the default version based on the cluster's Kubernetes version will be used.
327334
// +kubebuilder:validation:Optional
328335
Image *Image `json:"image,omitempty"`
336+
337+
// UpdateStrategy defines the strategy for how the CoreDNS version will be updated.
338+
// If not specified, the default value is Automatic,
339+
// which sets the CoreDNS version based on the cluster's Kubernetes version.
340+
// +kubebuilder:default=Automatic
341+
UpdateStrategy *CoreDNSUpdateStrategy `json:"updateStrategy,omitempty"`
329342
}
330343

331344
//nolint:gochecknoinits // Idiomatic to use init functions to register APIs with scheme.

api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,7 @@ spec:
379379
description: CoreDNS defines the CoreDNS configuration for the cluster.
380380
properties:
381381
image:
382-
description: |-
383-
Image required for overriding Kubernetes DNS image details.
384-
If the image version is not specified,
385-
the default version based on the cluster's Kubernetes version will be used.
382+
description: Image required for overriding Kubernetes DNS image details.
386383
properties:
387384
repository:
388385
description: Repository is used to override the image repository to pull from.
@@ -393,6 +390,16 @@ spec:
393390
pattern: ^[\w][\w.-]{0,127}$
394391
type: string
395392
type: object
393+
updateStrategy:
394+
default: Automatic
395+
description: |-
396+
UpdateStrategy defines the strategy for how the CoreDNS version will be updated.
397+
If not specified, the default value is Automatic,
398+
which sets the CoreDNS version based on the cluster's Kubernetes version.
399+
enum:
400+
- Manual
401+
- Automatic
402+
type: string
396403
type: object
397404
type: object
398405
encryptionAtRest:

api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,7 @@ spec:
296296
description: CoreDNS defines the CoreDNS configuration for the cluster.
297297
properties:
298298
image:
299-
description: |-
300-
Image required for overriding Kubernetes DNS image details.
301-
If the image version is not specified,
302-
the default version based on the cluster's Kubernetes version will be used.
299+
description: Image required for overriding Kubernetes DNS image details.
303300
properties:
304301
repository:
305302
description: Repository is used to override the image repository to pull from.
@@ -310,6 +307,16 @@ spec:
310307
pattern: ^[\w][\w.-]{0,127}$
311308
type: string
312309
type: object
310+
updateStrategy:
311+
default: Automatic
312+
description: |-
313+
UpdateStrategy defines the strategy for how the CoreDNS version will be updated.
314+
If not specified, the default value is Automatic,
315+
which sets the CoreDNS version based on the cluster's Kubernetes version.
316+
enum:
317+
- Manual
318+
- Automatic
319+
type: string
313320
type: object
314321
type: object
315322
docker:

api/v1alpha1/crds/caren.nutanix.com_genericclusterconfigs.yaml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ spec:
5858
cluster.
5959
properties:
6060
image:
61-
description: |-
62-
Image required for overriding Kubernetes DNS image details.
63-
If the image version is not specified,
64-
the default version based on the cluster's Kubernetes version will be used.
61+
description: Image required for overriding Kubernetes DNS
62+
image details.
6563
properties:
6664
repository:
6765
description: Repository is used to override the image
@@ -74,6 +72,16 @@ spec:
7472
pattern: ^[\w][\w.-]{0,127}$
7573
type: string
7674
type: object
75+
updateStrategy:
76+
default: Automatic
77+
description: |-
78+
UpdateStrategy defines the strategy for how the CoreDNS version will be updated.
79+
If not specified, the default value is Automatic,
80+
which sets the CoreDNS version based on the cluster's Kubernetes version.
81+
enum:
82+
- Manual
83+
- Automatic
84+
type: string
7785
type: object
7886
type: object
7987
encryptionAtRest:

api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,10 +449,7 @@ spec:
449449
description: CoreDNS defines the CoreDNS configuration for the cluster.
450450
properties:
451451
image:
452-
description: |-
453-
Image required for overriding Kubernetes DNS image details.
454-
If the image version is not specified,
455-
the default version based on the cluster's Kubernetes version will be used.
452+
description: Image required for overriding Kubernetes DNS image details.
456453
properties:
457454
repository:
458455
description: Repository is used to override the image repository to pull from.
@@ -463,6 +460,16 @@ spec:
463460
pattern: ^[\w][\w.-]{0,127}$
464461
type: string
465462
type: object
463+
updateStrategy:
464+
default: Automatic
465+
description: |-
466+
UpdateStrategy defines the strategy for how the CoreDNS version will be updated.
467+
If not specified, the default value is Automatic,
468+
which sets the CoreDNS version based on the cluster's Kubernetes version.
469+
enum:
470+
- Manual
471+
- Automatic
472+
type: string
466473
type: object
467474
type: object
468475
encryptionAtRest:

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/handlers/generic/mutation/coredns/inject.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1111
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
12+
"k8s.io/utils/ptr"
1213
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
1314
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
1415
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
@@ -71,10 +72,11 @@ func (h *coreDNSPatchHandler) Mutate(
7172
h.variableFieldPath...,
7273
)
7374
if err != nil {
74-
if !variables.IsNotFoundError(err) {
75-
return err
75+
if variables.IsNotFoundError(err) {
76+
log.V(5).Info("coreDNS variable not defined")
77+
return nil
7678
}
77-
log.V(5).Info("coreDNS variable not defined")
79+
return err
7880
}
7981

8082
log = log.WithValues(
@@ -101,7 +103,7 @@ func (h *coreDNSPatchHandler) Mutate(
101103
log.WithValues(
102104
"patchedObjectKind", obj.GetObjectKind().GroupVersionKind().String(),
103105
"patchedObjectName", ctrlclient.ObjectKeyFromObject(obj),
104-
).Info("setting CoreDNS version")
106+
).Info("setting CoreDNS version if needed")
105107

106108
if obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration == nil {
107109
obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration = &bootstrapv1.ClusterConfiguration{}
@@ -119,9 +121,11 @@ func (h *coreDNSPatchHandler) Mutate(
119121
}
120122
}
121123

122-
// If the CoreDNS image tag is still not set, set the image tag to the default CoreDNS version based on the
124+
// If the updateStrategy is set Automatic, set the image tag to the default CoreDNS version based on the
123125
// Kubernetes version.
124-
if dns.ImageTag == "" {
126+
// Default the strategy to Automatic if var is not nil.
127+
strategy := ptr.Deref(coreDNSVar.UpdateStrategy, v1alpha1.CoreDNSUpdateStrategyAutomatic)
128+
if strategy == v1alpha1.CoreDNSUpdateStrategyAutomatic {
125129
defaultCoreDNSVersion, found := corednsversions.GetCoreDNSVersion(
126130
cluster.Spec.Topology.Version,
127131
)

pkg/handlers/generic/mutation/coredns/inject_test.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"k8s.io/apimachinery/pkg/runtime"
1414
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1515
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
16+
"k8s.io/utils/ptr"
1617
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1718
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
1819

@@ -46,7 +47,34 @@ var _ = Describe("Generate CoreDNS patches", func() {
4647
testDefs := []testObj{
4748
{
4849
patchTest: capitest.PatchTestDef{
49-
Name: "unset variable",
50+
Name: "unset variable",
51+
},
52+
cluster: clusterv1.Cluster{
53+
ObjectMeta: metav1.ObjectMeta{
54+
Name: "test-cluster",
55+
Namespace: request.Namespace,
56+
Labels: map[string]string{
57+
clusterv1.ProviderNameLabel: "nutanix",
58+
},
59+
},
60+
Spec: clusterv1.ClusterSpec{
61+
Topology: &clusterv1.Topology{
62+
Version: "1.30.100",
63+
},
64+
},
65+
},
66+
},
67+
{
68+
patchTest: capitest.PatchTestDef{
69+
Name: "variable with defaults",
70+
Vars: []runtimehooksv1.Variable{
71+
capitest.VariableWithValue(
72+
v1alpha1.ClusterConfigVariableName,
73+
v1alpha1.CoreDNS{},
74+
v1alpha1.DNSVariableName,
75+
VariableName,
76+
),
77+
},
5078
RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""),
5179
ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{
5280
Operation: "add",
@@ -85,6 +113,7 @@ var _ = Describe("Generate CoreDNS patches", func() {
85113
Repository: "my-registry.io/my-org/my-repo",
86114
Tag: "v1.11.3_custom.0",
87115
},
116+
UpdateStrategy: ptr.To(v1alpha1.CoreDNSUpdateStrategyManual),
88117
},
89118
v1alpha1.DNSVariableName,
90119
VariableName,
@@ -171,6 +200,7 @@ var _ = Describe("Generate CoreDNS patches", func() {
171200
Image: &v1alpha1.Image{
172201
Tag: "v1.11.3_custom.0",
173202
},
203+
UpdateStrategy: ptr.To(v1alpha1.CoreDNSUpdateStrategyManual),
174204
},
175205
v1alpha1.DNSVariableName,
176206
VariableName,
@@ -205,7 +235,15 @@ var _ = Describe("Generate CoreDNS patches", func() {
205235
},
206236
{
207237
patchTest: capitest.PatchTestDef{
208-
Name: "error if cannot find default CoreDNS version",
238+
Name: "error if cannot find default CoreDNS version",
239+
Vars: []runtimehooksv1.Variable{
240+
capitest.VariableWithValue(
241+
v1alpha1.ClusterConfigVariableName,
242+
v1alpha1.CoreDNS{},
243+
v1alpha1.DNSVariableName,
244+
VariableName,
245+
),
246+
},
209247
RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""),
210248
ExpectedFailure: true,
211249
},
@@ -235,6 +273,7 @@ var _ = Describe("Generate CoreDNS patches", func() {
235273
Repository: "my-registry.io/my-org/my-repo",
236274
Tag: "v1.11.3_custom.0",
237275
},
276+
UpdateStrategy: ptr.To(v1alpha1.CoreDNSUpdateStrategyManual),
238277
},
239278
v1alpha1.DNSVariableName,
240279
VariableName,

pkg/handlers/generic/mutation/coredns/variables_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import (
1515
nutanixclusterconfig "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig"
1616
)
1717

18+
const (
19+
invalidUpdateStrategy = v1alpha1.CoreDNSUpdateStrategy("this:is:not:a:valid:update:strategy")
20+
)
21+
1822
var testDefs = []capitest.VariableTestDef{{
1923
Name: "unset",
2024
Vals: v1alpha1.GenericClusterConfigSpec{
@@ -78,6 +82,16 @@ var testDefs = []capitest.VariableTestDef{{
7882
},
7983
},
8084
ExpectError: true,
85+
}, {
86+
Name: "set an invalid updateStrategy",
87+
Vals: v1alpha1.GenericClusterConfigSpec{
88+
DNS: &v1alpha1.DNS{
89+
CoreDNS: &v1alpha1.CoreDNS{
90+
UpdateStrategy: ptr.To(invalidUpdateStrategy),
91+
},
92+
},
93+
},
94+
ExpectError: true,
8195
}}
8296

8397
func TestVariableValidation_AWS(t *testing.T) {

0 commit comments

Comments
 (0)