Skip to content

Commit

Permalink
CMP-2526: Disable automatic remediation for ROSA HCP environments
Browse files Browse the repository at this point in the history
Since the Compliance Operator is only going to support running on HCP environments,
where end users don't have access to the master nodes (or control plane),
it doesn't make sense to give them a scan setting with auto remediation functionality applied.

For this case, the Compliance Operator should detect if it is running on ROSA HCP and adjust,
or just not create the `default-auto-apply` scan settings.
  • Loading branch information
Vincent056 committed May 16, 2024
1 parent 9e8ea4d commit 2731ca3
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 24 deletions.
59 changes: 35 additions & 24 deletions cmd/manager/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ var (
"worker",
},
}
defaultAutoRemediationPerPlatform = map[PlatformType]bool{
PlatformOpenShift: true,
PlatformOpenShiftOnPower: true,
PlatformOpenShiftOnZ: true,
PlatformEKS: false,
PlatformGeneric: false,
PlatformHyperShift: true,
PlatformROSA: false,
}
serviceMonitorBearerTokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"
serviceMonitorTLSCAFile = "/etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt"
alertName = "compliance"
Expand Down Expand Up @@ -571,6 +580,7 @@ func ensureDefaultScanSettings(
var lastErr error
for _, ns := range namespaceList {
roles := getDefaultRoles(platform)
autoRemediationEnabled := defaultAutoRemediationPerPlatform[platform]
d := &compv1alpha1.ScanSetting{
ObjectMeta: metav1.ObjectMeta{
Name: defaultScanSettingsName,
Expand All @@ -594,31 +604,32 @@ func ensureDefaultScanSettings(
if !k8serrors.IsAlreadyExists(derr) {
lastErr = derr
}

a := &compv1alpha1.ScanSetting{
ObjectMeta: metav1.ObjectMeta{
Name: defaultAutoApplyScanSettingsName,
Namespace: ns,
},
ComplianceScanSettings: compv1alpha1.ComplianceScanSettings{
RawResultStorage: compv1alpha1.RawResultStorageSettings{
NodeSelector: si.Selector,
Tolerations: si.Tolerations,
if autoRemediationEnabled {
a := &compv1alpha1.ScanSetting{
ObjectMeta: metav1.ObjectMeta{
Name: defaultAutoApplyScanSettingsName,
Namespace: ns,
},
},
ComplianceSuiteSettings: compv1alpha1.ComplianceSuiteSettings{
AutoApplyRemediations: true,
AutoUpdateRemediations: true,
Schedule: defaultScanSettingsSchedule,
},
Roles: roles,
}
setupLog.Info("Ensuring ScanSetting is available",
"ScanSetting.Name", d.GetName(),
"ScanSetting.Namespace", d.GetNamespace())
aerr := crclient.Create(ctx, a)
if !k8serrors.IsAlreadyExists(aerr) {
lastErr = aerr
ComplianceScanSettings: compv1alpha1.ComplianceScanSettings{
RawResultStorage: compv1alpha1.RawResultStorageSettings{
NodeSelector: si.Selector,
Tolerations: si.Tolerations,
},
},
ComplianceSuiteSettings: compv1alpha1.ComplianceSuiteSettings{
AutoApplyRemediations: true,
AutoUpdateRemediations: true,
Schedule: defaultScanSettingsSchedule,
},
Roles: roles,
}
setupLog.Info("Ensuring ScanSetting is available",
"ScanSetting.Name", d.GetName(),
"ScanSetting.Namespace", d.GetNamespace())
aerr := crclient.Create(ctx, a)
if !k8serrors.IsAlreadyExists(aerr) {
lastErr = aerr
}
}
}
return lastErr
Expand Down
27 changes: 27 additions & 0 deletions tests/e2e/framework/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
clusterv1alpha1 "open-cluster-management.io/api/cluster/v1alpha1"

"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
Expand Down Expand Up @@ -222,6 +224,19 @@ func (f *Framework) addFrameworks() error {
}
}

// ClusterClaim objects
if f.Platform == "rosa" {
ccObjs := [1]dynclient.ObjectList{
&clusterv1alpha1.ClusterClaimList{},
}
for _, obj := range ccObjs {
err := AddToFrameworkScheme(clusterv1alpha1.Install, obj)
if err != nil {
return fmt.Errorf("failed to add custom resource scheme to framework: %v", err)
}
}
}

// OpenShift objects
ocpObjs := [2]dynclient.ObjectList{
&imagev1.ImageStreamList{},
Expand Down Expand Up @@ -420,6 +435,10 @@ func (f *Framework) GetReadyProfileBundle(name, namespace string) (*compv1alpha1
}

func (f *Framework) updateScanSettingsForDebug() error {
if f.Platform == "rosa" {
fmt.Printf("bypassing ScanSettings test setup because it's not supported on %s\n", f.Platform)
return nil
}
for _, ssName := range []string{"default", "default-auto-apply"} {
ss := &compv1alpha1.ScanSetting{}
sskey := types.NamespacedName{Name: ssName, Namespace: f.OperatorNamespace}
Expand All @@ -438,6 +457,10 @@ func (f *Framework) updateScanSettingsForDebug() error {
}

func (f *Framework) ensureE2EScanSettings() error {
if f.Platform == "rosa" {
fmt.Printf("bypassing ScanSettings test setup because it's not supported on %s\n", f.Platform)
return nil
}
for _, ssName := range []string{"default", "default-auto-apply"} {
ss := &compv1alpha1.ScanSetting{}
sskey := types.NamespacedName{Name: ssName, Namespace: f.OperatorNamespace}
Expand All @@ -464,6 +487,10 @@ func (f *Framework) ensureE2EScanSettings() error {
}

func (f *Framework) deleteScanSettings(name string) error {
if f.Platform == "rosa" {
fmt.Printf("bypassing ScanSettings test setup because it's not supported on %s\n", f.Platform)
return nil
}
ss := &compv1alpha1.ScanSetting{}
sskey := types.NamespacedName{Name: name, Namespace: f.OperatorNamespace}
if err := f.Client.Get(context.TODO(), sskey, ss); err != nil {
Expand Down
65 changes: 65 additions & 0 deletions tests/e2e/rosa/main_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package rosa_e2e

import (
"context"
"log"
"os"
"strings"
"testing"

compv1alpha1 "github.com/ComplianceAsCode/compliance-operator/pkg/apis/compliance/v1alpha1"
"github.com/ComplianceAsCode/compliance-operator/tests/e2e/framework"
corev1 "k8s.io/api/core/v1"
clusterv1alpha1 "open-cluster-management.io/api/cluster/v1alpha1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

var brokenContentImagePath string
Expand All @@ -26,3 +32,62 @@ func TestMain(m *testing.M) {
}
os.Exit(exitCode)
}

func TestScanSetting(t *testing.T) {
f := framework.Global
// prinout all scan settings
scanSettingList := compv1alpha1.ScanSettingList{}
err := f.Client.List(context.TODO(), &scanSettingList)
if err != nil {
t.Fatalf("Failed to list scan settings: %v", err)
}
for _, scanSetting := range scanSettingList.Items {
t.Logf("ScanSetting: %s", scanSetting.Name)
for _, role := range scanSetting.Roles {
t.Logf("Role: %s", role)
}
}

// List cluster claims
clusterClaimList := clusterv1alpha1.ClusterClaimList{}
err = f.Client.List(context.TODO(), &clusterClaimList)
if err != nil {
t.Fatalf("Failed to list cluster claims: %v", err)
}
for _, clusterClaim := range clusterClaimList.Items {
t.Logf("ClusterClaim: %s", clusterClaim.Name)
t.Logf("ClusterClaim.Spec.Value: %v", clusterClaim.Spec.Value)

}

// print out logs for compliance-operator deployment
podList := corev1.PodList{}
err = f.Client.List(context.TODO(), &podList, client.InNamespace(f.OperatorNamespace))
if err != nil {
t.Fatalf("Failed to list pods: %v", err)
}
for _, pod := range podList.Items {
// find pod named contains compliance-operator substring
if strings.Contains(pod.Name, "compliance-operator") {
log.Printf("Pod: %s", pod.Name)
log.Printf("Pod.Status: %v", pod.Status)
// print out logs for compliance-operator pod
req := f.KubeClient.CoreV1().Pods(f.OperatorNamespace).GetLogs(pod.Name, &corev1.PodLogOptions{})
log.Printf("Request: %v", req)
reader, err := req.Stream(context.Background())
if err != nil {
t.Fatalf("Failed to get logs: %v", err)
}
buf := make([]byte, 1024)
for {
n, err := reader.Read(buf)
if err != nil {
break
}
log.Printf("Logs: %s", string(buf[:n]))
}

}
}

}

0 comments on commit 2731ca3

Please sign in to comment.