Skip to content

Commit

Permalink
Fix GUID for cross bundle scan
Browse files Browse the repository at this point in the history
Added check to make sure the scan we are going to label for the profile GID come from the actully profile being used for the scan, because two profile can potentially have the same name, we want to take bundle name into consideration
  • Loading branch information
Vincent056 committed May 6, 2024
1 parent 67cac7e commit 9e31bd1
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 84 deletions.
3 changes: 2 additions & 1 deletion cmd/manager/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import (
"github.com/ComplianceAsCode/compliance-operator/pkg/controller/common"
ctrlMetrics "github.com/ComplianceAsCode/compliance-operator/pkg/controller/metrics"
"github.com/ComplianceAsCode/compliance-operator/pkg/utils"
"github.com/ComplianceAsCode/compliance-operator/pkg/xccdf"
"github.com/ComplianceAsCode/compliance-operator/version"
)

Expand Down Expand Up @@ -515,7 +516,7 @@ func ensureDefaultProfileBundles(
},
Spec: compv1alpha1.ProfileBundleSpec{
ContentImage: pbimg,
ContentFile: fmt.Sprintf("ssg-%s-ds.xml", prod),
ContentFile: xccdf.GetContentFileName(prod),
},
}
setupLog.Info("Ensuring ProfileBundle is available",
Expand Down
6 changes: 4 additions & 2 deletions pkg/controller/compliancesuite/compliancesuite_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,10 @@ func launchScanForSuite(r *ReconcileComplianceSuite, suite *compv1alpha1.Complia
}
for _, profile := range profiles.Items {
if profile.ID == scanProfile {
profileUniqueID = profile.GetAnnotations()[compv1alpha1.ProfileGuidAnnotation]
break
if scanWrap.Name == utils.GetScanNameFromProfile(profile.Name, scanWrap.NodeSelector) {
profileUniqueID = profile.GetAnnotations()[compv1alpha1.ProfileGuidAnnotation]
break
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/utils/nodeutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ func GetFirstNodeRole(nodeSelector map[string]string) string {
return ""
}

func GetScanNameFromProfile(profileName string, nodeSelector map[string]string) string {
role := GetFirstNodeRole(nodeSelector)
if role == "" {
return profileName
}

return fmt.Sprintf("%s-%s", profileName, role)
}

func GetNodeRoles(nodeSelector map[string]string) []string {
roles := []string{}
if nodeSelector == nil {
Expand Down
11 changes: 9 additions & 2 deletions pkg/xccdf/tailoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ const (
varIDPrefix string = "xccdf_org.ssgproject.content_value_"
// XCCDFNamespace is the XCCDF namespace of this project. Per the XCCDF
// specification, this assiciates the content with the author
XCCDFNamespace string = "compliance.openshift.io"
XCCDFURI string = "http://checklists.nist.gov/xccdf/1.2"
XCCDFNamespace string = "compliance.openshift.io"
XCCDFURI string = "http://checklists.nist.gov/xccdf/1.2"
ContentFileNamePrefix string = "ssg-"
ContentFileNameSuffix string = "-ds.xml"
)

type TailoringElement struct {
Expand Down Expand Up @@ -76,6 +78,11 @@ type SetValueElement struct {
Value string `xml:",chardata"`
}

// GetContentFileName gets the file name for a profile bundle
func GetContentFileName(productName string) string {
return fmt.Sprintf("%s%s%s", ContentFileNamePrefix, productName, ContentFileNameSuffix)
}

// GetXCCDFProfileID gets a profile xccdf ID from the TailoredProfile object
func GetXCCDFProfileID(tp *cmpv1alpha1.TailoredProfile) string {
return fmt.Sprintf("xccdf_%s_profile_%s", XCCDFNamespace, tp.Name)
Expand Down
22 changes: 18 additions & 4 deletions tests/e2e/framework/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -1049,16 +1049,30 @@ func (f *Framework) AssertScanIsCompliant(name, namespace string) error {
return nil
}

// AssertScanUUIDMatches checks if the scan has the expected UUID
func (f *Framework) AssertScanUUIDMatches(name, namespace, expectedUUID string) error {
// AssertScanGUIDMatches checks if the scan has the expected GUID
func (f *Framework) AssertScanGUIDMatches(name, namespace, expectedGUID string) error {
cs := &compv1alpha1.ComplianceScan{}
defer f.logContainerOutput(namespace, name)
err := f.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: namespace}, cs)
if err != nil {
return err
}
if cs.Labels[compv1alpha1.ProfileGuidLabel] != expectedUUID {
return fmt.Errorf("Expected UUID %s for scan %s, got %s", expectedUUID, name, cs.Labels[compv1alpha1.ProfileGuidLabel])
if cs.Labels[compv1alpha1.ProfileGuidLabel] != expectedGUID {
return fmt.Errorf("Expected GUID %s for scan %s, got %s", expectedGUID, name, cs.Labels[compv1alpha1.ProfileGuidLabel])
}
return nil
}

// AssertProfileGUIDMatches checks if the profile has the expected GUID
func (f *Framework) AssertProfileGUIDMatches(name, namespace, expectedGUID string) error {
profile := &compv1alpha1.Profile{}
defer f.logContainerOutput(namespace, name)
err := f.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: namespace}, profile)
if err != nil {
return err
}
if profile.Annotations[compv1alpha1.ProfileGuidAnnotation] != expectedGUID {
return fmt.Errorf("Expected GUID %s for profile %s, got %s", expectedGUID, name, profile.Annotations[compv1alpha1.ProfileGuidAnnotation])
}
return nil
}
Expand Down
75 changes: 0 additions & 75 deletions tests/e2e/parallel/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3124,78 +3124,3 @@ func TestScanCleansUpComplianceCheckResults(t *testing.T) {
t.Fatal(err)
}
}

func TestScanHasProfileUUID(t *testing.T) {
t.Parallel()
f := framework.Global
bindingName := framework.GetObjNameFromTest(t)
tpName := "test-scan-have-profile-uuid-tp"
// This is the profileUUID for the redhat_openshift_container_platform_4.1 product and xccdf_org.ssgproject.content_profile_moderate profile
const profileUUID = "d625badc-92a1-5438-afd7-19526c26b03c"
const profileUUIDTP = "d1359d86-c04f-5aa7-bcbc-e75a40844734"
// check if the profileUUID is correct in ocp4-moderate profile
profile := &compv1alpha1.Profile{}
err := f.Client.Get(context.TODO(), types.NamespacedName{Name: "ocp4-moderate", Namespace: f.OperatorNamespace}, profile)
if err != nil {
t.Fatal(err)
}
if profile.Annotations[compv1alpha1.ProfileGuidAnnotation] != profileUUID {
t.Fatalf("expected profileUUID %s, got %s", profileUUID, profile.Annotations[compv1alpha1.ProfileGuidAnnotation])
}

tp := &compv1alpha1.TailoredProfile{
ObjectMeta: metav1.ObjectMeta{
Name: tpName,
Namespace: f.OperatorNamespace,
},
Spec: compv1alpha1.TailoredProfileSpec{
Title: "TestScanHaveProfileUUID",
Description: "TestScanHaveProfileUUID",
Extends: "ocp4-moderate",
},
}

createTPErr := f.Client.Create(context.TODO(), tp, nil)
if createTPErr != nil {
t.Fatal(createTPErr)
}
defer f.Client.Delete(context.TODO(), tp)
scanSettingBinding := compv1alpha1.ScanSettingBinding{
ObjectMeta: metav1.ObjectMeta{
Name: bindingName,
Namespace: f.OperatorNamespace,
},
Profiles: []compv1alpha1.NamedObjectReference{
{
Name: tpName,
Kind: "TailoredProfile",
APIGroup: "compliance.openshift.io/v1alpha1",
},
{
Name: "ocp4-moderate",
Kind: "Profile",
APIGroup: "compliance.openshift.io/v1alpha1",
},
},
SettingsRef: &compv1alpha1.NamedObjectReference{
Name: "default",
Kind: "ScanSetting",
APIGroup: "compliance.openshift.io/v1alpha1",
},
}
// use Context's create helper to create the object and add a cleanup function for the new object
err = f.Client.Create(context.TODO(), &scanSettingBinding, nil)
if err != nil {
t.Fatal(err)
}
defer f.Client.Delete(context.TODO(), &scanSettingBinding)
if err := f.WaitForSuiteScansStatus(f.OperatorNamespace, bindingName, compv1alpha1.PhaseDone, compv1alpha1.ResultNonCompliant); err != nil {
t.Fatal(err)
}

// check if the profileUUID is correct in the scan's label
f.AssertScanUUIDMatches("ocp4-moderate", f.OperatorNamespace, profileUUID)
// check if the profileUUID is correct in the tailored profile's label
f.AssertScanUUIDMatches(tpName, f.OperatorNamespace, profileUUIDTP)

}
83 changes: 83 additions & 0 deletions tests/e2e/serial/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,89 @@ func TestSuiteScan(t *testing.T) {

}

func TestScanHasProfileGUID(t *testing.T) {
f := framework.Global
bindingName := framework.GetObjNameFromTest(t)
tpName := "test-scan-have-profile-guid-tp"
// This is the profileGUID for the redhat_openshift_container_platform_4.1 product and xccdf_org.ssgproject.content_profile_moderate profile
const profileGUIDOCPModerate = "d625badc-92a1-5438-afd7-19526c26b03c"
const profileGUIDTP = "d1359d86-c04f-5aa7-bcbc-e75a40844734"
const profileGUIDRHCOSModerate = "eceb9af0-17d4-5c59-9b17-07cfd22a3ba1"
const profileGUIDOCPCIS = "a230315d-3e4a-5b58-b00f-f96f1553e036"

f.AssertProfileGUIDMatches("ocp4-moderate", f.OperatorNamespace, profileGUIDOCPModerate)
f.AssertProfileGUIDMatches("rhcos4-moderate", f.OperatorNamespace, profileGUIDRHCOSModerate)
f.AssertProfileGUIDMatches("ocp4-cis", f.OperatorNamespace, profileGUIDOCPCIS)
tp := &compv1alpha1.TailoredProfile{
ObjectMeta: metav1.ObjectMeta{
Name: tpName,
Namespace: f.OperatorNamespace,
},
Spec: compv1alpha1.TailoredProfileSpec{
Title: "TestScanHaveProfileGUID",
Description: "TestScanHaveProfileGUID",
Extends: "ocp4-moderate",
},
}

createTPErr := f.Client.Create(context.TODO(), tp, nil)
if createTPErr != nil {
t.Fatal(createTPErr)
}
defer f.Client.Delete(context.TODO(), tp)
scanSettingBinding := compv1alpha1.ScanSettingBinding{
ObjectMeta: metav1.ObjectMeta{
Name: bindingName,
Namespace: f.OperatorNamespace,
},
Profiles: []compv1alpha1.NamedObjectReference{
{
Name: "ocp4-cis",
Kind: "Profile",
APIGroup: "compliance.openshift.io/v1alpha1",
},
{
Name: tpName,
Kind: "TailoredProfile",
APIGroup: "compliance.openshift.io/v1alpha1",
},
{
Name: "ocp4-moderate",
Kind: "Profile",
APIGroup: "compliance.openshift.io/v1alpha1",
},
{
Name: "rhcos4-moderate",
Kind: "Profile",
APIGroup: "compliance.openshift.io/v1alpha1",
},
},
SettingsRef: &compv1alpha1.NamedObjectReference{
Name: "default",
Kind: "ScanSetting",
APIGroup: "compliance.openshift.io/v1alpha1",
},
}
// use Context's create helper to create the object and add a cleanup function for the new object
err := f.Client.Create(context.TODO(), &scanSettingBinding, nil)
if err != nil {
t.Fatal(err)
}
defer f.Client.Delete(context.TODO(), &scanSettingBinding)
if err := f.WaitForSuiteScansStatus(f.OperatorNamespace, bindingName, compv1alpha1.PhaseDone, compv1alpha1.ResultNonCompliant); err != nil {
t.Fatal(err)
}

// check if the profileGUID is correct in the scan's label
f.AssertScanGUIDMatches("ocp4-moderate", f.OperatorNamespace, profileGUIDOCPModerate)
f.AssertScanGUIDMatches("rhcos4-moderate", f.OperatorNamespace, profileGUIDRHCOSModerate)
f.AssertScanGUIDMatches("ocp4-cis-node-master", f.OperatorNamespace, profileGUIDOCPCIS)
f.AssertScanGUIDMatches("ocp4-cis-node-worker", f.OperatorNamespace, profileGUIDOCPCIS)
// check if the profileGUID is correct in the tailored profile's label
f.AssertScanGUIDMatches(tpName, f.OperatorNamespace, profileGUIDTP)

}

func TestMixProductScan(t *testing.T) {
f := framework.Global

Expand Down

0 comments on commit 9e31bd1

Please sign in to comment.