Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/imdario/mergo v0.3.8 // indirect
github.com/openshift/api v0.0.0-20220325173635-8107b7a38e53
github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3
github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a
github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/client_model v0.2.0
Expand Down
11 changes: 4 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/RangelReale/osincli v0.0.0-20160924135400-fababb0555f2/go.mod h1:XyjUkMA8GN+tOOPXvnbi3XuRxWFvTJntqvTFnjmhzbk=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
Expand Down Expand Up @@ -483,19 +484,15 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/openshift/api v0.0.0-20211209135129-c58d9f695577/go.mod h1:DoslCwtqUpr3d/gsbq4ZlkaMEdYqKxuypsDjorcHhME=
github.com/openshift/api v0.0.0-20220208222216-7e3ffb09accd h1:EaCz2jR4vZvtTBGXBLD4V3Lwg96DDAK+wsZvS8+1+EE=
github.com/openshift/api v0.0.0-20220208222216-7e3ffb09accd/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4=
github.com/openshift/api v0.0.0-20220317153038-a2ca88c44400 h1:DMzrYI2PxPHFGQEWLSiHnAcF8l3wYDlGk1kUlEPhSC8=
github.com/openshift/api v0.0.0-20220317153038-a2ca88c44400/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4=
github.com/openshift/api v0.0.0-20220315184754-d7c10d0b647e/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4=
github.com/openshift/api v0.0.0-20220325173635-8107b7a38e53 h1:WpOfczPbuY5llRH94DJRsGTsgm7d8iAA2b7m0+YXAqI=
github.com/openshift/api v0.0.0-20220325173635-8107b7a38e53/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4=
github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/build-machinery-go v0.0.0-20210806203541-4ea9b6da3a37/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3 h1:SG1aqwleU6bGD0X4mhkTNupjVnByMYYuW4XbnCPavQU=
github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3/go.mod h1:cwhyki5lqBmrT0m8Im+9I7PGFaraOzcYPtEz93RcsGY=
github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a h1:MoAaYFrzB5QlYzO7phyjx/JBxghUrLitwb69RaulRAs=
github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a/go.mod h1:M/Gi/GUUrMdSS07nrYtTiK43J6/VUAyk/+IfN4ZqUY4=
github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d h1:uEOiLtoPeRfnsust0rTediph3fYqUxBVgJ5zWVMnxwY=
github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d/go.mod h1:5a5oGzRGu6XjtAmChVlwstxp0MWDGh7fIXlN34mFiLA=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
Expand Down
3 changes: 1 addition & 2 deletions hack/cluster-version-util/task_graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/spf13/cobra"

"github.com/openshift/cluster-version-operator/lib/capability"
"github.com/openshift/cluster-version-operator/pkg/payload"
)

Expand All @@ -31,7 +30,7 @@ func newTaskGraphCmd() *cobra.Command {

func runTaskGraphCmd(cmd *cobra.Command, args []string) error {
manifestDir := args[0]
release, err := payload.LoadUpdate(manifestDir, "", "", false, payload.DefaultClusterProfile, capability.ClusterCapabilities{})
release, err := payload.LoadUpdate(manifestDir, "", "", false, payload.DefaultClusterProfile, nil)
if err != nil {
return err
}
Expand Down
95 changes: 48 additions & 47 deletions lib/capability/capability.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package capability

import (
"fmt"
"reflect"
"sort"
"strings"

configv1 "github.com/openshift/api/config/v1"
)
Expand All @@ -15,8 +14,13 @@ const (
)

type ClusterCapabilities struct {
KnownCapabilities map[configv1.ClusterVersionCapability]struct{}
EnabledCapabilities map[configv1.ClusterVersionCapability]struct{}
KnownCapabilities map[configv1.ClusterVersionCapability]struct{}
EnabledCapabilities map[configv1.ClusterVersionCapability]struct{}
ImplicitlyEnabledCapabilities []configv1.ClusterVersionCapability
}

func (c *ClusterCapabilities) Equal(capabilities *ClusterCapabilities) bool {
return reflect.DeepEqual(c.EnabledCapabilities, capabilities.EnabledCapabilities)
}

type capabilitiesSort []configv1.ClusterVersionCapability
Expand All @@ -25,14 +29,30 @@ func (caps capabilitiesSort) Len() int { return len(caps) }
func (caps capabilitiesSort) Swap(i, j int) { caps[i], caps[j] = caps[j], caps[i] }
func (caps capabilitiesSort) Less(i, j int) bool { return string(caps[i]) < string(caps[j]) }

// SetCapabilities populates and returns cluster capabilities from ClusterVersion capabilities spec.
func SetCapabilities(config *configv1.ClusterVersion) ClusterCapabilities {
// SetCapabilities populates and returns cluster capabilities from ClusterVersion capabilities spec. This method also
// ensures that no previousily enabled capability is now disabled and returns any such implicitly enabled capabilities.
func SetCapabilities(config *configv1.ClusterVersion,
existingEnabled map[configv1.ClusterVersionCapability]struct{}) ClusterCapabilities {

var capabilities ClusterCapabilities
capabilities.KnownCapabilities = setKnownCapabilities(config)
capabilities.EnabledCapabilities = setEnabledCapabilities(config)
capabilities.KnownCapabilities = setKnownCapabilities()

capabilities.EnabledCapabilities, capabilities.ImplicitlyEnabledCapabilities = setEnabledCapabilities(config.Spec.Capabilities,
existingEnabled)

return capabilities
}

// GetKnownCapabilities returns all known capabilities as defined in ClusterVersion.
func GetKnownCapabilities() []configv1.ClusterVersionCapability {
var known []configv1.ClusterVersionCapability

for _, v := range configv1.ClusterVersionCapabilitySets {
known = append(known, v...)
}
return known
}

// GetCapabilitiesStatus populates and returns ClusterVersion capabilities status from given capabilities.
func GetCapabilitiesStatus(capabilities ClusterCapabilities) configv1.ClusterVersionCapabilitiesStatus {
var status configv1.ClusterVersionCapabilitiesStatus
Expand All @@ -47,39 +67,8 @@ func GetCapabilitiesStatus(capabilities ClusterCapabilities) configv1.ClusterVer
return status
}

// CheckResourceEnablement, given resource annotations and defined cluster capabilities, checks if the capability
// annotation exists. If so, each capability name is validated against the known set of capabilities. Each valid
// capability is then checked if it is disabled. If any invalid capabilities are found an error is returned listing
// all invalid capabilities. Otherwise, if any disabled capabilities are found an error is returned listing all
// disabled capabilities.
func CheckResourceEnablement(annotations map[string]string, capabilities ClusterCapabilities) error {
val, ok := annotations[CapabilityAnnotation]
if !ok {
return nil
}
caps := strings.Split(val, "+")
numCaps := len(caps)
unknownCaps := make([]string, 0, numCaps)
disabledCaps := make([]string, 0, numCaps)

for _, c := range caps {
if _, ok = capabilities.KnownCapabilities[configv1.ClusterVersionCapability(c)]; !ok {
unknownCaps = append(unknownCaps, c)
} else if _, ok = capabilities.EnabledCapabilities[configv1.ClusterVersionCapability(c)]; !ok {
disabledCaps = append(disabledCaps, c)
}
}
if len(unknownCaps) > 0 {
return fmt.Errorf("unrecognized capability names: %s", strings.Join(unknownCaps, ", "))
}
if len(disabledCaps) > 0 {
return fmt.Errorf("disabled capabilities: %s", strings.Join(disabledCaps, ", "))
}
return nil
}

// setKnownCapabilities populates a map keyed by capability from all known capabilities as defined in ClusterVersion.
func setKnownCapabilities(config *configv1.ClusterVersion) map[configv1.ClusterVersionCapability]struct{} {
func setKnownCapabilities() map[configv1.ClusterVersionCapability]struct{} {
known := make(map[configv1.ClusterVersionCapability]struct{})

for _, v := range configv1.ClusterVersionCapabilitySets {
Expand All @@ -94,27 +83,39 @@ func setKnownCapabilities(config *configv1.ClusterVersion) map[configv1.ClusterV
}

// setEnabledCapabilities populates a map keyed by capability from all enabled capabilities as defined in ClusterVersion.
// DefaultCapabilitySet is used if a baseline capability set is not defined by ClusterVersion.
func setEnabledCapabilities(config *configv1.ClusterVersion) map[configv1.ClusterVersionCapability]struct{} {
// DefaultCapabilitySet is used if a baseline capability set is not defined by ClusterVersion. A check is then made to
// ensure that no previousily enabled capability is now disabled and if any such capabilities are found each is enabled,
// saved, and returned.
func setEnabledCapabilities(capabilitiesSpec *configv1.ClusterVersionCapabilitiesSpec,
priorEnabled map[configv1.ClusterVersionCapability]struct{}) (map[configv1.ClusterVersionCapability]struct{},
[]configv1.ClusterVersionCapability) {

enabled := make(map[configv1.ClusterVersionCapability]struct{})

capSet := DefaultCapabilitySet

if config.Spec.Capabilities != nil && len(config.Spec.Capabilities.BaselineCapabilitySet) > 0 {
capSet = config.Spec.Capabilities.BaselineCapabilitySet
if capabilitiesSpec != nil && len(capabilitiesSpec.BaselineCapabilitySet) > 0 {
capSet = capabilitiesSpec.BaselineCapabilitySet
}

for _, v := range configv1.ClusterVersionCapabilitySets[capSet] {
enabled[v] = struct{}{}
}

if config.Spec.Capabilities != nil {
for _, v := range config.Spec.Capabilities.AdditionalEnabledCapabilities {
if capabilitiesSpec != nil {
for _, v := range capabilitiesSpec.AdditionalEnabledCapabilities {
if _, ok := enabled[v]; ok {
continue
}
enabled[v] = struct{}{}
}
}
return enabled
var implicitlyEnabled []configv1.ClusterVersionCapability
for k := range priorEnabled {
if _, ok := enabled[k]; !ok {
implicitlyEnabled = append(implicitlyEnabled, k)
enabled[k] = struct{}{}
}
}
return enabled, implicitlyEnabled
}
139 changes: 41 additions & 98 deletions lib/capability/capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func TestSetCapabilities(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
caps := SetCapabilities(test.config)
caps := SetCapabilities(test.config, nil)
if test.config.Spec.Capabilities == nil || (test.config.Spec.Capabilities != nil &&
len(test.config.Spec.Capabilities.BaselineCapabilitySet) == 0) {

Expand All @@ -149,6 +149,46 @@ func TestSetCapabilities(t *testing.T) {
}
}

func TestSetCapabilitiesWithImplicitlyEnabled(t *testing.T) {
tests := []struct {
name string
config *configv1.ClusterVersion
wantImplicit []string
priorEnabled map[configv1.ClusterVersionCapability]struct{}
}{
{name: "set capabilities 4_11 with additional",
config: &configv1.ClusterVersion{
Spec: configv1.ClusterVersionSpec{
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySet4_11,
},
},
},
priorEnabled: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}, "cap3": {}},
wantImplicit: []string{"cap1", "cap2", "cap3"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
caps := SetCapabilities(test.config, test.priorEnabled)
if len(caps.ImplicitlyEnabledCapabilities) != len(test.wantImplicit) {
t.Errorf("Incorrect number of implicitly enabled keys, wanted: %q. ImplicitlyEnabledCapabilities returned: %v", test.wantImplicit, caps.ImplicitlyEnabledCapabilities)
}
for _, wanted := range test.wantImplicit {
found := false
for _, have := range caps.ImplicitlyEnabledCapabilities {
if wanted == string(have) {
found = true
}
}
if !found {
t.Errorf("Missing ImplicitlyEnabledCapabilities key %q. ImplicitlyEnabledCapabilities returned : %v", wanted, caps.ImplicitlyEnabledCapabilities)
}
}
})
}
}

func TestGetCapabilitiesStatus(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -215,103 +255,6 @@ func TestGetCapabilitiesStatus(t *testing.T) {
}
}

func TestCheckResourceEnablement(t *testing.T) {
tests := []struct {
name string
annotations map[string]string
caps ClusterCapabilities
wantError string
}{
{name: "empty annotations"},
{name: "no capabilitity annotation",
annotations: map[string]string{"foo": "bar"},
},
{name: "known capabilitity annotation",
annotations: map[string]string{CapabilityAnnotation: string(configv1.ClusterVersionCapabilityOpenShiftSamples), "foo": "bar"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
},
},
{name: "multiple enabled capabilitities annotation",
annotations: map[string]string{CapabilityAnnotation: "cap1+cap2"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}},
},
},
{name: "multiple capabilitities annotation with spaces",
annotations: map[string]string{CapabilityAnnotation: " + cap1 +cap2+ "},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}},
},
wantError: "unrecognized capability names: , cap1 , ",
},
{name: "unrecognized capabilitity annotation",
annotations: map[string]string{CapabilityAnnotation: "cap1"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
},
wantError: "unrecognized capability names: cap1",
},
{name: "unrecognized capabilitities, spaces",
annotations: map[string]string{CapabilityAnnotation: "cap1 + cap2"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}},
},
wantError: "unrecognized capability names: cap1 , cap2",
},
{name: "invalid capabilitity annotation divider",
annotations: map[string]string{CapabilityAnnotation: "cap1,cap2,cap3,cap4"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
},
wantError: "unrecognized capability names: cap1,cap2,cap3,cap4",
},
{name: "multiple unrecognized capabilitities annotation",
annotations: map[string]string{CapabilityAnnotation: "cap1+cap2+cap3+cap4"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}},
},
wantError: "unrecognized capability names: cap1, cap2, cap3, cap4",
},
{name: "disabled capabilitity annotation",
annotations: map[string]string{CapabilityAnnotation: "cap1"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{},
},
wantError: "disabled capabilities: cap1",
},
{name: "multiple disabled capabilitities annotation",
annotations: map[string]string{CapabilityAnnotation: "cap1+cap2+cap3+cap4+cap5+cap6"},
caps: ClusterCapabilities{
KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {},
"cap3": {}, "cap4": {}, "cap5": {}, "cap6": {}},
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}, "cap3": {}},
},
wantError: "disabled capabilities: cap4, cap5, cap6",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := CheckResourceEnablement(test.annotations, test.caps)
if len(test.wantError) == 0 {
if err != nil {
t.Errorf("Wanted no error, got error %q", err.Error())
}
} else if test.wantError != err.Error() {
t.Errorf("Wanted error %q, got error %q", test.wantError, err.Error())
}
})
}
}

func getDefaultCapabilities() []string {
var caps []string

Expand Down
7 changes: 2 additions & 5 deletions pkg/cvo/cvo.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,12 @@ func New(
// payload appears to be in error rather than continuing.
func (optr *Operator) InitializeFromPayload(ctx context.Context, restConfig *rest.Config, burstRestConfig *rest.Config) error {

var config *configv1.ClusterVersion

// wait until cluster version object exists
if err := wait.PollImmediateInfiniteWithContext(ctx, 3*time.Second, func(ctx context.Context) (bool, error) {
var err error

// ensure the cluster version exists
config, _, err = optr.getClusterVersion(ctx)
_, _, err = optr.getClusterVersion(ctx)
if err != nil {
if apierrors.IsNotFound(err) {
klog.V(2).Infof("No cluster version object, waiting for one")
Expand All @@ -241,10 +239,9 @@ func (optr *Operator) InitializeFromPayload(ctx context.Context, restConfig *res
}); err != nil {
return fmt.Errorf("Error when attempting to get cluster version object: %w", err)
}
capabilities := capability.SetCapabilities(config)

update, err := payload.LoadUpdate(optr.defaultPayloadDir(), optr.release.Image, optr.exclude, optr.includeTechPreview,
optr.clusterProfile, capabilities)
optr.clusterProfile, capability.GetKnownCapabilities())

if err != nil {
return fmt.Errorf("the local release contents are invalid - no current version can be determined from disk: %v", err)
Expand Down
Loading