Skip to content

Commit d53c60d

Browse files
committed
Update ControlPlaneEndpoint InfraCluster contract, align CAPD to infra
contracts Signed-off-by: Stefan Büringer buringerst@vmware.com
1 parent ea6314d commit d53c60d

23 files changed

+230
-74
lines changed

docs/book/src/developer/providers/contracts/infra-cluster.md

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,19 +221,26 @@ in the InfraCluster resource.
221221
type FooClusterSpec struct {
222222
// controlPlaneEndpoint represents the endpoint used to communicate with the control plane.
223223
// +optional
224-
ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint"`
224+
ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint,omitempty,omitzero"`
225225

226226
// See other rules for more details about mandatory/optional fields in InfraCluster spec.
227227
// Other fields SHOULD be added based on the needs of your provider.
228228
}
229229

230230
// APIEndpoint represents a reachable Kubernetes API endpoint.
231+
// +kubebuilder:validation:MinProperties=1
231232
type APIEndpoint struct {
232233
// host is the hostname on which the API server is serving.
233-
Host string `json:"host"`
234-
234+
// +optional
235+
// +kubebuilder:validation:MinLength=1
236+
// +kubebuilder:validation:MaxLength=512
237+
Host string `json:"host,omitempty"`
238+
235239
// port is the port on which the API server is serving.
236-
Port int32 `json:"port"`
240+
// +optional
241+
// +kubebuilder:validation:Minimum=1
242+
// +kubebuilder:validation:Maximum=65535
243+
Port int32 `json:"port,omitempty"`
237244
}
238245
```
239246

@@ -243,6 +250,35 @@ the Cluster controller will surface this info in Cluster's `spec.controlPlaneEnd
243250
If instead you are developing an infrastructure provider which is NOT responsible to provide a control plane endpoint,
244251
the implementer should exit reconciliation until it sees Cluster's `spec.controlPlaneEndpoint` populated.
245252

253+
<aside class="note warning">
254+
255+
<h1>Compatibility with the deprecated v1beta1 contract</h1>
256+
257+
In order to ease the transition for providers, the v1beta2 version of the Cluster API contract _temporarily_
258+
preserves compatibility with the deprecated v1beta1 contract; compatibility will be removed tentatively in August 2026.
259+
260+
```go
261+
type FooClusterSpec struct {
262+
// controlPlaneEndpoint represents the endpoint used to communicate with the control plane.
263+
// +optional
264+
ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint"`
265+
266+
// See other rules for more details about mandatory/optional fields in InfraCluster spec.
267+
// Other fields SHOULD be added based on the needs of your provider.
268+
}
269+
270+
// APIEndpoint represents a reachable Kubernetes API endpoint.
271+
type APIEndpoint struct {
272+
// host is the hostname on which the API server is serving.
273+
Host string `json:"host"`
274+
275+
// port is the port on which the API server is serving.
276+
Port int32 `json:"port"`
277+
}
278+
```
279+
280+
</aside>
281+
246282
### InfraCluster: failure domains
247283

248284
In case you are developing an infrastructure provider which has a notion of failure domains where machines should be

docs/book/src/developer/providers/migrations/v1.10-to-v1.11.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ KubeadmControlPlaneTemplate `spec.template.spec` has been aligned to changes in
437437
Following rules have been changed or are not supported anymore; please read corresponding notes about compatibility
438438
for providers still implementing the v1beta1 contract.
439439

440+
- [InfraCluster: control plane endpoint](../contracts/infra-cluster.md#infracluster-control-plane-endpoint)
440441
- [InfraCluster: failure domains](../contracts/infra-cluster.md#infracluster-failure-domains)
441442
- [InfraCluster: initialization completed](../contracts/infra-cluster.md#infracluster-initialization-completed)
442443
- [InfraCluster: conditions](../contracts/infra-cluster.md#infracluster-conditions)

test/infrastructure/docker/api/v1alpha3/conversion.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ func (dst *DockerMachine) ConvertFrom(srcRaw conversion.Hub) error {
108108
return err
109109
}
110110

111+
if dst.Spec.ProviderID != nil && *dst.Spec.ProviderID == "" {
112+
dst.Spec.ProviderID = nil
113+
}
114+
111115
if err := utilconversion.MarshalData(src, dst); err != nil {
112116
return err
113117
}
@@ -141,6 +145,10 @@ func (dst *DockerMachineTemplate) ConvertFrom(srcRaw conversion.Hub) error {
141145
return err
142146
}
143147

148+
if dst.Spec.Template.Spec.ProviderID != nil && *dst.Spec.Template.Spec.ProviderID == "" {
149+
dst.Spec.Template.Spec.ProviderID = nil
150+
}
151+
144152
// Preserve Hub data on down-conversion except for metadata
145153
if err := utilconversion.MarshalData(src, dst); err != nil {
146154
return err

test/infrastructure/docker/api/v1alpha3/conversion_test.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ func TestFuzzyConversion(t *testing.T) {
4848
}))
4949

5050
t.Run("for DockerMachineTemplate", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
51-
Hub: &infrav1.DockerMachineTemplate{},
52-
Spoke: &DockerMachineTemplate{},
51+
Hub: &infrav1.DockerMachineTemplate{},
52+
Spoke: &DockerMachineTemplate{},
53+
FuzzerFuncs: []fuzzer.FuzzerFuncs{DockerMachineTemplateFuzzFunc},
5354
}))
5455
}
5556

@@ -87,6 +88,7 @@ func hubFailureDomain(in *clusterv1.FailureDomain, c randfill.Continue) {
8788
func DockerMachineFuzzFunc(_ runtimeserializer.CodecFactory) []any {
8889
return []any{
8990
hubDockerMachineStatus,
91+
spokeDockerMachineSpec,
9092
}
9193
}
9294

@@ -105,3 +107,17 @@ func hubDockerMachineStatus(in *infrav1.DockerMachineStatus, c randfill.Continue
105107
}
106108
}
107109
}
110+
111+
func spokeDockerMachineSpec(in *DockerMachineSpec, c randfill.Continue) {
112+
c.FillNoCustom(in)
113+
114+
if in.ProviderID != nil && *in.ProviderID == "" {
115+
in.ProviderID = nil
116+
}
117+
}
118+
119+
func DockerMachineTemplateFuzzFunc(_ runtimeserializer.CodecFactory) []any {
120+
return []any{
121+
spokeDockerMachineSpec,
122+
}
123+
}

test/infrastructure/docker/api/v1alpha3/zz_generated.conversion.go

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

test/infrastructure/docker/api/v1alpha4/conversion.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ func (dst *DockerMachine) ConvertFrom(srcRaw conversion.Hub) error {
136136
return err
137137
}
138138

139+
if dst.Spec.ProviderID != nil && *dst.Spec.ProviderID == "" {
140+
dst.Spec.ProviderID = nil
141+
}
142+
139143
if err := utilconversion.MarshalData(src, dst); err != nil {
140144
return err
141145
}
@@ -169,6 +173,10 @@ func (dst *DockerMachineTemplate) ConvertFrom(srcRaw conversion.Hub) error {
169173
return err
170174
}
171175

176+
if dst.Spec.Template.Spec.ProviderID != nil && *dst.Spec.Template.Spec.ProviderID == "" {
177+
dst.Spec.Template.Spec.ProviderID = nil
178+
}
179+
172180
// Preserve Hub data on down-conversion except for metadata
173181
if err := utilconversion.MarshalData(src, dst); err != nil {
174182
return err

test/infrastructure/docker/api/v1alpha4/conversion_test.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ func TestFuzzyConversion(t *testing.T) {
5454
}))
5555

5656
t.Run("for DockerMachineTemplate", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
57-
Hub: &infrav1.DockerMachineTemplate{},
58-
Spoke: &DockerMachineTemplate{},
57+
Hub: &infrav1.DockerMachineTemplate{},
58+
Spoke: &DockerMachineTemplate{},
59+
FuzzerFuncs: []fuzzer.FuzzerFuncs{DockerMachineTemplateFuzzFunc},
5960
}))
6061
}
6162

@@ -99,6 +100,7 @@ func DockerClusterTemplateFuzzFunc(_ runtimeserializer.CodecFactory) []any {
99100
func DockerMachineFuzzFunc(_ runtimeserializer.CodecFactory) []any {
100101
return []any{
101102
hubDockerMachineStatus,
103+
spokeDockerMachineSpec,
102104
}
103105
}
104106

@@ -117,3 +119,17 @@ func hubDockerMachineStatus(in *infrav1.DockerMachineStatus, c randfill.Continue
117119
}
118120
}
119121
}
122+
123+
func spokeDockerMachineSpec(in *DockerMachineSpec, c randfill.Continue) {
124+
c.FillNoCustom(in)
125+
126+
if in.ProviderID != nil && *in.ProviderID == "" {
127+
in.ProviderID = nil
128+
}
129+
}
130+
131+
func DockerMachineTemplateFuzzFunc(_ runtimeserializer.CodecFactory) []any {
132+
return []any{
133+
spokeDockerMachineSpec,
134+
}
135+
}

test/infrastructure/docker/api/v1alpha4/zz_generated.conversion.go

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

test/infrastructure/docker/api/v1beta1/conversion.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ func (dst *DockerMachine) ConvertFrom(srcRaw conversion.Hub) error {
9999
return err
100100
}
101101

102+
if dst.Spec.ProviderID != nil && *dst.Spec.ProviderID == "" {
103+
dst.Spec.ProviderID = nil
104+
}
105+
102106
if err := utilconversion.MarshalData(src, dst); err != nil {
103107
return err
104108
}
@@ -115,7 +119,15 @@ func (src *DockerMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
115119
func (dst *DockerMachineTemplate) ConvertFrom(srcRaw conversion.Hub) error {
116120
src := srcRaw.(*infrav1.DockerMachineTemplate)
117121

118-
return Convert_v1beta2_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(src, dst, nil)
122+
if err := Convert_v1beta2_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(src, dst, nil); err != nil {
123+
return err
124+
}
125+
126+
if dst.Spec.Template.Spec.ProviderID != nil && *dst.Spec.Template.Spec.ProviderID == "" {
127+
dst.Spec.Template.Spec.ProviderID = nil
128+
}
129+
130+
return nil
119131
}
120132

121133
func (src *DevCluster) ConvertTo(dstRaw conversion.Hub) error {
@@ -185,6 +197,10 @@ func (dst *DevMachine) ConvertFrom(srcRaw conversion.Hub) error {
185197
return err
186198
}
187199

200+
if dst.Spec.ProviderID != nil && *dst.Spec.ProviderID == "" {
201+
dst.Spec.ProviderID = nil
202+
}
203+
188204
if err := utilconversion.MarshalData(src, dst); err != nil {
189205
return err
190206
}
@@ -201,7 +217,15 @@ func (src *DevMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
201217
func (dst *DevMachineTemplate) ConvertFrom(srcRaw conversion.Hub) error {
202218
src := srcRaw.(*infrav1.DevMachineTemplate)
203219

204-
return Convert_v1beta2_DevMachineTemplate_To_v1beta1_DevMachineTemplate(src, dst, nil)
220+
if err := Convert_v1beta2_DevMachineTemplate_To_v1beta1_DevMachineTemplate(src, dst, nil); err != nil {
221+
return err
222+
}
223+
224+
if dst.Spec.Template.Spec.ProviderID != nil && *dst.Spec.Template.Spec.ProviderID == "" {
225+
dst.Spec.Template.Spec.ProviderID = nil
226+
}
227+
228+
return nil
205229
}
206230

207231
func Convert_v1beta1_ObjectMeta_To_v1beta2_ObjectMeta(in *clusterv1beta1.ObjectMeta, out *clusterv1.ObjectMeta, s apiconversion.Scope) error {

0 commit comments

Comments
 (0)