Skip to content

Commit 8661d4b

Browse files
committed
feat: Add IPAM integration
- Added RBAC rules - Fixed reconcile Signed-off-by: appkins <nbatkins@gmail.com>
1 parent 35364da commit 8661d4b

15 files changed

+1050
-41
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,12 @@ jobs:
7373
go-version: "${{ env.GO_VERSION }}"
7474
cache: true
7575

76-
- name: Set up QEMU
77-
uses: docker/setup-qemu-action@v3
78-
79-
- name: Set up Docker Buildx
80-
uses: docker/setup-buildx-action@v3
81-
82-
- name: Log in to the Container registry
83-
uses: docker/login-action@v3
84-
with:
85-
registry: ${{ env.REGISTRY }}
86-
username: ${{ github.actor }}
87-
password: ${{ secrets.GITHUB_TOKEN }}
76+
- uses: ko-build/setup-ko@v0.9
77+
- run: ko login ${{ env.REGISTRY }} -u ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }}
8878

8979
- name: Build and push image
9080
run: make build-image-push
9181
env:
9282
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93-
IS_RELEASE: false
94-
GORELEASER_EXTRA_FLAGS: "--skip=validate"
83+
IS_RELEASE: true
84+
GORELEASER_EXTRA_FLAGS: "--clean --skip=validate"

.github/workflows/release.yaml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,12 @@ jobs:
2727
go-version: "${{ env.GO_VERSION }}"
2828
cache: true
2929

30-
- name: Set up QEMU
31-
uses: docker/setup-qemu-action@v3
32-
33-
- name: Set up Docker Buildx
34-
uses: docker/setup-buildx-action@v3
35-
36-
- name: Log in to the Container registry
37-
uses: docker/login-action@v3
38-
with:
39-
registry: ${{ env.REGISTRY }}
40-
username: ${{ github.actor }}
41-
password: ${{ secrets.GITHUB_TOKEN }}
30+
- uses: ko-build/setup-ko@v0.9
31+
env:
32+
KO_DEFAULTBASEIMAGE: docker.io/chainguard/static
33+
KO_DOCKER_REPO: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
34+
35+
- run: ko login ${{ env.REGISTRY }} -u ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }}
4236

4337
- name: Build and push image
4438
run: make build-image-push

.goreleaser.yaml

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: 2
22

33
env:
44
- REGISTRY={{ if index .Env "REGISTRY" }}{{ .Env.REGISTRY }}{{ else }}ghcr.io{{ end }}
5-
- IMAGE_NAME={{ if index .Env "IMAGE_NAME" }}{{ .Env.IMAGE_NAME }}{{ else }}tinkerbell/cluster-api-provider-tinkerbell{{ end }}
5+
- IMAGE_NAME={{ if index .Env "IMAGE_NAME" }}{{ .Env.IMAGE_NAME }}{{ else }}{{.GitURL | trimprefix "https://" | trimprefix "git@" | trimprefix "github.com" | trimprefix ":" | trimprefix "/" | trimsuffix ".git"}}{{ end }}
66
- BINARY=capt
77
- IS_RELEASE={{ if index .Env "IS_RELEASE" }}{{ .Env.IS_RELEASE }}{{ else }}true{{ end }}
88

@@ -14,35 +14,50 @@ builds:
1414
- id: build
1515
binary: "{{ .Env.BINARY }}"
1616
env:
17-
- CGO_ENABLED=0
17+
- CGO_ENABLED=0
1818
goos:
19-
- linux
19+
- linux
2020
ldflags:
21-
- -s -w
21+
- -s -w
2222
goarch:
23-
- amd64
24-
- arm64
23+
- amd64
24+
- arm64
25+
skip: false
2526

2627
checksum:
27-
name_template: 'checksums.txt'
28+
name_template: "checksums.txt"
2829

2930
archives:
3031
- formats:
31-
- binary
32+
- binary
3233

3334
release:
3435
disable: true
3536

36-
dockers_v2:
37-
- images:
37+
snapshot:
38+
version_template: "{{ incpatch .Version }}-next"
39+
40+
kos:
41+
- build: build
42+
repositories:
3843
- "{{ .Env.REGISTRY }}/{{ .Env.IMAGE_NAME }}"
3944
tags:
4045
- '{{ if eq .Env.IS_RELEASE "true" }}v{{ .Version }}{{ end }}'
41-
- '{{ if not .IsNightly }}latest{{ end }}'
46+
- "{{ if not .IsSnapshot }}latest{{ end }}"
4247
- '{{ if eq .Branch "main" }}sha-{{ .ShortCommit }}{{ end }}'
4348
labels:
4449
"org.opencontainers.image.created": "{{.Date}}"
4550
"org.opencontainers.image.name": "{{.ProjectName}}"
4651
"org.opencontainers.image.revision": "{{.FullCommit}}"
4752
"org.opencontainers.image.version": "v{{.Version}}"
4853
"org.opencontainers.image.source": "{{.GitURL}}"
54+
bare: true
55+
preserve_import_paths: false
56+
platforms:
57+
- linux/amd64
58+
- linux/arm64
59+
base_image: docker.io/chainguard/static
60+
creation_time: "{{.CommitTimestamp}}"
61+
ko_data_creation_time: "{{.CommitTimestamp}}"
62+
sbom: none
63+
disable: "{{ .IsSnapshot }}"

api/v1beta1/tinkerbellmachine_types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ type TinkerbellMachineSpec struct {
8282
// +optional
8383
BootOptions BootOptions `json:"bootOptions,omitempty"`
8484

85+
// IPAMPoolRef is a reference to an IPAM pool resource to allocate an IP address from.
86+
// When specified, an IPAddressClaim will be created to request an IP address allocation.
87+
// The allocated IP will be set on the Hardware's first interface DHCP configuration.
88+
// This enables integration with Cluster API IPAM providers for dynamic IP allocation.
89+
// +optional
90+
IPAMPoolRef *corev1.TypedLocalObjectReference `json:"ipamPoolRef,omitempty"`
91+
8592
// Those fields are set programmatically, but they cannot be re-constructed from "state of the world", so
8693
// we put them in spec instead of status.
8794
HardwareName string `json:"hardwareName,omitempty"`

api/v1beta1/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.

config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,30 @@ spec:
265265
ImageLookupOSVersion is the version of the OS distribution to use when fetching machine
266266
images. If not set it will default based on ImageLookupOSDistro.
267267
type: string
268+
ipamPoolRef:
269+
description: |-
270+
IPAMPoolRef is a reference to an IPAM pool resource to allocate an IP address from.
271+
When specified, an IPAddressClaim will be created to request an IP address allocation.
272+
The allocated IP will be set on the Hardware's first interface DHCP configuration.
273+
This enables integration with Cluster API IPAM providers for dynamic IP allocation.
274+
properties:
275+
apiGroup:
276+
description: |-
277+
APIGroup is the group for the resource being referenced.
278+
If APIGroup is not specified, the specified Kind must be in the core API group.
279+
For any other third-party types, APIGroup is required.
280+
type: string
281+
kind:
282+
description: Kind is the type of resource being referenced
283+
type: string
284+
name:
285+
description: Name is the name of resource being referenced
286+
type: string
287+
required:
288+
- kind
289+
- name
290+
type: object
291+
x-kubernetes-map-type: atomic
268292
providerID:
269293
type: string
270294
templateOverride:

config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,30 @@ spec:
258258
ImageLookupOSVersion is the version of the OS distribution to use when fetching machine
259259
images. If not set it will default based on ImageLookupOSDistro.
260260
type: string
261+
ipamPoolRef:
262+
description: |-
263+
IPAMPoolRef is a reference to an IPAM pool resource to allocate an IP address from.
264+
When specified, an IPAddressClaim will be created to request an IP address allocation.
265+
The allocated IP will be set on the Hardware's first interface DHCP configuration.
266+
This enables integration with Cluster API IPAM providers for dynamic IP allocation.
267+
properties:
268+
apiGroup:
269+
description: |-
270+
APIGroup is the group for the resource being referenced.
271+
If APIGroup is not specified, the specified Kind must be in the core API group.
272+
For any other third-party types, APIGroup is required.
273+
type: string
274+
kind:
275+
description: Kind is the type of resource being referenced
276+
type: string
277+
name:
278+
description: Name is the name of resource being referenced
279+
type: string
280+
required:
281+
- kind
282+
- name
283+
type: object
284+
x-kubernetes-map-type: atomic
261285
providerID:
262286
type: string
263287
templateOverride:

config/rbac/role.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,34 @@ rules:
5454
- get
5555
- patch
5656
- update
57+
- apiGroups:
58+
- ipam.cluster.x-k8s.io
59+
resources:
60+
- ipaddressclaims
61+
verbs:
62+
- create
63+
- delete
64+
- get
65+
- list
66+
- patch
67+
- update
68+
- watch
69+
- apiGroups:
70+
- ipam.cluster.x-k8s.io
71+
resources:
72+
- ipaddressclaims/status
73+
verbs:
74+
- get
75+
- patch
76+
- update
77+
- apiGroups:
78+
- ipam.cluster.x-k8s.io
79+
resources:
80+
- ipaddresses
81+
verbs:
82+
- get
83+
- list
84+
- watch
5785
- apiGroups:
5886
- tinkerbell.org
5987
resources:

controller/machine/hardware.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package machine
22

33
import (
44
"fmt"
5+
"maps"
56
"sort"
67
"strings"
78

@@ -84,9 +85,7 @@ func (scope *machineReconcileScope) patchHardwareAnnotations(hw *tinkv1.Hardware
8485
hw.Annotations = map[string]string{}
8586
}
8687

87-
for k, v := range annotations {
88-
hw.Annotations[k] = v
89-
}
88+
maps.Copy(hw.Annotations, annotations)
9089

9190
if err := patchHelper.Patch(scope.ctx, hw); err != nil {
9291
return fmt.Errorf("patching Hardware object: %w", err)
@@ -152,6 +151,14 @@ func (scope *machineReconcileScope) ensureHardware() (*tinkv1.Hardware, error) {
152151
return nil, fmt.Errorf("ensuring Hardware user data: %w", err)
153152
}
154153

154+
// Check if IPAM pool is configured and handle IP allocation
155+
poolRef := scope.getIPAMPoolRef()
156+
if poolRef != nil {
157+
if err := scope.reconcileIPAM(hw, poolRef); err != nil {
158+
return hw, fmt.Errorf("failed to reconcile IPAM: %w", err)
159+
}
160+
}
161+
155162
return hw, scope.setStatus(hw)
156163
}
157164

0 commit comments

Comments
 (0)