Skip to content

Commit f18fd3b

Browse files
dkoshkinjimmidyson
authored andcommitted
feat: add etcd registry and tag patch and vars
1 parent c16c492 commit f18fd3b

File tree

11 files changed

+438
-1
lines changed

11 files changed

+438
-1
lines changed

.gitlint

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ regex=https?://
2020
regex=(.*)dependabot(.*) #
2121
ignore=T1,body-min-length
2222

23-
2423
[contrib-title-conventional-commits]
2524
# Specify allowed commit types. For details see: https://www.conventionalcommits.org/
2625
types = fix,feat,docs,style,refactor,perf,test,revert,ci,build

api/v1alpha1/clusterconfig_types.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ type ClusterConfigSpec struct {
3333
// +optional
3434
KubernetesImageRegistry *KubernetesImageRegistry `json:"kubernetesImageRegistry,omitempty"`
3535

36+
// +optional
37+
Etcd *Etcd `json:"etcd,omitempty"`
38+
3639
// +optional
3740
Proxy *HTTPProxy `json:"proxy,omitempty"`
3841

@@ -53,6 +56,7 @@ func (ClusterConfigSpec) VariableSchema() clusterv1.VariableSchema {
5356
"",
5457
).VariableSchema().
5558
OpenAPIV3Schema,
59+
"etcd": Etcd{}.VariableSchema().OpenAPIV3Schema,
5660
"proxy": HTTPProxy{}.VariableSchema().OpenAPIV3Schema,
5761
"extraAPIServerCertSANs": ExtraAPIServerCertSANs{}.VariableSchema().OpenAPIV3Schema,
5862
"cni": CNI{}.VariableSchema().OpenAPIV3Schema,
@@ -77,6 +81,32 @@ func (v KubernetesImageRegistry) String() string {
7781
return string(v)
7882
}
7983

84+
type Etcd struct {
85+
// ImageRepository required for overriding etcd image repository.
86+
ImageRepository string `json:"imageRepository,omitempty"`
87+
88+
// ImageTag required for overriding etcd image tag.
89+
ImageTag string `json:"imageTag,omitempty"`
90+
}
91+
92+
func (Etcd) VariableSchema() clusterv1.VariableSchema {
93+
return clusterv1.VariableSchema{
94+
OpenAPIV3Schema: clusterv1.JSONSchemaProps{
95+
Type: "object",
96+
Properties: map[string]clusterv1.JSONSchemaProps{
97+
"imageRepository": {
98+
Description: "Image repository for etcd.",
99+
Type: "string",
100+
},
101+
"imageTag": {
102+
Description: "Image tag for etcd.",
103+
Type: "string",
104+
},
105+
},
106+
},
107+
}
108+
}
109+
80110
// HTTPProxy required for providing proxy configuration.
81111
type HTTPProxy struct {
82112
// HTTP proxy.

api/v1alpha1/zz_generated.deepcopy.go

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

cmd/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/auditpolicy"
3030
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/clusterconfig"
3131
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/cni/calico"
32+
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/etcd"
3233
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/extraapiservercertsans"
3334
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/httpproxy"
3435
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/kubernetesimageregistry"
@@ -129,6 +130,9 @@ func main() {
129130
kubernetesimageregistry.NewVariable(),
130131
kubernetesimageregistry.NewPatch(kubernetesimageregistry.VariableName),
131132

133+
etcd.NewVariable(),
134+
etcd.NewPatch(etcd.VariableName),
135+
132136
clusterconfig.NewVariable(),
133137
mutation.NewMetaGeneratePatchesHandler(
134138
"clusterConfigPatch",
@@ -142,6 +146,7 @@ func main() {
142146
clusterconfig.VariableName,
143147
kubernetesimageregistry.VariableName,
144148
),
149+
etcd.NewPatch(clusterconfig.VariableName, etcd.VariableName),
145150
),
146151
)
147152
if err := mgr.Add(runtimeWebhookServer); err != nil {

docs/content/cluster-config.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ spec:
3636
- name: clusterConfig
3737
value:
3838
kubernetesImageRegistry: "my-registry.io/my-org/my-repo"
39+
etcd:
40+
imageRepository: my-registry.io/my-org/my-repo
41+
imageTag: "v3.5.99_custom.0"
3942
extraAPIServerCertSANs:
4043
- a.b.c.example.com
4144
- d.e.f.example.com

docs/content/etcd.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: "etcd"
3+
---
4+
5+
Override the container image registry and tag for [etcd](https://github.com/etcd-io/etcd).
6+
7+
To enable this handler set the `etcdpatch` and `etcdvars` external patches on `ClusterClass`.
8+
9+
```yaml
10+
apiVersion: cluster.x-k8s.io/v1beta1
11+
kind: ClusterClass
12+
metadata:
13+
name: <NAME>
14+
spec:
15+
patches:
16+
- name: image-registry
17+
external:
18+
generateExtension: "etcdpatch.capi-runtime-extensions"
19+
discoverVariablesExtension: "etcdvars.capi-runtime-extensions"
20+
```
21+
22+
On the cluster resource then specify desired etcd image registry and/or image tag values:
23+
24+
```yaml
25+
apiVersion: cluster.x-k8s.io/v1beta1
26+
kind: Cluster
27+
metadata:
28+
name: <NAME>
29+
spec:
30+
topology:
31+
variables:
32+
- name: etcd
33+
values:
34+
imageRepository: my-registry.io/my-org/my-repo
35+
imageTag: "v3.5.99_custom.0"
36+
```
37+
38+
Applying this configuration will result in the following value being set:
39+
40+
- KubeadmControlPlaneTemplate:
41+
42+
- ```yaml
43+
spec:
44+
kubeadmConfigSpec:
45+
clusterConfiguration:
46+
etcd:
47+
local:
48+
imageRepository: "my-registry.io/my-org/my-repo"
49+
imageTag: "v3.5.99_custom.0"
50+
```

pkg/handlers/cni/constants.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2023 D2iQ, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package cni
5+
6+
import "github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers"
7+
8+
const (
9+
CNIProviderLabelKey = handlers.MetadataDomain + "/cni"
10+
)

pkg/handlers/etcd/inject.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Copyright 2023 D2iQ, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package etcd
5+
6+
import (
7+
"context"
8+
_ "embed"
9+
10+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
11+
"k8s.io/apimachinery/pkg/runtime"
12+
"k8s.io/apimachinery/pkg/runtime/serializer"
13+
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
14+
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
15+
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
16+
"sigs.k8s.io/cluster-api/exp/runtime/topologymutation"
17+
ctrl "sigs.k8s.io/controller-runtime"
18+
"sigs.k8s.io/controller-runtime/pkg/client"
19+
20+
"github.com/d2iq-labs/capi-runtime-extensions/api/v1alpha1"
21+
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers"
22+
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers/mutation"
23+
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/patches"
24+
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/patches/selectors"
25+
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/variables"
26+
)
27+
28+
const (
29+
// HandlerNamePatch is the name of the inject handler.
30+
HandlerNamePatch = "EtcdPatch"
31+
)
32+
33+
type etcdPatchHandler struct {
34+
decoder runtime.Decoder
35+
variableName string
36+
variableFieldPath []string
37+
}
38+
39+
var (
40+
_ handlers.Named = &etcdPatchHandler{}
41+
_ mutation.GeneratePatches = &etcdPatchHandler{}
42+
)
43+
44+
func NewPatch(
45+
variableName string,
46+
variableFieldPath ...string,
47+
) *etcdPatchHandler {
48+
scheme := runtime.NewScheme()
49+
_ = bootstrapv1.AddToScheme(scheme)
50+
_ = controlplanev1.AddToScheme(scheme)
51+
return &etcdPatchHandler{
52+
decoder: serializer.NewCodecFactory(scheme).UniversalDecoder(
53+
controlplanev1.GroupVersion,
54+
bootstrapv1.GroupVersion,
55+
),
56+
variableName: variableName,
57+
variableFieldPath: variableFieldPath,
58+
}
59+
}
60+
61+
func (h *etcdPatchHandler) Name() string {
62+
return HandlerNamePatch
63+
}
64+
65+
func (h *etcdPatchHandler) GeneratePatches(
66+
ctx context.Context,
67+
req *runtimehooksv1.GeneratePatchesRequest,
68+
resp *runtimehooksv1.GeneratePatchesResponse,
69+
) {
70+
topologymutation.WalkTemplates(
71+
ctx,
72+
h.decoder,
73+
req,
74+
resp,
75+
func(
76+
ctx context.Context,
77+
obj runtime.Object,
78+
vars map[string]apiextensionsv1.JSON,
79+
holderRef runtimehooksv1.HolderReference,
80+
) error {
81+
log := ctrl.LoggerFrom(ctx).WithValues(
82+
"holderRef", holderRef,
83+
)
84+
85+
etcd, found, err := variables.Get[v1alpha1.Etcd](
86+
vars,
87+
h.variableName,
88+
h.variableFieldPath...,
89+
)
90+
if err != nil {
91+
return err
92+
}
93+
if !found {
94+
log.V(5).Info("etcd variable not defined")
95+
return nil
96+
}
97+
98+
log = log.WithValues(
99+
"variableName",
100+
h.variableName,
101+
"variableFieldPath",
102+
h.variableFieldPath,
103+
"variableValue",
104+
etcd,
105+
)
106+
107+
return patches.Generate(
108+
obj, vars, &holderRef, selectors.ControlPlane(), log,
109+
func(obj *controlplanev1.KubeadmControlPlaneTemplate) error {
110+
log.WithValues(
111+
"patchedObjectKind", obj.GetObjectKind().GroupVersionKind().String(),
112+
"patchedObjectName", client.ObjectKeyFromObject(obj),
113+
).Info("setting etcd configuration in kubeadm config spec")
114+
115+
if obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration == nil {
116+
obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration = &bootstrapv1.ClusterConfiguration{}
117+
}
118+
if obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.Etcd.Local == nil {
119+
obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.Etcd.Local = &bootstrapv1.LocalEtcd{}
120+
}
121+
122+
localEtcd := obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.Etcd.Local
123+
if etcd.ImageTag != "" {
124+
localEtcd.ImageTag = etcd.ImageTag
125+
}
126+
if etcd.ImageRepository != "" {
127+
localEtcd.ImageRepository = etcd.ImageRepository
128+
}
129+
130+
return nil
131+
},
132+
)
133+
},
134+
)
135+
}

0 commit comments

Comments
 (0)