Skip to content

Commit

Permalink
add the OPENSHIFT_REQUIRED_FEATURESET env var and openshift:enable:fe…
Browse files Browse the repository at this point in the history
…atureSet marker
  • Loading branch information
deads2k committed Sep 6, 2022
1 parent e0dd977 commit 0ab0804
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 0 deletions.
31 changes: 31 additions & 0 deletions pkg/crd/markers/patch_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package markers

import (
"os"
"strings"

"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/controller-tools/pkg/markers"
)

var RequiredFeatureSets = sets.NewString("")

func init() {
featureSet := os.Getenv("OPENSHIFT_REQUIRED_FEATURESET")
if len(featureSet) == 0 {
return
}

for _, curr := range strings.Split(featureSet, ",") {
RequiredFeatureSets.Insert(curr)
}
}

const OpenShiftFeatureSetMarkerName = "openshift:enable:FeatureSets"

func init() {
FieldOnlyMarkers = append(FieldOnlyMarkers,
must(markers.MakeDefinition(OpenShiftFeatureSetMarkerName, markers.DescribesField, []string{})).
WithHelp(markers.SimpleHelp("OpenShift", "specifies the FeatureSet that is required to generate this field.")),
)
}
29 changes: 29 additions & 0 deletions pkg/crd/patch_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package crd

import (
"fmt"

crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"
"sigs.k8s.io/controller-tools/pkg/markers"
)

// mayHandleField returns true if the field should be considered by this invocation of the generator.
// Right now, the only sip is based on the featureset marker.
func mayHandleField(field markers.FieldInfo) bool {
uncastFeatureSet := field.Markers.Get(crdmarkers.OpenShiftFeatureSetMarkerName)
if uncastFeatureSet == nil {
return true
}

featureSetsForField, ok := uncastFeatureSet.([]string)
if !ok {
panic(fmt.Sprintf("actually got %t", uncastFeatureSet))
}
// if any of the field's declared featureSets match any of the manifest's declared featuresets, include the field.
for _, currFeatureSetForField := range featureSetsForField {
if crdmarkers.RequiredFeatureSets.Has(currFeatureSetForField) {
return true
}
}
return false
}
5 changes: 5 additions & 0 deletions pkg/crd/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,11 @@ func structToSchema(ctx *schemaContext, structType *ast.StructType) *apiext.JSON
}

for _, field := range ctx.info.Fields {
// Skip the field if it has a marker for a FeatureSet that is not the FeatureSet we're generating for.
if !mayHandleField(field) {
continue
}

jsonTag, hasTag := field.Tag.Lookup("json")
if !hasTag {
// if the field doesn't have a JSON tag, it doesn't belong in output (and shouldn't exist in a serialized type)
Expand Down
5 changes: 5 additions & 0 deletions pkg/schemapatcher/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ func crdsFromDirectory(ctx *genall.GenerationContext, dir string) (map[schema.Gr
continue
}

// this is a patch that allows us to skip manifests to support things like TechPreviewNoUpgrade manifests.
if !mayHandleFile(fileInfo.Name(), rawContent) {
continue
}

// collect the group-kind and versions from the actual structured form
var actualCRD crdIsh
if err := kyaml.Unmarshal(rawContent, &actualCRD); err != nil {
Expand Down
28 changes: 28 additions & 0 deletions pkg/schemapatcher/patch_gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package schemapatcher

import (
"strings"

crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/sets"
kyaml "sigs.k8s.io/yaml"
)

// mayHandleFile returns true if this manifest should progress past the file collection stage.
// Currently, the only check is the feature-set annotation.
func mayHandleFile(filename string, rawContent []byte) bool {
manifest := &unstructured.Unstructured{}
if err := kyaml.Unmarshal(rawContent, &manifest); err != nil {
return true
}

manifestFeatureSets := sets.String{}
if manifestFeatureSetString := manifest.GetAnnotations()["release.openshift.io/feature-set"]; len(manifestFeatureSets) > 0 {
for _, curr := range strings.Split(manifestFeatureSetString, ",") {
manifestFeatureSets.Insert(curr)
}
}
return manifestFeatureSets.Equal(crdmarkers.RequiredFeatureSets)
}

0 comments on commit 0ab0804

Please sign in to comment.