Skip to content

Commit 6627858

Browse files
authored
operator: Multiple same operators installed test (#2542)
1 parent b48ff45 commit 6627858

File tree

7 files changed

+99
-7
lines changed

7 files changed

+99
-7
lines changed

CATALOG.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Depending on the workload type, not all tests are required to pass to satisfy be
77

88
## Test cases summary
99

10-
### Total test cases: 114
10+
### Total test cases: 116
1111

1212
### Total suites: 10
1313

@@ -19,7 +19,7 @@ Depending on the workload type, not all tests are required to pass to satisfy be
1919
|manageability|2|
2020
|networking|12|
2121
|observability|5|
22-
|operator|9|
22+
|operator|10|
2323
|performance|6|
2424
|platform-alteration|13|
2525
|preflight|17|
@@ -36,11 +36,11 @@ Depending on the workload type, not all tests are required to pass to satisfy be
3636
|---|---|
3737
|8|1|
3838

39-
### Non-Telco specific tests only: 67
39+
### Non-Telco specific tests only: 68
4040

4141
|Mandatory|Optional|
4242
|---|---|
43-
|42|25|
43+
|43|25|
4444

4545
### Telco specific tests only: 27
4646

@@ -1266,15 +1266,31 @@ Tags|common,operator
12661266
|Non-Telco|Mandatory|
12671267
|Telco|Mandatory|
12681268

1269+
#### operator-multiple-same-operators
1270+
1271+
Property|Description
1272+
---|---
1273+
Unique ID|operator-multiple-same-operators
1274+
Description|Tests whether multiple instances of the same Operator CSV are installed.
1275+
Suggested Remediation|Ensure that only one Operator of the same type is installed in the cluster.
1276+
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-operator-requirements
1277+
Exception Process|No exceptions
1278+
Tags|common,operator
1279+
|**Scenario**|**Optional/Mandatory**|
1280+
|Extended|Mandatory|
1281+
|Far-Edge|Mandatory|
1282+
|Non-Telco|Mandatory|
1283+
|Telco|Mandatory|
1284+
12691285
#### operator-olm-skip-range
12701286

12711287
Property|Description
12721288
---|---
12731289
Unique ID|operator-olm-skip-range
12741290
Description|Test that checks the operator has a valid olm skip range.
1275-
Suggested Remediation|Ensure that the Operator has a valid OLM skip range.
1291+
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.
12761292
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-operator-requirements
1277-
Exception Process|No exceptions
1293+
Exception Process|If there is not a version of the operator that needs to be skipped, then an exception will be granted.
12781294
Tags|common,operator
12791295
|**Scenario**|**Optional/Mandatory**|
12801296
|Extended|Optional|

expected_results.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ testCases:
5858
- operator-semantic-versioning
5959
- operator-single-crd-owner
6060
- operator-pods-no-hugepages
61+
- operator-multiple-same-operators
6162
- performance-exclusive-cpu-pool
6263
- performance-max-resources-exec-probes
6364
- performance-shared-cpu-pool-non-rt-scheduling-policy # hazelcast pod meets requirements

pkg/provider/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func buildTestEnvironment() { //nolint:funlen
240240
}
241241
env.AllSubscriptions = data.AllSubscriptions
242242
env.AllCatalogSources = data.AllCatalogSources
243-
env.AllOperators = createOperators(data.AllCsvs, data.AllSubscriptions, data.AllInstallPlans, data.AllCatalogSources, false, false)
243+
env.AllOperators = createOperators(data.AllCsvs, data.AllSubscriptions, data.AllInstallPlans, data.AllCatalogSources, false, true)
244244
env.AllOperatorsSummary = getSummaryAllOperators(env.AllOperators)
245245
env.AllCrds = data.AllCrds
246246
env.Namespaces = data.Namespaces

tests/identifiers/doclinks.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ const (
117117
TestOperatorReadOnlyFilesystemDocLink = DocOperatorRequirement
118118
TestOperatorPodsNoHugepagesDocLink = DocOperatorRequirement
119119
TestOperatorOlmSkipRangeDocLink = DocOperatorRequirement
120+
TestMultipleSameOperatorsIdentifierDocLink = DocOperatorRequirement
120121

121122
// Observability Test Suite
122123
TestLoggingIdentifierDocLink = "https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-logging"

tests/identifiers/identifiers.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ var (
133133
TestOperatorCrdSchemaIdentifier claim.Identifier
134134
TestOperatorSingleCrdOwnerIdentifier claim.Identifier
135135
TestOperatorPodsNoHugepages claim.Identifier
136+
TestMultipleSameOperatorsIdentifier claim.Identifier
136137
TestPodNodeSelectorAndAffinityBestPractices claim.Identifier
137138
TestPodHighAvailabilityBestPractices claim.Identifier
138139
TestPodClusterRoleBindingsBestPracticesIdentifier claim.Identifier
@@ -1067,6 +1068,22 @@ that Node's kernel may not have the same hacks.'`,
10671068
},
10681069
TagCommon)
10691070

1071+
TestMultipleSameOperatorsIdentifier = AddCatalogEntry(
1072+
"multiple-same-operators",
1073+
common.OperatorTestKey,
1074+
`Tests whether multiple instances of the same Operator CSV are installed.`,
1075+
MultipleSameOperatorsRemediation,
1076+
NoExceptions,
1077+
TestMultipleSameOperatorsIdentifierDocLink,
1078+
false,
1079+
map[string]string{
1080+
FarEdge: Mandatory,
1081+
Telco: Mandatory,
1082+
NonTelco: Mandatory,
1083+
Extended: Mandatory,
1084+
},
1085+
TagCommon)
1086+
10701087
TestPodNodeSelectorAndAffinityBestPractices = AddCatalogEntry(
10711088
"pod-scheduling",
10721089
common.LifecycleTestKey,

tests/identifiers/remediation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ const (
101101

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

104+
MultipleSameOperatorsRemediation = `Ensure that only one Operator of the same type is installed in the cluster.`
105+
104106
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.`
105107

106108
PodHighAvailabilityBestPracticesRemediation = `In high availability cases, Pod podAntiAffinity rule should be specified for pod scheduling and pod replica value is set to more than 1 .`

tests/operator/suite.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ func LoadChecks() {
108108
testOperatorOlmSkipRange(c, &env)
109109
return nil
110110
}))
111+
112+
checksGroup.Add(checksdb.NewCheck(identifiers.GetTestIDAndLabels(identifiers.TestMultipleSameOperatorsIdentifier)).
113+
WithSkipCheckFn(testhelper.GetNoOperatorsSkipFn(&env)).
114+
WithCheckFn(func(c *checksdb.Check) error {
115+
testMultipleSameOperators(c, &env)
116+
return nil
117+
}))
111118
}
112119

113120
// This function check if the Operator CRD version follows K8s versioning
@@ -373,3 +380,51 @@ func testOperatorOlmSkipRange(check *checksdb.Check, env *provider.TestEnvironme
373380
}
374381
check.SetResult(compliantObjects, nonCompliantObjects)
375382
}
383+
384+
func testMultipleSameOperators(check *checksdb.Check, env *provider.TestEnvironment) {
385+
var compliantObjects []*testhelper.ReportObject
386+
var nonCompliantObjects []*testhelper.ReportObject
387+
388+
// Ensure the CSV name is unique and not installed more than once.
389+
// CSV Names are unique and OLM installs them with name.version format.
390+
// So, we can check if the CSV name is installed more than once.
391+
392+
check.LogInfo("Checking if the operator is installed more than once")
393+
394+
for _, op := range env.AllOperators {
395+
check.LogDebug("Checking operator %q", op.Name)
396+
check.LogDebug("Number of operators to check %s against: %d", op.Name, len(env.AllOperators))
397+
for _, op2 := range env.AllOperators {
398+
check.LogDebug("Comparing operator %q with operator %q", op.Name, op2.Name)
399+
400+
// Retrieve the version from each CSV
401+
csv1Version := op.Csv.Spec.Version.String()
402+
csv2Version := op2.Csv.Spec.Version.String()
403+
404+
log.Debug("CSV1 Version: %s", csv1Version)
405+
log.Debug("CSV2 Version: %s", csv2Version)
406+
407+
// Strip the version from the CSV name by removing the suffix (which should be the version)
408+
csv1Name := strings.TrimSuffix(op.Csv.Name, ".v"+csv1Version)
409+
csv2Name := strings.TrimSuffix(op2.Csv.Name, ".v"+csv2Version)
410+
411+
check.LogDebug("Comparing CSV names %q and %q", csv1Name, csv2Name)
412+
413+
// The CSV name should be the same, but the version should be different
414+
// if the operator is installed more than once.
415+
if op.Csv != nil && op2.Csv != nil &&
416+
csv1Name == csv2Name &&
417+
csv1Version != csv2Version {
418+
check.LogError("Operator %q is installed more than once", op.Name)
419+
nonCompliantObjects = append(nonCompliantObjects, testhelper.NewOperatorReportObject(
420+
op.Namespace, op.Name, "Operator is installed more than once", false))
421+
break
422+
}
423+
}
424+
425+
compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(
426+
op.Namespace, op.Name, "Operator is installed only once", true))
427+
}
428+
429+
check.SetResult(compliantObjects, nonCompliantObjects)
430+
}

0 commit comments

Comments
 (0)