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

Cluster-wide operators support improvements #2479

Merged
3 changes: 3 additions & 0 deletions .github/workflows/pre-main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ jobs:
- name: 'Test: Run test suites'
run: ./certsuite run --label-filter="${SMOKE_TESTS_LABELS_FILTER}" --output-dir=certsuite-out --log-level="${SMOKE_TESTS_LOG_LEVEL}"

- name: 'Show failed test cases and the non compliant objects'
run: ./certsuite claim show failures -c certsuite-out/claim.json

- name: Upload smoke test results as an artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/qe-hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ jobs:
with:
repository: ${{ env.QE_REPO }}
path: certsuite-qe
ref: main
ref: access_control_and_operator_updates

- name: Extract dependent Pull Requests
uses: depends-on/depends-on-action@9e8a61fce18b15281e831f1bba0e14c71d1e1f46 # main
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/qe-ocp-arm-416.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ jobs:
with:
repository: ${{ env.QE_REPO }}
path: certsuite-qe
ref: main
# Reference temporarily changed to point to QE PR#953.
ref: access_control_and_operator_updates

- name: Preemptively potential QE namespaces
run: ./scripts/delete-namespaces.sh
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/qe-ocp-pre-main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ jobs:
with:
repository: ${{ env.QE_REPO }}
path: certsuite-qe
ref: main
# Reference temporarily changed to point to QE PR#952.
ref: access_control_and_operator_updates

- name: Preemptively potential QE namespaces
run: ./scripts/delete-namespaces.sh
Expand Down
110 changes: 39 additions & 71 deletions CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ 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: 112

### Total suites: 10

|Suite|Tests per suite|
|---|---|
|access-control|27|
|access-control|29|
|affiliated-certification|4|
|lifecycle|18|
|manageability|2|
|networking|11|
|observability|5|
|operator|11|
|operator|7|
|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
|---|---|
|7|1|

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

|Mandatory|Optional|
|---|---|
|44|23|
|42|23|

### Telco specific tests only: 27

Expand Down Expand Up @@ -374,11 +374,11 @@ Tags|extended,access-control
|Non-Telco|Optional|
|Telco|Optional|

#### access-control-security-context-non-root-user-check
#### access-control-security-context-non-root-user-id-check

Property|Description
---|---
Unique ID|access-control-security-context-non-root-user-check
Unique ID|access-control-security-context-non-root-user-id-check
Description|Checks the security context runAsUser parameter in pods and containers to make sure it is not set to uid root(0). Pods and containers should not run as root (runAsUser is not set to uid0).
Suggested Remediation|Change the pod and containers "runAsUser" uid to something other than root(0)
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-security
Expand Down Expand Up @@ -406,6 +406,38 @@ Tags|common,access-control
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### access-control-security-context-read-only-file-system

Property|Description
---|---
Unique ID|access-control-security-context-read-only-file-system
Description|Checks the security context readOnlyFileSystem in containers is enabled. Containers should not try modify its own filesystem.
Suggested Remediation|No exceptions - will only be considered under special circumstances. Must identify which container needs access and document why with details.
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-security
Exception Process|No exceptions
Tags|common,access-control
|**Scenario**|**Optional/Mandatory**|
|Extended|Optional|
|Far-Edge|Optional|
|Non-Telco|Optional|
|Telco|Optional|

#### access-control-security-context-run-as-non-root-user-check

Property|Description
---|---
Unique ID|access-control-security-context-run-as-non-root-user-check
Description|Checks the security context runAsNonRoot parameter in pods and containers to make sure it is not set to false. Pods and containers should not be able to run as root..
Suggested Remediation|Set the the pod and containers "runAsNonRoot" to true.
Best Practice Reference|https://redhat-best-practices-for-k8s.github.io/guide/#redhat-best-practices-for-k8s-cnf-security
Exception Process|No exceptions - will only be considered under special circumstances. Must identify which container needs access and document why with details.
Tags|common,access-control
|**Scenario**|**Optional/Mandatory**|
|Extended|Mandatory|
|Far-Edge|Mandatory|
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### access-control-service-type

Property|Description
Expand Down Expand Up @@ -1138,22 +1170,6 @@ Tags|telco,observability

### operator

#### operator-automount-tokens

Property|Description
---|---
Unique ID|operator-automount-tokens
Description|Tests that check that the pods disable the automount service account token."
Suggested Remediation|Ensure that the pods have the automount service account token disabled.
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-crd-openapi-schema

Property|Description
Expand Down Expand Up @@ -1234,54 +1250,6 @@ Tags|common,operator
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-read-only-file-system

Property|Description
---|---
Unique ID|operator-read-only-file-system
Description|Tests that check that the pods have the read-only root filesystem setting enabled.
Suggested Remediation|Ensure that the pods have the read-only root filesystem setting enabled.
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|Optional|
|Far-Edge|Optional|
|Non-Telco|Optional|
|Telco|Optional|

#### operator-run-as-non-root

Property|Description
---|---
Unique ID|operator-run-as-non-root
Description|Tests that checks the pods ensure they are run as non root.
Suggested Remediation|Ensure that the pods are running as non root.
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-run-as-user-id

Property|Description
---|---
Unique ID|operator-run-as-user-id
Description|Tests that checks the user id of the pods ensure it is not 0.
Suggested Remediation|Ensure that the user ID of the pods is not 0.
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-semantic-versioning

Property|Description
Expand Down
30 changes: 16 additions & 14 deletions expected_results.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ testCases:
- access-control-pod-role-bindings
- access-control-pod-service-account
- access-control-requests-and-limits
- access-control-security-context-non-root-user-check
- access-control-security-context-non-root-user-id-check
- access-control-security-context-privilege-escalation
- access-control-service-type
- access-control-ssh-daemons
- access-control-sys-admin-capability-check
- access-control-sys-nice-realtime-capability
- affiliated-certification-operator-is-certified
- lifecycle-affinity-required-pods
- lifecycle-container-poststart
- lifecycle-container-prestop
- lifecycle-crd-scaling
- lifecycle-deployment-scaling
- lifecycle-image-pull-policy
Expand All @@ -40,9 +38,6 @@ testCases:
- lifecycle-pod-scheduling
- lifecycle-pod-toleration-bypass
- lifecycle-readiness-probe
- lifecycle-startup-probe
- manageability-container-port-name-format
- manageability-containers-image-tag
- networking-dual-stack-service
- networking-icmpv4-connectivity
- networking-icmpv4-connectivity-multus
Expand All @@ -54,26 +49,34 @@ testCases:
- observability-container-logging
- observability-crd-status
- observability-pod-disruption-budget
- observability-termination-policy
- observability-compatibility-with-next-ocp-release
- operator-crd-openapi-schema
- operator-crd-versioning
- operator-install-source
- operator-install-status-no-privileges
- operator-install-status-succeeded
- operator-run-as-user-id
- operator-semantic-versioning
- operator-single-crd-owner
- performance-exclusive-cpu-pool
- performance-max-resources-exec-probes
- performance-shared-cpu-pool-non-rt-scheduling-policy # hazelcast pod meets requirements
- platform-alteration-isredhat-release
- platform-alteration-tainted-node-kernel
fail:
- access-control-security-context # test pod does not meet the security requirements
- affiliated-certification-container-is-certified-digest # test container image is not certified
- operator-read-only-file-system
- operator-run-as-non-root
- operator-automount-tokens
- affiliated-certification-container-is-certified-digest # test container image is not certified
- access-control-security-context # hazelcast pod does not meet the security context requirements
- access-control-security-context-run-as-non-root-user-check # hazelcast pod does not meet the security context requirements
- access-control-security-context-read-only-file-system # hazelcast pod does not meet the security context requirements
- access-control-pod-role-bindings # hazelcast pod has role bindings outside installation ns
- access-control-pod-automount-service-account-token # hazelcast pod has SA token automounted
- networking-network-policy-deny-all # hazelcast pod does not have deny-all network policy
- networking-undeclared-container-ports-usage # hazelcast pod does not declare ports 8080 and 8081
- observability-termination-policy # hazelcast pod uses terminationMessagePolicy
- lifecycle-container-prestop # hazelcast pod doesn't define this hook
- lifecycle-container-poststart # hazelcast pod doesn't define this hook
- lifecycle-startup-probe # hazelcast pod doesn't define this probe
- manageability-container-port-name-format # hazelcast declares not allowed port name "webhook-server".
- manageability-containers-image-tag # hazelcast container not using image tag.
skip:
- access-control-sys-ptrace-capability
- affiliated-certification-helm-version
Expand All @@ -87,7 +90,6 @@ testCases:
- performance-exclusive-cpu-pool-rt-scheduling-policy
- performance-isolated-cpu-pool-rt-scheduling-policy
- performance-rt-apps-no-exec-probes
- performance-shared-cpu-pool-non-rt-scheduling-policy
- platform-alteration-base-image
- platform-alteration-boot-params
- platform-alteration-hugepages-config
Expand Down
59 changes: 20 additions & 39 deletions pkg/autodiscover/autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

const (
Expand All @@ -59,7 +60,7 @@ type DiscoveredTestData struct {
Pods []corev1.Pod
AllPods []corev1.Pod
ProbePods []corev1.Pod
CSVToPodListMap map[string][]*corev1.Pod
CSVToPodListMap map[types.NamespacedName][]*corev1.Pod
ResourceQuotaItems []corev1.ResourceQuota
PodDisruptionBudgets []policyv1.PodDisruptionBudget
NetworkPolicies []networkingv1.NetworkPolicy
Expand Down Expand Up @@ -300,36 +301,34 @@ func getOpenshiftVersion(oClient clientconfigv1.ConfigV1Interface) (ver string,
return "", errors.New("could not get openshift version from clusterOperator")
}

// Get a map of csvs with its managed pods from the target namespaces
func getOperatorCsvPods(csvList []*olmv1Alpha.ClusterServiceVersion) (map[string][]*corev1.Pod, error) {
// Get a map of csvs with its managed operator/controller pods from its installation namespace.
func getOperatorCsvPods(csvList []*olmv1Alpha.ClusterServiceVersion) (map[types.NamespacedName][]*corev1.Pod, error) {
const nsAnnotation = "olm.operatorNamespace"

client := clientsholder.GetClientsHolder()
csvToPodsMapping := make(map[string][]*corev1.Pod)
csvToPodsMapping := make(map[types.NamespacedName][]*corev1.Pod)

// The operator's pod (controller) should run in the subscription/operatorgroup ns.
for _, csv := range csvList {
// Get target namespaces
operatorTargetNamespaces, err := getOperatorTargetNamespaces(csv, client)
if err != nil {
return csvToPodsMapping, err
ns, found := csv.Annotations[nsAnnotation]
if !found {
return nil, fmt.Errorf("failed to get ns annotation %q from csv %v/%v", nsAnnotation, csv.Namespace, csv.Name)
}
var podList []*corev1.Pod

for _, targetNamespace := range operatorTargetNamespaces {
pods, err := getCsvPodsFromTargetNamespace(csv, strings.TrimSpace(targetNamespace), client)
if err != nil {
continue
}
podList = append(podList, pods...)
pods, err := getPodsOwnedByCsv(csv.Name, strings.TrimSpace(ns), client)
if err != nil {
return nil, fmt.Errorf("failed to get pods from ns %v: %v", ns, err)
}

csvToPodsMapping[fmt.Sprintf(csvNameWithNamespaceFormatStr, csv.Name, csv.Namespace)] = podList
csvToPodsMapping[types.NamespacedName{Name: csv.Name, Namespace: csv.Namespace}] = pods
}
return csvToPodsMapping, nil
}

// This function gets the pods of the specified csv in a target namespace
func getCsvPodsFromTargetNamespace(csv *olmv1Alpha.ClusterServiceVersion, targetNamespace string, client *clientsholder.ClientsHolder) (managedPods []*corev1.Pod, err error) {
// This function gets the operator/controller pods of the specified csv name in from the installation namespace.
func getPodsOwnedByCsv(csvName, operatorNamespace string, client *clientsholder.ClientsHolder) (managedPods []*corev1.Pod, err error) {
// Get all pods from the target namespace
podsList, err := client.K8sClient.CoreV1().Pods(targetNamespace).List(context.TODO(), metav1.ListOptions{})
podsList, err := client.K8sClient.CoreV1().Pods(operatorNamespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
Expand All @@ -344,30 +343,12 @@ func getCsvPodsFromTargetNamespace(csv *olmv1Alpha.ClusterServiceVersion, target

// check if owner matches with the csv
for _, owner := range topOwners {
if owner.Kind == csv.Kind && owner.Namespace == csv.Namespace && owner.Name == csv.Name {
// The owner must be in the targetNamespace
if owner.Kind == olmv1Alpha.ClusterServiceVersionKind && owner.Namespace == operatorNamespace && owner.Name == csvName {
managedPods = append(managedPods, &podsList.Items[index])
break
}
}
}
return managedPods, nil
}

// This function lists the target namespaces of an operator
func getOperatorTargetNamespaces(csv *olmv1Alpha.ClusterServiceVersion, client *clientsholder.ClientsHolder) ([]string, error) {
annotations := csv.Annotations

targetNamespaces := annotations["olm.targetNamespaces"] // This is a comma-separated string, example : a,b,c where a, b and c are target namespaces
operatorTargetNamespaces := strings.Split(targetNamespaces, ",") // For cluster installed operator olm.targetNamespaces: ""

// When the operator is cluster installed operator
if len(operatorTargetNamespaces) == 0 {
// Get all namespaces
allNamespaces, err := getAllNamespaces(client.K8sClient.CoreV1())
if err != nil {
return nil, err
}
operatorTargetNamespaces = allNamespaces
}
return operatorTargetNamespaces, nil
}
Loading
Loading