Skip to content

Commit 6428bf2

Browse files
authored
Merge pull request #7297 from sbueringer/pr-update-contract
⚠️ contract: add CRD naming requirements
2 parents 75bc1ff + ded9239 commit 6428bf2

File tree

10 files changed

+79
-13
lines changed

10 files changed

+79
-13
lines changed

cmd/clusterctl/client/cluster/topology.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"strings"
2424

2525
jsonpatch "github.com/evanphx/json-patch"
26-
"github.com/gobuffalo/flect"
2726
"github.com/pkg/errors"
2827
corev1 "k8s.io/api/core/v1"
2928
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -44,6 +43,7 @@ import (
4443
"sigs.k8s.io/cluster-api/feature"
4544
clustertopologycontroller "sigs.k8s.io/cluster-api/internal/controllers/topology/cluster"
4645
"sigs.k8s.io/cluster-api/internal/webhooks"
46+
"sigs.k8s.io/cluster-api/util/contract"
4747
)
4848

4949
const (
@@ -519,7 +519,7 @@ func (t *topologyClient) generateCRDs(objs []*unstructured.Unstructured) []*apie
519519
Kind: "CustomResourceDefinition",
520520
},
521521
ObjectMeta: metav1.ObjectMeta{
522-
Name: fmt.Sprintf("%s.%s", flect.Pluralize(strings.ToLower(gvk.Kind)), gvk.Group),
522+
Name: contract.CalculateCRDName(gvk.Group, gvk.Kind),
523523
Labels: map[string]string{
524524
// Here we assume that all the versions are compatible with the Cluster API contract version.
525525
clusterv1.GroupVersion.String(): gvk.Version,

docs/book/src/developer/architecture/controllers/control-plane.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ The `ImplementationControlPlane` *must* rely on the existence of
5050

5151
### CRD contracts
5252

53+
The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
54+
The same applies for the name of the corresponding ControlPlane template CRD.
55+
5356
#### Required `spec` fields for implementations using replicas
5457

5558
* `replicas` - is an integer representing the number of desired
@@ -78,21 +81,21 @@ documentation][scale].
7881

7982
#### Required `spec` fields for implementations using Machines
8083

81-
* `machineTemplate` - is a struct containing details of the control plane
84+
* `machineTemplate` - is a struct containing details of the control plane
8285
machine template.
8386

8487
* `machineTemplate.metadata` - is a struct containing info about metadata for control plane
8588
machines.
8689

87-
* `machineTemplate.metadata.labels` - is a map of string keys and values that can be used
90+
* `machineTemplate.metadata.labels` - is a map of string keys and values that can be used
8891
to organize and categorize control plane machines.
8992

9093
* `machineTemplate.metadata.annotations` - is a map of string keys and values containing
9194
arbitrary metadata to be applied to control plane machines.
9295

9396
* `machineTemplate.infrastructureRef` - is a corev1.ObjectReference to a custom resource
9497
offered by an infrastructure provider. The namespace in the ObjectReference must
95-
be in the same namespace of the control plane object.
98+
be in the same namespace of the control plane object.
9699

97100
* `machineTemplate.nodeDrainTimeout` - is a *metav1.Duration defining the total amount of time
98101
that the controller will spend on draining a control plane node.
@@ -220,7 +223,7 @@ following fields defined:
220223
version, will be used to determine when a control plane is fully upgraded
221224
(`spec.version == status.version`) and for enforcing [Kubernetes version
222225
skew policies](https://kubernetes.io/releases/version-skew-policy/) in managed topologies.
223-
226+
224227
#### Optional `status` fields
225228

226229
The `status` object **may** define several fields:

docs/book/src/developer/architecture/controllers/machine-pool.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ Cluster associations are made via labels.
4141

4242
The BootstrapConfig object **must** have a `status` object.
4343

44+
The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
45+
4446
To override the bootstrap provider, a user (or external system) can directly set the `MachinePool.Spec.Bootstrap.DataSecretName`
4547
field. This will mark the machine as ready for bootstrapping and no bootstrap data secret name will be copied from the
4648
BootstrapConfig object.
@@ -73,6 +75,8 @@ status:
7375
7476
The InfrastructureMachinePool object **must** have both `spec` and `status` objects.
7577

78+
The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
79+
7680
#### Required `spec` fields
7781

7882
The `spec` object **must** have at least one field defined:

docs/book/src/developer/providers/bootstrap.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ A bootstrap provider generates bootstrap data that is used to bootstrap a Kubern
1010
A bootstrap provider must define an API type for bootstrap resources. The type:
1111

1212
1. Must belong to an API group served by the Kubernetes apiserver
13-
2. May be implemented as a CustomResourceDefinition, or as part of an aggregated apiserver
13+
2. Must be implemented as a CustomResourceDefinition.
14+
1. The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
1415
3. Must be namespace-scoped
1516
4. Must have the standard Kubernetes "type metadata" and "object metadata"
1617
5. Should have a `spec` field containing fields relevant to the bootstrap provider
@@ -54,6 +55,9 @@ type PhippyBootstrapConfigTemplateResource struct {
5455
Spec PhippyBootstrapConfigSpec `json:"spec"`
5556
}
5657
```
58+
59+
The CRD name of the template must also have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
60+
5761
### List Resources
5862

5963
For any resource, also add list resources, e.g.

docs/book/src/developer/providers/cluster-infrastructure.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ Examples might include networking, load balancers, firewall rules, and so on.
1212
A cluster infrastructure provider must define an API type for "infrastructure cluster" resources. The type:
1313

1414
1. Must belong to an API group served by the Kubernetes apiserver
15-
2. May be implemented as a CustomResourceDefinition, or as part of an aggregated apiserver
15+
2. Must be implemented as a CustomResourceDefinition.
16+
1. The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
1617
3. Must be namespace-scoped
1718
4. Must have the standard Kubernetes "type metadata" and "object metadata"
1819
5. Must have a `spec` field with the following:
@@ -66,6 +67,8 @@ type InfraClusterTemplateResource struct {
6667
}
6768
```
6869

70+
The CRD name of the template must also have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
71+
6972
### List Resources
7073

7174
For any resource, also add list resources, e.g.

docs/book/src/developer/providers/machine-infrastructure.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ These may be physical or virtual instances, and they represent the infrastructur
1010
A machine infrastructure provider must define an API type for "infrastructure machine" resources. The type:
1111

1212
1. Must belong to an API group served by the Kubernetes apiserver
13-
2. May be implemented as a CustomResourceDefinition, or as part of an aggregated apiserver
13+
2. Must be implemented as a CustomResourceDefinition.
14+
1. The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
1415
3. Must be namespace-scoped
1516
4. Must have the standard Kubernetes "type metadata" and "object metadata"
1617
5. Must have a `spec` field with the following:
@@ -75,6 +76,9 @@ type InfraMachineTemplateResource struct {
7576
Spec InfraMachineSpec `json:"spec"`
7677
}
7778
```
79+
80+
The CRD name of the template must also have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`.
81+
7882
### List Resources
7983

8084
For any resource, also add list resources, e.g.

internal/test/builder/crds.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package builder
1818

1919
import (
20-
"fmt"
2120
"strings"
2221

2322
"github.com/gobuffalo/flect"
@@ -27,6 +26,7 @@ import (
2726
"k8s.io/utils/pointer"
2827

2928
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
29+
"sigs.k8s.io/cluster-api/util/contract"
3030
)
3131

3232
func untypedCRD(gvk schema.GroupVersionKind) *apiextensionsv1.CustomResourceDefinition {
@@ -49,7 +49,7 @@ func generateCRD(gvk schema.GroupVersionKind, properties map[string]apiextension
4949
Kind: "CustomResourceDefinition",
5050
},
5151
ObjectMeta: metav1.ObjectMeta{
52-
Name: fmt.Sprintf("%s.%s", flect.Pluralize(strings.ToLower(gvk.Kind)), gvk.Group),
52+
Name: contract.CalculateCRDName(gvk.Group, gvk.Kind),
5353
Labels: map[string]string{
5454
clusterv1.GroupVersion.String(): "v1beta1",
5555
},

util/contract/contract.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package contract
18+
19+
import (
20+
"fmt"
21+
"strings"
22+
23+
"github.com/gobuffalo/flect"
24+
)
25+
26+
// CalculateCRDName generates a CRD name based on group and kind according to
27+
// the naming conventions in the contract.
28+
func CalculateCRDName(group, kind string) string {
29+
return fmt.Sprintf("%s.%s", flect.Pluralize(strings.ToLower(kind)), group)
30+
}

util/contract/doc.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package contract contains utils related to the Cluster API contract.
18+
package contract

util/util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
"time"
2929

3030
"github.com/blang/semver"
31-
"github.com/gobuffalo/flect"
3231
"github.com/pkg/errors"
3332
corev1 "k8s.io/api/core/v1"
3433
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -48,6 +47,7 @@ import (
4847

4948
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
5049
"sigs.k8s.io/cluster-api/util/annotations"
50+
"sigs.k8s.io/cluster-api/util/contract"
5151
)
5252

5353
const (
@@ -442,7 +442,7 @@ func HasOwner(refList []metav1.OwnerReference, apiVersion string, kinds []string
442442
// This function is greatly more efficient than GetCRDWithContract and should be preferred in most cases.
443443
func GetGVKMetadata(ctx context.Context, c client.Client, gvk schema.GroupVersionKind) (*metav1.PartialObjectMetadata, error) {
444444
meta := &metav1.PartialObjectMetadata{}
445-
meta.SetName(fmt.Sprintf("%s.%s", flect.Pluralize(strings.ToLower(gvk.Kind)), gvk.Group))
445+
meta.SetName(contract.CalculateCRDName(gvk.Group, gvk.Kind))
446446
meta.SetGroupVersionKind(apiextensionsv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
447447
if err := c.Get(ctx, client.ObjectKeyFromObject(meta), meta); err != nil {
448448
return meta, errors.Wrap(err, "failed to retrieve metadata from GVK resource")

0 commit comments

Comments
 (0)