Skip to content

Commit

Permalink
Merge pull request #398 from Vincent056/profile-name
Browse files Browse the repository at this point in the history
Add Profile Name to rule
  • Loading branch information
openshift-merge-bot[bot] authored Nov 9, 2023
2 parents c735a90 + 19e3c82 commit a1ce852
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/apis/compliance/v1alpha1/rule_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const RuleHideTagAnnotationKey = "compliance.openshift.io/hide-tag"
// RuleVariableAnnotationKey store list of xccdf variables used to render the rule
const RuleVariableAnnotationKey = "compliance.openshift.io/rule-variable"

// RuleProfileAnnotationKey is the annotation used to store which profiles are using a particular rule
const RuleProfileAnnotationKey = "compliance.openshift.io/profiles"

const (
CheckTypePlatform = "Platform"
CheckTypeNode = "Node"
Expand Down
19 changes: 19 additions & 0 deletions pkg/profileparser/profileparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ func ParseRulesAndDo(contentDom *xmlquery.Node, stdParser *referenceParser, pb *
var wg sync.WaitGroup
questionsTable := utils.NewOcilQuestionTable(contentDom)
defTable := utils.NewDefHashTable(contentDom)
profileTable := utils.NewProfileTable(contentDom)

allValues := xmlquery.Find(contentDom, "//xccdf-1.2:Value")
valuesList := make(map[string]string)
Expand Down Expand Up @@ -585,6 +586,7 @@ func ParseRulesAndDo(contentDom *xmlquery.Node, stdParser *referenceParser, pb *
rationale := ruleObj.SelectElement("xccdf-1.2:rationale")
warnings := utils.GetWarningsForRule(ruleObj)
severity := ruleObj.SelectAttr("severity")
profiles := utils.GetRuleProfile(ruleObj, profileTable)

fixes := []cmpv1alpha1.FixDefinition{}
foundPlatformMap := make(map[string]bool)
Expand Down Expand Up @@ -640,6 +642,23 @@ func ParseRulesAndDo(contentDom *xmlquery.Node, stdParser *referenceParser, pb *
annotations[cmpv1alpha1.RuleHideTagAnnotationKey] = "true"
}

profileList := []string{}

// add profiles to annotations
if len(profiles) > 0 {
for _, profile := range profiles {
profileID := profile.SelectAttr("id")
if profileID == "" {
log.Info("no id in profile")
continue
}
profileList = append(profileList, GetPrefixedName(pb.Name, xccdf.GetProfileNameFromID(profileID)))
}
if len(profileList) > 0 {
annotations[cmpv1alpha1.RuleProfileAnnotationKey] = strings.Join(profileList, ",")
}
}

p := cmpv1alpha1.Rule{
TypeMeta: metav1.TypeMeta{
Kind: "Rule",
Expand Down
20 changes: 20 additions & 0 deletions pkg/utils/parse_arf_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ func newRuleHashTable(dsDom *xmlquery.Node) NodeByIdHashTable {
func NewOcilQuestionTable(dsDom *xmlquery.Node) NodeByIdHashTable {
return newHashTableFromRootAndQuery(dsDom, "//ds:component/ocil:ocil", "//ocil:boolean_question")
}

func NewProfileTable(dsDom *xmlquery.Node) NodeByIdHashTable {
return newHashTableFromRootAndQuery(dsDom, "//ds:component/xccdf-1.2:Benchmark", "//xccdf-1.2:Profile")
}

func newStateHashTable(dsDom *xmlquery.Node) NodeByIdHashTable {
return newHashTableFromRootAndQuery(dsDom, "//ds:component/oval-def:oval_definitions/oval-def:states", "*")
}
Expand Down Expand Up @@ -308,6 +313,21 @@ func findAllVariablesFromObject(node *xmlquery.Node) ([]string, bool) {
}
}

func GetRuleProfile(rule *xmlquery.Node, profileTable NodeByIdHashTable) NodeByIdHashTable {
// loop through profile table to find which profile uses the rule
ruleProfile := make(NodeByIdHashTable)
for _, profile := range profileTable {
for _, selectRule := range profile.SelectElements("//xccdf-1.2:select") {
if selectRule.SelectAttr("idref") == rule.SelectAttr("id") {
if selectRule.SelectAttr("selected") == "true" {
ruleProfile[profile.SelectAttr("id")] = profile
}
}
}
}
return ruleProfile
}

func GetRuleOvalTest(rule *xmlquery.Node, defTable NodeByIdHashTable) NodeByIdHashTable {
var ovalRefEl *xmlquery.Node
testList := make(map[string]*xmlquery.Node)
Expand Down
11 changes: 11 additions & 0 deletions tests/e2e/framework/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,17 @@ func (f *Framework) WaitForScanSettingBindingStatus(namespace, name string, targ
return nil
}

func (f *Framework) AssertProfileInRuleAnnotation(r *compv1alpha1.Rule, expectedProfileId string) bool {
if r.Annotations == nil {
return false
}
profileIds := r.Annotations[compv1alpha1.RuleProfileAnnotationKey]
if profileIds == "" {
return false
}
return strings.Contains(profileIds, expectedProfileId)
}

// waitForScanStatus will poll until the compliancescan that we're lookingfor reaches a certain status, or until
// a timeout is reached.
func (f *Framework) WaitForSuiteScansStatus(namespace, name string, targetStatus compv1alpha1.ComplianceScanStatusPhase, targetComplianceStatus compv1alpha1.ComplianceScanStatusResult) error {
Expand Down
30 changes: 30 additions & 0 deletions tests/e2e/parallel/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2827,3 +2827,33 @@ func TestResultServerHTTPVersion(t *testing.T) {
}
}
}

func TestRuleHasProfileAnnotation(t *testing.T) {
t.Parallel()
f := framework.Global
const requiredRule = "ocp4-file-groupowner-worker-kubeconfig"
const expectedRuleProfileAnnotation = "ocp4-pci-dss-node,ocp4-moderate-node,ocp4-stig-node,ocp4-nerc-cip-node,ocp4-cis-node,ocp4-high-node"
err, found := f.DoesRuleExist(f.OperatorNamespace, requiredRule)
if err != nil {
t.Fatal(err)
} else if !found {
t.Fatalf("Expected rule %s not found", requiredRule)
}

// Check if requiredRule has the correct profile annotation
rule := &compv1alpha1.Rule{}
err = f.Client.Get(context.TODO(), types.NamespacedName{
Name: requiredRule,
Namespace: f.OperatorNamespace,
}, rule)
if err != nil {
t.Fatal(err)
}
expectedProfiles := strings.Split(expectedRuleProfileAnnotation, ",")
for _, profileName := range expectedProfiles {
if !f.AssertProfileInRuleAnnotation(rule, profileName) {
t.Fatalf("expected to find profile %s in rule %s", profileName, rule.Name)
}
}

}

0 comments on commit a1ce852

Please sign in to comment.