diff --git a/pkg/operator/render/options/generic.go b/pkg/operator/render/options/generic.go index c0efaea8c6..d9ae99fe85 100644 --- a/pkg/operator/render/options/generic.go +++ b/pkg/operator/render/options/generic.go @@ -132,6 +132,30 @@ func (o *GenericOptions) FeatureGates() (featuregates.FeatureGateAccess, error) return nil, fmt.Errorf("cannot return FeatureGate without rendered manifests") } + manifests, err := o.FeatureGateManifests() + if err != nil { + return nil, fmt.Errorf("error reading input manifests: %w", err) + } + // they're all the same, so just get the first + featureGate, err := manifests[0].GetDecodedObj() + if err != nil { + return nil, fmt.Errorf("error decoding FeatureGates: %w", err) + } + + ret, err := featuregates.NewHardcodedFeatureGateAccessFromFeatureGate(featureGate.(*configv1.FeatureGate), o.PayloadVersion) + if err != nil { + return nil, fmt.Errorf("error creating feature accessor: %w", err) + } + + return ret, nil +} + +// FeatureGateManifests is exposed for usage in getting FeatureGateAccess and for convenient by cluster-config-operator +func (o *GenericOptions) FeatureGateManifests() (RenderedManifests, error) { + if len(o.RenderedManifestInputFilenames) == 0 { + return nil, nil + } + inputManifest, err := o.ReadInputManifests() if err != nil { return nil, fmt.Errorf("error reading input manifests: %w", err) @@ -140,10 +164,15 @@ func (o *GenericOptions) FeatureGates() (featuregates.FeatureGateAccess, error) if len(featureGates) == 0 { return nil, fmt.Errorf("no FeatureGates found in manfest dir: %v", o.RenderedManifestInputFilenames) } + + ret := RenderedManifests{} + var prev *RenderedManifest var featureGate *configv1.FeatureGate for i := range featureGates { curr := featureGates[i] + ret = append(ret, curr) + decodedObj, err := curr.GetDecodedObj() if err != nil { return nil, fmt.Errorf("decoding failure for %q: %w", curr.OriginalFilename, err) @@ -163,12 +192,25 @@ func (o *GenericOptions) FeatureGates() (featuregates.FeatureGateAccess, error) } } - ret, err := featuregates.NewHardcodedFeatureGateAccessFromFeatureGate(featureGate, o.PayloadVersion) + return ret, nil +} + +func (o *GenericOptions) FeatureSetName() (configv1.FeatureSet, error) { + if len(o.RenderedManifestInputFilenames) == 0 { + return configv1.FeatureSet(o.FeatureSet), nil + } + + manifests, err := o.FeatureGateManifests() if err != nil { - return nil, fmt.Errorf("error creating feature accessor: %w", err) + return "MISSING", fmt.Errorf("error reading input manifests: %w", err) + } + // they're all the same, so just get the first + featureGate, err := manifests[0].GetDecodedObj() + if err != nil { + return "MISSING", fmt.Errorf("error decoding FeatureGates: %w", err) } - return ret, nil + return featureGate.(*configv1.FeatureGate).Spec.FeatureSet, nil } // ApplyTo applies the options to the given config struct using the provided text/template data. diff --git a/pkg/operator/render/render.go b/pkg/operator/render/render.go index 9c772a56c2..adffee5c38 100644 --- a/pkg/operator/render/render.go +++ b/pkg/operator/render/render.go @@ -11,8 +11,13 @@ import ( // WriteFiles writes the manifests and the bootstrap config file. func WriteFiles(opt *options.GenericOptions, fileConfig *options.FileConfig, templateData interface{}, additionalPredicates ...assets.FileInfoPredicate) error { + featureSet, err := opt.FeatureSetName() + if err != nil { + return err + } + defaultPredicates := []assets.FileInfoPredicate{assets.OnlyYaml} - manifestPredicates := []assets.FileContentsPredicate{assets.InstallerFeatureSet(opt.FeatureSet)} + manifestPredicates := []assets.FileContentsPredicate{assets.InstallerFeatureSet(string(featureSet))} // write assets for _, manifestDir := range []string{"bootstrap-manifests", "manifests"} {