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

Fix for test case operator-install-status-no-privileges. #1665

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 CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ Tags|common,operator
Property|Description
---|---
Unique ID|operator-install-status-no-privileges
Description|The operator is not installed with privileged rights. Test passes if clusterPermissions is not present in the CSV manifest or is present with no resourceNames under its rules.
Description|Checks whether the operator needs access to Security Context Constraints. Test passes if clusterPermissions is not present in the CSV manifest or is present with no RBAC rules related to SCCs.
Suggested Remediation|Ensure all the CNF operators have no privileges on cluster resources.
Best Practice Reference|https://test-network-function.github.io/cnf-best-practices-guide/#cnf-best-practices-cnf-operator-requirements
Exception Process|No exceptions
Expand Down
6 changes: 3 additions & 3 deletions cnf-certification-test/identifiers/identifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ var (
TestNamespaceBestPracticesIdentifier claim.Identifier
TestNonTaintedNodeKernelsIdentifier claim.Identifier
TestOperatorInstallStatusSucceededIdentifier claim.Identifier
TestOperatorNoPrivileges claim.Identifier
TestOperatorNoSCCAccess claim.Identifier
TestOperatorIsCertifiedIdentifier claim.Identifier
TestHelmIsCertifiedIdentifier claim.Identifier
TestOperatorIsInstalledViaOLMIdentifier claim.Identifier
Expand Down Expand Up @@ -846,10 +846,10 @@ tag. (2) It does not have any of the following prefixes: default, openshift-, is
},
TagCommon)

TestOperatorNoPrivileges = AddCatalogEntry(
TestOperatorNoSCCAccess = AddCatalogEntry(
"install-status-no-privileges",
common.OperatorTestKey,
`The operator is not installed with privileged rights. Test passes if clusterPermissions is not present in the CSV manifest or is present with no resourceNames under its rules.`,
`Checks whether the operator needs access to Security Context Constraints. Test passes if clusterPermissions is not present in the CSV manifest or is present with no RBAC rules related to SCCs.`,
OperatorNoPrivilegesRemediation,
NoExceptions,
TestOperatorNoPrivilegesDocLink,
Expand Down
60 changes: 38 additions & 22 deletions cnf-certification-test/operator/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ func LoadChecks() {
return nil
}))

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

Expand Down Expand Up @@ -159,42 +159,58 @@ func testOperatorInstallationPhaseSucceeded(check *checksdb.Check, env *provider
check.SetResult(compliantObjects, nonCompliantObjects)
}

func testOperatorInstallationWithoutPrivileges(check *checksdb.Check, env *provider.TestEnvironment) {
func testOperatorInstallationAccessToSCC(check *checksdb.Check, env *provider.TestEnvironment) {
var compliantObjects []*testhelper.ReportObject
var nonCompliantObjects []*testhelper.ReportObject
for _, op := range env.Operators {
check.LogInfo("Testing Operator %q", op)
clusterPermissions := op.Csv.Spec.InstallStrategy.StrategySpec.ClusterPermissions
for i := range env.Operators {
operator := env.Operators[i]
csv := operator.Csv
check.LogDebug("Checking operator %s", operator)
clusterPermissions := csv.Spec.InstallStrategy.StrategySpec.ClusterPermissions
if len(clusterPermissions) == 0 {
check.LogInfo("Operator %q has no privileged on cluster resources. No clusterPermissions found.", op)
compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(op.Namespace, op.Name, "Operator has no privileges on cluster resources", true))
check.LogInfo("No clusterPermissions found in %s's CSV", operator)
compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(operator.Namespace, operator.Name,
"No RBAC rules for Security Context Constraints found in CSV (no clusterPermissions found)", true))
continue
}

// Fails in case any cluster permission has a rule with any resource name.
// Fails in case any cluster permission has a rule that refers to securitycontextconstraints.
badRuleFound := false
for permissionIndex := range clusterPermissions {
permission := &clusterPermissions[permissionIndex]
for ruleIndex := range permission.Rules {
if n := len(permission.Rules[ruleIndex].ResourceNames); n > 0 {
resources := strings.Join(permission.Rules[ruleIndex].ResourceNames, " ")
check.LogError("Operator %q has privileges on cluster resources (service account=%q, resources=%q)", op, permission.ServiceAccountName, resources)
// Keep reviewing other permissions' rules so we can log all the failing ones in the claim file.
badRuleFound = true
nonCompliantObjects = append(nonCompliantObjects, testhelper.NewOperatorReportObject(op.Namespace, op.Name, "Operator has privileges on cluster resources ", false).
SetType(testhelper.OperatorPermission).AddField(testhelper.ServiceAccountName, permission.ServiceAccountName).AddField(testhelper.ResourceName+"s", resources))
} else {
check.LogInfo("Operator %q has no privileges on cluster resources", op)
compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(op.Namespace, op.Name, "Operator has no privileges on cluster resources", true).
SetType(testhelper.OperatorPermission).AddField(testhelper.ServiceAccountName, permission.ServiceAccountName).AddField(testhelper.ResourceName+"s", "n/a"))
rule := &permission.Rules[ruleIndex]

// Check whether the rule is for the security api group.
securityGroupFound := false
for _, group := range rule.APIGroups {
if group == "*" || group == "security.openshift.io" {
securityGroupFound = true
break
}
}

if !securityGroupFound {
continue
}

// Now check whether it grants some access to securitycontextconstraint resources.
for _, resource := range rule.Resources {
if resource == "*" || resource == "securitycontextconstraints" {
check.LogInfo("Operator %s has a rule (index %d) for service account %s to access cluster SCCs",
operator, ruleIndex, permission.ServiceAccountName)
// Keep reviewing other permissions' rules so we can log all the failing ones in the claim file.
badRuleFound = true
break
}
}
}
}

if badRuleFound {
nonCompliantObjects = append(nonCompliantObjects, testhelper.NewOperatorReportObject(op.Namespace, op.Name, "Operator has privileges on cluster resources ", false))
nonCompliantObjects = append(nonCompliantObjects, testhelper.NewOperatorReportObject(operator.Namespace, operator.Name, "One or more RBAC rules for Security Context Constraints found in CSV", false))
} else {
compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(op.Namespace, op.Name, "Operator has no privileges on cluster resources", true))
compliantObjects = append(compliantObjects, testhelper.NewOperatorReportObject(operator.Namespace, operator.Name, "No RBAC rules for Security Context Constraints found in CSV", true))
}
}

Expand Down
Loading