Skip to content

Commit ed20527

Browse files
Enhanced node reconciliation by automating maintenance CR lifecycle (#157)
* Node maintenance controller * Node maintenance finalizer * Local environment * go mod tidy * Changes motivated by code review * ServerMaintenance managed-by label * Check for ServerMaintenance owner before CreateOrPatch() * Delete ServerMaintenance even if ServerClaim not found * Refactor providerID logic + switch to komega in tests * metal operator v0.4.0
1 parent ce4dbd4 commit ed20527

File tree

16 files changed

+806
-117
lines changed

16 files changed

+806
-117
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,10 @@ vendor
2525
*.swo
2626
*~
2727
dev/
28+
29+
.tiltbuild
30+
31+
# kind configs
32+
config/kind/mgmt-kubeconfig-external
33+
config/kind/mgmt-kubeconfig-internal
34+
config/kind/worker-kubeconfig

Makefile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ check-license: addlicense ## Check that every file has a license header present.
6767

6868
check: add-license lint test
6969

70+
.PHONY: kind-setup
71+
kind-setup:
72+
kind create cluster --name mgmt
73+
kind create cluster --name worker
74+
75+
.PHONY: export-kubeconfig
76+
export-kubeconfig:
77+
kind get kubeconfig --name mgmt > ./config/kind/mgmt-kubeconfig-external # for applying crds to mgmt cluster via tilt
78+
kind get kubeconfig --name mgmt --internal > ./config/kind/mgmt-kubeconfig-internal # for ccm config (it needs access to mgmt cluster)
79+
kind get kubeconfig --name worker > ./config/kind/worker-kubeconfig # for applying crds to worker cluster via tilt
80+
81+
.PHONY: tilt-up
82+
tilt-up: kind-setup export-kubeconfig
83+
KUBECONFIG=./config/kind/mgmt-kubeconfig:./config/kind/worker-kubeconfig tilt up
84+
7085
##@ Build
7186

7287
.PHONY: build
@@ -78,7 +93,7 @@ run: fmt vet ## Run a metal cloud controller from your host.
7893
go run ./cmd/metal-cloud-controller-manager/main.go
7994

8095
.PHONY: docker-build
81-
docker-build: test ## Build docker image with the metal cloud controller.
96+
docker-build: ## Build docker image with the metal cloud controller.
8297
$(CONTAINER_TOOL) build -t ${CONTROLLER_IMG} .
8398

8499
.PHONY: docker-push

Tiltfile

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
allow_k8s_contexts(['kind-mgmt', 'kind-worker'])
2+
3+
mgmt_ctx = 'kind-mgmt'
4+
worker_ctx = 'kind-worker'
5+
6+
mgmt_kubeconfig = './config/kind/mgmt-kubeconfig-external'
7+
worker_kubeconfig = './config/kind/worker-kubeconfig'
8+
9+
def mgmt_kubectl(args):
10+
return local('kubectl --kubeconfig=' + mgmt_kubeconfig + ' --context=' + mgmt_ctx + ' ' + args)
11+
12+
def worker_kubectl(args):
13+
return local('kubectl --kubeconfig=' + worker_kubeconfig + ' --context=' + worker_ctx + ' ' + args)
14+
15+
METAL_OPERATOR_REF = "v0.4.0"
16+
mgmt_kubectl('apply -f https://raw.githubusercontent.com/ironcore-dev/metal-operator/' + METAL_OPERATOR_REF + '/config/crd/bases/metal.ironcore.dev_serverclaims.yaml')
17+
mgmt_kubectl('apply -f https://raw.githubusercontent.com/ironcore-dev/metal-operator/' + METAL_OPERATOR_REF + '/config/crd/bases/metal.ironcore.dev_servermaintenances.yaml')
18+
mgmt_kubectl('apply -f https://raw.githubusercontent.com/ironcore-dev/metal-operator/' + METAL_OPERATOR_REF + '/config/crd/bases/metal.ironcore.dev_servers.yaml')
19+
mgmt_kubectl('wait --for=condition=Established --timeout=60s crd/serverclaims.metal.ironcore.dev')
20+
mgmt_kubectl('wait --for=condition=Established --timeout=60s crd/servermaintenances.metal.ironcore.dev')
21+
mgmt_kubectl('wait --for=condition=Established --timeout=60s crd/servers.metal.ironcore.dev')
22+
mgmt_kubectl('apply -f config/kind/crs/server.yaml')
23+
mgmt_kubectl('apply -f config/kind/crs/serverclaim.yaml')
24+
25+
worker_kubectl('apply -k config/kind') # kustomize
26+
worker_kubectl('apply -f config/kind/crs/node.yaml')
27+
28+
local_resource(
29+
"manager-binary",
30+
cmd = 'mkdir -p .tiltbuild; CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o .tiltbuild/manager ./cmd/metal-cloud-controller-manager/main.go',
31+
deps = ["pkg", "cmd", "go.mod", "go.sum"]
32+
)
33+
34+
docker_build(
35+
ref = "controller",
36+
context = "./.tiltbuild/",
37+
dockerfile_contents = """
38+
FROM gcr.io/distroless/static:nonroot
39+
WORKDIR /
40+
COPY manager /metal-cloud-controller-manager
41+
USER 65532:65532
42+
ENTRYPOINT ["/metal-cloud-controller-manager"]
43+
""",
44+
only = "manager"
45+
)
46+
47+
k8s_yaml(kustomize('config/kind'))
48+
49+
k8s_resource(
50+
'cloud-controller-manager',
51+
labels=['CCM'],
52+
port_forwards='10258:10258',
53+
extra_pod_selectors=[{'app.kubernetes.io/name': 'cloud-controller-manager'}]
54+
)

Tiltfile.license

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SPDX-FileCopyrightText: 2026 SAP SE
2+
3+
SPDX-License-Identifier: Apache-2.0

config/kind/cloud-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
clusterName: kind-ccm
2+
networking:
3+
configureNodeAddresses: true
4+
ipamKind:
5+
apiGroup: metal.ironcore.dev
6+
kind: ServerClaim

config/kind/crs/node.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: v1
2+
kind: Node
3+
metadata:
4+
name: metal-node-1
5+
labels:
6+
kubernetes.io/hostname: metal-node-1
7+
spec:
8+
providerID: metal://default/server-1

config/kind/crs/server.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: metal.ironcore.dev/v1alpha1
2+
kind: Server
3+
metadata:
4+
name: physical-server-1
5+
spec:
6+
systemUUID: "some-uuid"

config/kind/crs/serverclaim.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: metal.ironcore.dev/v1alpha1
2+
kind: ServerClaim
3+
metadata:
4+
name: server-1
5+
namespace: default
6+
spec:
7+
image: "test-image"
8+
power: "On"
9+
serverRef:
10+
name: physical-server-1
11+
serverSelector:
12+
matchLabels:
13+
machine: "true"

config/kind/kustomization.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: kustomize.config.k8s.io/v1beta1
2+
kind: Kustomization
3+
namespace: kube-system
4+
5+
resources:
6+
- ../default
7+
8+
patches:
9+
- target:
10+
kind: Deployment
11+
name: manager
12+
path: manager-patch.yaml
13+
14+
secretGenerator:
15+
- name: metal-cloud-config
16+
namespace: kube-system
17+
files:
18+
- cloud-config=cloud-config.yaml
19+
- kubeconfig=mgmt-kubeconfig-internal
20+
21+
generatorOptions:
22+
disableNameSuffixHash: true

config/kind/manager-patch.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: manager
5+
spec:
6+
strategy:
7+
type: Recreate
8+
template:
9+
spec:
10+
containers:
11+
- name: manager
12+
image: controller
13+
imagePullPolicy: IfNotPresent
14+
args:
15+
- --cloud-provider=metal
16+
- --cloud-config=/etc/kubernetes/cloud-config/cloud-config
17+
- --metal-kubeconfig=/etc/kubernetes/cloud-config/kubeconfig
18+
- --concurrent-service-syncs=10
19+
- --leader-elect=false
20+
- --secure-port=10258
21+
- --v=2
22+
volumeMounts:
23+
- mountPath: /etc/kubernetes/cloud-config
24+
name: cloud-config
25+
readOnly: true
26+
volumes:
27+
- name: cloud-config
28+
secret:
29+
secretName: metal-cloud-config

0 commit comments

Comments
 (0)