Skip to content

Commit

Permalink
Support api-approved annotation for CRD with k8s group
Browse files Browse the repository at this point in the history
  • Loading branch information
FillZpp committed Aug 22, 2022
1 parent 8a80a3b commit fde1d19
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 9 deletions.
40 changes: 40 additions & 0 deletions pkg/crd/markers/crd.go
Expand Up @@ -18,6 +18,7 @@ package markers

import (
"fmt"
"strings"

apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

Expand Down Expand Up @@ -51,6 +52,9 @@ var CRDMarkers = []*definitionWithHelp{

must(markers.MakeDefinition("kubebuilder:deprecatedversion", markers.DescribesType, DeprecatedVersion{})).
WithHelp(DeprecatedVersion{}.Help()),

must(markers.MakeDefinition("kubebuilder:additionalmetadata", markers.DescribesType, AdditionalMetadata{})).
WithHelp(AdditionalMetadata{}.Help()),
}

// TODO: categories and singular used to be annotations types
Expand Down Expand Up @@ -345,3 +349,39 @@ func (s DeprecatedVersion) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec,
}
return nil
}

// +controllertools:marker:generateHelp:category=CRD

// AdditionalMetadata configures the additional annotations or labels for this CRD.
// For example adding annotation "api-approved.kubernetes.io" for a CRD with Kubernetes groups,
// or annotation "cert-manager.io/inject-ca-from-secret" for a CRD that needs CA injection.
type AdditionalMetadata struct {
// Annotations will be added into the annotations of this CRD.
Annotations []string `marker:",optional"`
// Labels will be added into the labels of this CRD.
Labels []string `marker:",optional"`
}

func (s AdditionalMetadata) ApplyToCRD(crd *apiext.CustomResourceDefinition, version string) error {
if len(s.Annotations) > 0 {
if crd.Annotations == nil {
crd.Annotations = map[string]string{}
}
for _, str := range s.Annotations {
kv := strings.SplitN(str, "=", 2)
crd.Annotations[kv[0]] = kv[1]
}
}

if len(s.Labels) > 0 {
if crd.Labels == nil {
crd.Labels = map[string]string{}
}
for _, str := range s.Labels {
kv := strings.SplitN(str, "=", 2)
crd.Labels[kv[0]] = kv[1]
}
}

return nil
}
20 changes: 20 additions & 0 deletions pkg/crd/markers/zz_generated.markerhelp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions pkg/crd/parser_integration_test.go
Expand Up @@ -122,8 +122,11 @@ var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func
By(fmt.Sprintf("parsing the desired %s YAML", kind))
var crd apiext.CustomResourceDefinition
ExpectWithOffset(1, yaml.Unmarshal(expectedFile, &crd)).To(Succeed())
// clear the annotations -- we don't care about the attribution annotation
crd.Annotations = nil
// clear the version annotation -- we don't care about the attribution annotation
delete(crd.Annotations, "controller-gen.kubebuilder.io/version")
if len(crd.Annotations) == 0 {
crd.Annotations = nil
}

By(fmt.Sprintf("comparing the two %s CRDs", kind))
ExpectWithOffset(1, parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd))
Expand Down
24 changes: 17 additions & 7 deletions pkg/crd/spec.go
Expand Up @@ -30,13 +30,21 @@ import (
)

// SpecMarker is a marker that knows how to apply itself to a particular
// version in a CRD.
// version in a CRD Spec.
type SpecMarker interface {
// ApplyToCRD applies this marker to the given CRD, in the given version
// within that CRD. It's called after everything else in the CRD is populated.
ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error
}

// Marker is a marker that knows how to apply itself to a particular
// version in a CRD.
type Marker interface {
// ApplyToCRD applies this marker to the given CRD, in the given version
// within that CRD. It's called after everything else in the CRD is populated.
ApplyToCRD(crd *apiext.CustomResourceDefinition, version string) error
}

// NeedCRDFor requests the full CRD for the given group-kind. It requires
// that the packages containing the Go structs for that CRD have already
// been loaded with NeedPackage.
Expand Down Expand Up @@ -109,12 +117,14 @@ func (p *Parser) NeedCRDFor(groupKind schema.GroupKind, maxDescLen *int) {

for _, markerVals := range typeInfo.Markers {
for _, val := range markerVals {
crdMarker, isCrdMarker := val.(SpecMarker)
if !isCrdMarker {
continue
}
if err := crdMarker.ApplyToCRD(&crd.Spec, ver); err != nil {
pkg.AddError(loader.ErrFromNode(err /* an okay guess */, typeInfo.RawSpec))
if specMarker, isSpecMarker := val.(SpecMarker); isSpecMarker {
if err := specMarker.ApplyToCRD(&crd.Spec, ver); err != nil {
pkg.AddError(loader.ErrFromNode(err /* an okay guess */, typeInfo.RawSpec))
}
} else if crdMarker, isCRDMarker := val.(Marker); isCRDMarker {
if err := crdMarker.ApplyToCRD(&crd, ver); err != nil {
pkg.AddError(loader.ErrFromNode(err /* an okay guess */, typeInfo.RawSpec))
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/crd/testdata/cronjob_types.go
Expand Up @@ -499,6 +499,7 @@ type CronJobStatus struct {
// +kubebuilder:subresource:status
// +kubebuilder:resource:singular=mycronjob
// +kubebuilder:storageversion
// +kubebuilder:additionalmetadata:annotations="api-approved.kubernetes.io=https://github.com/kubernetes-sigs/controller-tools";"cert-manager.io/inject-ca-from-secret=cert-manager/cert-manager-webhook-ca"

// CronJob is the Schema for the cronjobs API
type CronJob struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
Expand Up @@ -4,6 +4,8 @@ kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/controller-tools
cert-manager.io/inject-ca-from-secret: cert-manager/cert-manager-webhook-ca
creationTimestamp: null
name: cronjobs.testdata.kubebuilder.io
spec:
Expand Down

0 comments on commit fde1d19

Please sign in to comment.