Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

operator: Multiple same operators installed test #2542

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
28 changes: 22 additions & 6 deletions CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Depending on the workload type, not all tests are required to pass to satisfy be

## Test cases summary

### Total test cases: 114
### Total test cases: 116

### Total suites: 10

Expand All @@ -19,7 +19,7 @@ Depending on the workload type, not all tests are required to pass to satisfy be
|manageability|2|
|networking|12|
|observability|5|
|operator|9|
|operator|10|
|performance|6|
|platform-alteration|13|
|preflight|17|
Expand All @@ -36,11 +36,11 @@ Depending on the workload type, not all tests are required to pass to satisfy be
|---|---|
|8|1|

### Non-Telco specific tests only: 67
### Non-Telco specific tests only: 68

|Mandatory|Optional|
|---|---|
|42|25|
|43|25|

### Telco specific tests only: 27

Expand Down Expand Up @@ -1266,15 +1266,31 @@ Tags|common,operator
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-multiple-same-operators

Property|Description
---|---
Unique ID|operator-multiple-same-operators
Description|Tests whether multiple instances of the same Operator CSV are installed.
Suggested Remediation|Ensure that only one Operator of the same type is installed in the cluster.
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-operator-requirements
Exception Process|No exceptions
Tags|common,operator
|**Scenario**|**Optional/Mandatory**|
|Extended|Mandatory|
|Far-Edge|Mandatory|
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-olm-skip-range

Property|Description
---|---
Unique ID|operator-olm-skip-range
Description|Test that checks the operator has a valid olm skip range.
Suggested Remediation|Ensure that the Operator has a valid OLM skip range.
Suggested Remediation|Ensure that the Operator has a valid OLM skip range. If the operator does not have another version to "skip", then ignore the result of this test.
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-operator-requirements
Exception Process|No exceptions
Exception Process|If there is not a version of the operator that needs to be skipped, then an exception will be granted.
Tags|common,operator
|**Scenario**|**Optional/Mandatory**|
|Extended|Optional|
Expand Down
1 change: 1 addition & 0 deletions expected_results.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ testCases:
- operator-semantic-versioning
- operator-single-crd-owner
- operator-pods-no-hugepages
- operator-multiple-same-operators
- performance-exclusive-cpu-pool
- performance-max-resources-exec-probes
- performance-shared-cpu-pool-non-rt-scheduling-policy # hazelcast pod meets requirements
Expand Down
2 changes: 1 addition & 1 deletion pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func buildTestEnvironment() { //nolint:funlen
}
env.AllSubscriptions = data.AllSubscriptions
env.AllCatalogSources = data.AllCatalogSources
env.AllOperators = createOperators(data.AllCsvs, data.AllSubscriptions, data.AllInstallPlans, data.AllCatalogSources, false, false)
env.AllOperators = createOperators(data.AllCsvs, data.AllSubscriptions, data.AllInstallPlans, data.AllCatalogSources, false, true)
env.AllOperatorsSummary = getSummaryAllOperators(env.AllOperators)
env.AllCrds = data.AllCrds
env.Namespaces = data.Namespaces
Expand Down
1 change: 1 addition & 0 deletions tests/identifiers/doclinks.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const (
TestOperatorReadOnlyFilesystemDocLink = DocOperatorRequirement
TestOperatorPodsNoHugepagesDocLink = DocOperatorRequirement
TestOperatorOlmSkipRangeDocLink = DocOperatorRequirement
TestMultipleSameOperatorsIdentifierDocLink = DocOperatorRequirement

// Observability Test Suite
TestLoggingIdentifierDocLink = "https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-logging"
Expand Down
17 changes: 17 additions & 0 deletions tests/identifiers/identifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ var (
TestOperatorCrdSchemaIdentifier claim.Identifier
TestOperatorSingleCrdOwnerIdentifier claim.Identifier
TestOperatorPodsNoHugepages claim.Identifier
TestMultipleSameOperatorsIdentifier claim.Identifier
TestPodNodeSelectorAndAffinityBestPractices claim.Identifier
TestPodHighAvailabilityBestPractices claim.Identifier
TestPodClusterRoleBindingsBestPracticesIdentifier claim.Identifier
Expand Down Expand Up @@ -1067,6 +1068,22 @@ that Node's kernel may not have the same hacks.'`,
},
TagCommon)

TestMultipleSameOperatorsIdentifier = AddCatalogEntry(
"multiple-same-operators",
common.OperatorTestKey,
`Tests whether multiple instances of the same Operator CSV are installed.`,
MultipleSameOperatorsRemediation,
NoExceptions,
TestMultipleSameOperatorsIdentifierDocLink,
false,
map[string]string{
FarEdge: Mandatory,
Telco: Mandatory,
NonTelco: Mandatory,
Extended: Mandatory,
},
TagCommon)

TestPodNodeSelectorAndAffinityBestPractices = AddCatalogEntry(
"pod-scheduling",
common.LifecycleTestKey,
Expand Down
2 changes: 2 additions & 0 deletions tests/identifiers/remediation.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ const (

OperatorPodsNoHugepagesRemediation = `Ensure that the pods are not using hugepages`

MultipleSameOperatorsRemediation = `Ensure that only one Operator of the same type is installed in the cluster.`

PodNodeSelectorAndAffinityBestPracticesRemediation = `In most cases, Pod's should not specify their host Nodes through nodeSelector or nodeAffinity. However, there are cases in which workloads require specialized hardware specific to a particular class of Node.`

PodHighAvailabilityBestPracticesRemediation = `In high availability cases, Pod podAntiAffinity rule should be specified for pod scheduling and pod replica value is set to more than 1 .`
Expand Down
55 changes: 55 additions & 0 deletions tests/operator/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ func LoadChecks() {
testOperatorOlmSkipRange(c, &env)
return nil
}))

checksGroup.Add(checksdb.NewCheck(identifiers.GetTestIDAndLabels(identifiers.TestMultipleSameOperatorsIdentifier)).
WithSkipCheckFn(testhelper.GetNoOperatorsSkipFn(&env)).
WithCheckFn(func(c *checksdb.Check) error {
testMultipleSameOperators(c, &env)
return nil
}))
}

// This function check if the Operator CRD version follows K8s versioning
Expand Down Expand Up @@ -373,3 +380,51 @@ func testOperatorOlmSkipRange(check *checksdb.Check, env *provider.TestEnvironme
}
check.SetResult(compliantObjects, nonCompliantObjects)
}

func testMultipleSameOperators(check *checksdb.Check, env *provider.TestEnvironment) {
var compliantObjects []*testhelper.ReportObject
var nonCompliantObjects []*testhelper.ReportObject

// Ensure the CSV name is unique and not installed more than once.
// CSV Names are unique and OLM installs them with name.version format.
// So, we can check if the CSV name is installed more than once.

check.LogInfo("Checking if the operator is installed more than once")

for _, op := range env.AllOperators {
check.LogDebug("Checking operator %q", op.Name)
check.LogDebug("Number of operators to check %s against: %d", op.Name, len(env.AllOperators))
for _, op2 := range env.AllOperators {
check.LogDebug("Comparing operator %q with operator %q", op.Name, op2.Name)

// Retrieve the version from each CSV
csv1Version := op.Csv.Spec.Version.String()
csv2Version := op2.Csv.Spec.Version.String()

log.Debug("CSV1 Version: %s", csv1Version)
log.Debug("CSV2 Version: %s", csv2Version)

// Strip the version from the CSV name by removing the suffix (which should be the version)
csv1Name := strings.TrimSuffix(op.Csv.Name, ".v"+csv1Version)
csv2Name := strings.TrimSuffix(op2.Csv.Name, ".v"+csv2Version)

check.LogDebug("Comparing CSV names %q and %q", csv1Name, csv2Name)

// The CSV name should be the same, but the version should be different
// if the operator is installed more than once.
if op.Csv != nil && op2.Csv != nil &&
csv1Name == csv2Name &&
csv1Version != csv2Version {
check.LogError("Operator %q is installed more than once", op.Name)
nonCompliantObjects = append(nonCompliantObjects, testhelper.NewOperatorReportObject(
op.Namespace, op.Name, "Operator is installed more than once", false))
break
}
}

compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(
op.Namespace, op.Name, "Operator is installed only once", true))
}

check.SetResult(compliantObjects, nonCompliantObjects)
}
Loading