-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OTA-1010: pull GetImplicitlyEnabledCapabilities from the cvo repo
- Loading branch information
1 parent
b9df8bb
commit 9cbf3c7
Showing
3 changed files
with
333 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package capability | ||
|
||
import ( | ||
"sort" | ||
|
||
configv1 "github.com/openshift/api/config/v1" | ||
) | ||
|
||
type ClusterCapabilities struct { | ||
KnownCapabilities map[configv1.ClusterVersionCapability]struct{} | ||
EnabledCapabilities map[configv1.ClusterVersionCapability]struct{} | ||
ImplicitlyEnabledCapabilities []configv1.ClusterVersionCapability | ||
} | ||
|
||
// GetImplicitlyEnabledCapabilities filters out from a set of capabilities | ||
// the ones that | ||
// - are not in the list enabledCapabilities of clusterCapabilities | ||
// - are not the keys of clusterCapabilities.EnabledCapabilities | ||
// - are not in the list clusterCapabilities.ImplicitlyEnabledCapabilities | ||
// The returned list is the implicitly enabled capabilities. | ||
func GetImplicitlyEnabledCapabilities(enabledCapabilities []configv1.ClusterVersionCapability, | ||
capabilities []configv1.ClusterVersionCapability, | ||
clusterCapabilities ClusterCapabilities) []configv1.ClusterVersionCapability { | ||
var caps []configv1.ClusterVersionCapability | ||
for _, c := range capabilities { | ||
if contains(enabledCapabilities, c) { | ||
continue | ||
} | ||
if _, ok := clusterCapabilities.EnabledCapabilities[c]; !ok { | ||
if !contains(clusterCapabilities.ImplicitlyEnabledCapabilities, c) { | ||
caps = append(caps, c) | ||
} | ||
} | ||
} | ||
sort.Sort(capabilitiesSort(caps)) | ||
return caps | ||
} | ||
|
||
func contains(caps []configv1.ClusterVersionCapability, capability configv1.ClusterVersionCapability) bool { | ||
for _, c := range caps { | ||
if capability == c { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
type capabilitiesSort []configv1.ClusterVersionCapability | ||
|
||
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 clusterCapabilities from ClusterVersion clusterCapabilities spec. This method also | ||
// ensures that no previously enabled capability is now disabled and returns any such implicitly enabled clusterCapabilities. | ||
func SetCapabilities(config *configv1.ClusterVersion, | ||
existingEnabled, alwaysEnabled map[configv1.ClusterVersionCapability]struct{}) ClusterCapabilities { | ||
|
||
var capabilities ClusterCapabilities | ||
capabilities.KnownCapabilities = setKnownCapabilities() | ||
|
||
capabilities.EnabledCapabilities, capabilities.ImplicitlyEnabledCapabilities = setEnabledCapabilities(config.Spec.Capabilities, | ||
existingEnabled, alwaysEnabled) | ||
|
||
return capabilities | ||
} | ||
|
||
// setKnownCapabilities populates a map keyed by capability from all known clusterCapabilities as defined in ClusterVersion. | ||
func setKnownCapabilities() map[configv1.ClusterVersionCapability]struct{} { | ||
known := make(map[configv1.ClusterVersionCapability]struct{}) | ||
|
||
for _, v := range configv1.ClusterVersionCapabilitySets { | ||
for _, capability := range v { | ||
if _, ok := known[capability]; ok { | ||
continue | ||
} | ||
known[capability] = struct{}{} | ||
} | ||
} | ||
return known | ||
} | ||
|
||
const ( | ||
DefaultCapabilitySet = configv1.ClusterVersionCapabilitySetCurrent | ||
) | ||
|
||
// setEnabledCapabilities populates a map keyed by capability from all enabled clusterCapabilities as defined in ClusterVersion. | ||
// DefaultCapabilitySet is used if a baseline capability set is not defined by ClusterVersion. A check is then made to | ||
// ensure that no previously enabled capability is now disabled and if any such clusterCapabilities are found each is enabled, | ||
// saved, and returned. | ||
// The required clusterCapabilities are added to the implicitly enabled. | ||
func setEnabledCapabilities(capabilitiesSpec *configv1.ClusterVersionCapabilitiesSpec, | ||
priorEnabled, alwaysEnabled map[configv1.ClusterVersionCapability]struct{}) (map[configv1.ClusterVersionCapability]struct{}, | ||
[]configv1.ClusterVersionCapability) { | ||
|
||
capSet := DefaultCapabilitySet | ||
|
||
if capabilitiesSpec != nil && len(capabilitiesSpec.BaselineCapabilitySet) > 0 { | ||
capSet = capabilitiesSpec.BaselineCapabilitySet | ||
} | ||
enabled := GetCapabilitiesAsMap(configv1.ClusterVersionCapabilitySets[capSet]) | ||
|
||
if capabilitiesSpec != nil { | ||
for _, v := range capabilitiesSpec.AdditionalEnabledCapabilities { | ||
if _, ok := enabled[v]; ok { | ||
continue | ||
} | ||
enabled[v] = struct{}{} | ||
} | ||
} | ||
var implicitlyEnabled []configv1.ClusterVersionCapability | ||
for k := range priorEnabled { | ||
if _, ok := enabled[k]; !ok { | ||
implicitlyEnabled = append(implicitlyEnabled, k) | ||
enabled[k] = struct{}{} | ||
} | ||
} | ||
for k := range alwaysEnabled { | ||
if _, ok := enabled[k]; !ok { | ||
implicitlyEnabled = append(implicitlyEnabled, k) | ||
enabled[k] = struct{}{} | ||
} | ||
} | ||
sort.Sort(capabilitiesSort(implicitlyEnabled)) | ||
return enabled, implicitlyEnabled | ||
} | ||
|
||
// GetCapabilitiesAsMap returns the slice of clusterCapabilities as a map with default values. | ||
func GetCapabilitiesAsMap(capabilities []configv1.ClusterVersionCapability) map[configv1.ClusterVersionCapability]struct{} { | ||
caps := make(map[configv1.ClusterVersionCapability]struct{}, len(capabilities)) | ||
for _, c := range capabilities { | ||
caps[c] = struct{}{} | ||
} | ||
return caps | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
package capability | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
configv1 "github.com/openshift/api/config/v1" | ||
) | ||
|
||
func TestGetImplicitlyEnabledCapabilities(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
enabledCaps []configv1.ClusterVersionCapability | ||
capabilities []configv1.ClusterVersionCapability | ||
clusterCapabilities ClusterCapabilities | ||
expected []configv1.ClusterVersionCapability | ||
}{ | ||
{name: "implicitly enable capability", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1", "cap3"}, | ||
capabilities: []configv1.ClusterVersionCapability{"cap2"}, | ||
clusterCapabilities: ClusterCapabilities{ | ||
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}}, | ||
}, | ||
expected: []configv1.ClusterVersionCapability{"cap2"}, | ||
}, | ||
{name: "no prior caps, implicitly enabled capability", | ||
capabilities: []configv1.ClusterVersionCapability{"cap2"}, | ||
expected: []configv1.ClusterVersionCapability{"cap2"}, | ||
}, | ||
{name: "multiple implicitly enable capability", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1", "cap2", "cap3"}, | ||
capabilities: []configv1.ClusterVersionCapability{"cap4", "cap5", "cap6"}, | ||
expected: []configv1.ClusterVersionCapability{"cap4", "cap5", "cap6"}, | ||
}, | ||
{name: "no implicitly enable capability", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1", "cap3"}, | ||
capabilities: []configv1.ClusterVersionCapability{"cap1"}, | ||
clusterCapabilities: ClusterCapabilities{ | ||
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}}, | ||
}, | ||
}, | ||
{name: "prior cap, no updated caps, no implicitly enabled capability", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1"}, | ||
}, | ||
{name: "no implicitly enable capability, already enabled", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1", "cap2"}, | ||
capabilities: []configv1.ClusterVersionCapability{"cap2"}, | ||
clusterCapabilities: ClusterCapabilities{ | ||
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, | ||
}, | ||
}, | ||
{name: "no implicitly enable capability, new cap but already enabled", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1"}, | ||
capabilities: []configv1.ClusterVersionCapability{"cap2"}, | ||
clusterCapabilities: ClusterCapabilities{ | ||
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap2": {}}, | ||
}, | ||
}, | ||
{name: "no implicitly enable capability, already implcitly enabled", | ||
enabledCaps: []configv1.ClusterVersionCapability{"cap1"}, | ||
capabilities: []configv1.ClusterVersionCapability{"cap2"}, | ||
clusterCapabilities: ClusterCapabilities{ | ||
EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap2": {}}, | ||
ImplicitlyEnabledCapabilities: []configv1.ClusterVersionCapability{"cap2"}, | ||
}, | ||
}, | ||
} | ||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
caps := GetImplicitlyEnabledCapabilities(test.enabledCaps, test.capabilities, test.clusterCapabilities) | ||
if diff := cmp.Diff(test.expected, caps); diff != "" { | ||
t.Errorf("%s: Returned capacities differ from expected:\n%s", test.name, diff) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestSetCapabilities(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
config *configv1.ClusterVersion | ||
expected ClusterCapabilities | ||
}{ | ||
{name: "capabilities nil", | ||
config: &configv1.ClusterVersion{}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap(configv1.ClusterVersionCapabilitySets[DefaultCapabilitySet]), | ||
}, | ||
}, | ||
{name: "capabilities set not set", | ||
config: &configv1.ClusterVersion{ | ||
Spec: configv1.ClusterVersionSpec{ | ||
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{}, | ||
}, | ||
}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap(configv1.ClusterVersionCapabilitySets[DefaultCapabilitySet]), | ||
}, | ||
}, | ||
{name: "set capabilities None", | ||
config: &configv1.ClusterVersion{ | ||
Spec: configv1.ClusterVersionSpec{ | ||
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{ | ||
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySetNone, | ||
}, | ||
}, | ||
}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap([]configv1.ClusterVersionCapability{}), | ||
}, | ||
}, | ||
{name: "set capabilities 4_11", | ||
config: &configv1.ClusterVersion{ | ||
Spec: configv1.ClusterVersionSpec{ | ||
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{ | ||
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySet4_11, | ||
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{}, | ||
}, | ||
}, | ||
}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap([]configv1.ClusterVersionCapability{ | ||
configv1.ClusterVersionCapabilityBaremetal, | ||
configv1.ClusterVersionCapabilityMarketplace, | ||
configv1.ClusterVersionCapabilityOpenShiftSamples, | ||
configv1.ClusterVersionCapabilityMachineAPI, | ||
}), | ||
}, | ||
}, | ||
{name: "set capabilities vCurrent", | ||
config: &configv1.ClusterVersion{ | ||
Spec: configv1.ClusterVersionSpec{ | ||
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{ | ||
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySetCurrent, | ||
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{}, | ||
}, | ||
}, | ||
}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap(configv1.ClusterVersionCapabilitySets[configv1.ClusterVersionCapabilitySetCurrent]), | ||
}, | ||
}, | ||
{name: "set capabilities None with additional", | ||
config: &configv1.ClusterVersion{ | ||
Spec: configv1.ClusterVersionSpec{ | ||
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{ | ||
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySetNone, | ||
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{"cap1", "cap2", "cap3"}, | ||
}, | ||
}, | ||
}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap([]configv1.ClusterVersionCapability{"cap1", "cap2", "cap3"}), | ||
}, | ||
}, | ||
{name: "set capabilities 4_11 with additional", | ||
config: &configv1.ClusterVersion{ | ||
Spec: configv1.ClusterVersionSpec{ | ||
Capabilities: &configv1.ClusterVersionCapabilitiesSpec{ | ||
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySet4_11, | ||
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{"cap1", "cap2", "cap3"}, | ||
}, | ||
}, | ||
}, | ||
expected: ClusterCapabilities{ | ||
KnownCapabilities: GetCapabilitiesAsMap(configv1.KnownClusterVersionCapabilities), | ||
EnabledCapabilities: GetCapabilitiesAsMap([]configv1.ClusterVersionCapability{ | ||
configv1.ClusterVersionCapabilityBaremetal, | ||
configv1.ClusterVersionCapabilityMarketplace, | ||
configv1.ClusterVersionCapabilityOpenShiftSamples, | ||
configv1.ClusterVersionCapabilityMachineAPI, | ||
"cap1", | ||
"cap2", | ||
"cap3"}), | ||
}, | ||
}, | ||
} | ||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
caps := SetCapabilities(test.config, nil, nil) | ||
if diff := cmp.Diff(test.expected, caps); diff != "" { | ||
t.Errorf("%s: Returned capacities differ from expected:\n%s", test.name, diff) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters