Skip to content

Commit

Permalink
Merge pull request #6813 from JAORMX/ocp4-multiple-versions
Browse files Browse the repository at this point in the history
OCP4: Address flowschema version change by handling different OCP versions
  • Loading branch information
yuumasato committed Apr 12, 2021
2 parents 2a33320 + 297cf12 commit 8900e4a
Show file tree
Hide file tree
Showing 18 changed files with 215 additions and 12 deletions.
Expand Up @@ -26,6 +26,10 @@ rationale: |-
identifiers:
cce@ocp4: CCE-83522-3

platforms:
- ocp4.8
- ocp4.9
- ocp4.10

severity: medium

Expand All @@ -43,13 +47,16 @@ ocil: |-
warnings:
- general: |-
{{{ openshift_cluster_setting("/apis/flowcontrol.apiserver.k8s.io/v1alpha1/flowschemas/catch-all") | indent(4) }}}
{{{ openshift_cluster_setting("/apis/flowcontrol.apiserver.k8s.io/v1beta1/flowschemas/catch-all") | indent(4) }}}
- dependency: |-
Note that this is only applicable in OpenShift Container Platform version 4.8
and higher
template:
name: yamlfile_value
vars:
ocp_data: "true"
filepath: "/apis/flowcontrol.apiserver.k8s.io/v1alpha1/flowschemas/catch-all"
filepath: "/apis/flowcontrol.apiserver.k8s.io/v1beta1/flowschemas/catch-all"
yamlpath: '.spec.rules[0].subjects[:].group["name"]'
check_existence: "at_least_one_exists"
entity_check: "at least one"
Expand Down
@@ -0,0 +1,2 @@
---
default_result: NOT-APPLICABLE
@@ -0,0 +1,2 @@
---
default_result: NOT-APPLICABLE
@@ -0,0 +1,2 @@
---
default_result: PASS
@@ -0,0 +1,2 @@
---
default_result: PASS
@@ -0,0 +1,67 @@
documentation_complete: true

prodtype: ocp4

title: 'Ensure catch-all FlowSchema object for API Priority and Fairness Exists (v1alpha1)'

description: |-
Using <tt>APIPriorityAndFairness</tt> feature provides a fine-grained way
to control the behaviour of the Kubernetes API server in an overload
situation. The well-known FlowSchema <tt>catch-all</tt> should be available
to make sure that every request gets some kind of classification. By default,
the <tt>catch-all</tt> priority level only allows one concurrency share and
does not queue requests. To inspect all the <tt>FlowSchema</tt> objects, run:
<pre>oc get flowschema</pre>
To inspect the well-known <tt>catch-all</tt> object, run the following:
<pre>oc describe flowschema catch-all</pre>
rationale: |-
The <tt>FlowSchema</tt> API objects enforce a limit on the
number of events that the API Server will accept in a given time slice
In a large multi-tenant cluster, there might be a small percentage of
misbehaving tenants which could have a significant impact on the
performance of the cluster overall. It is recommended to limit the rate
of events that the API Server will accept.
identifiers:
cce@ocp4: CCE-84002-5


platforms:
- ocp4.6
- ocp4.7

severity: medium

references:
cis@ocp4: 1.2.10

ocil_clause: 'A FlowSchema object <tt>catch-all</tt> exists'

ocil: |-
Run the following commands:
<pre>oc get flowschema</pre>
and inspect the FlowSchema objects. Make sure that at least the <tt>catch-all</tt>
object exists by calling:
<pre>oc describe flowschema catch-all</pre>
warnings:
- general: |-
{{{ openshift_cluster_setting("/apis/flowcontrol.apiserver.k8s.io/v1alpha1/flowschemas/catch-all") | indent(4) }}}
- dependency: |-
Note that this rule is only applicable in OpenShift Container Platform
versions 4.7 and below.
template:
name: yamlfile_value
vars:
ocp_data: "true"
filepath: "/apis/flowcontrol.apiserver.k8s.io/v1alpha1/flowschemas/catch-all"
yamlpath: '.spec.rules[0].subjects[:].group["name"]'
check_existence: "at_least_one_exists"
entity_check: "at least one"
values:
- value: "system:authenticated"
operation: "pattern match"
check_existence: "at_least_one_exists"
entity_check: "at least one"
@@ -0,0 +1,2 @@
---
default_result: NOT-APPLICABLE
@@ -0,0 +1,2 @@
---
default_result: PASS
@@ -0,0 +1,2 @@
---
default_result: PASS
@@ -0,0 +1,2 @@
---
default_result: NOT-APPLICABLE
@@ -0,0 +1,2 @@
---
default_result: NOT-APPLICABLE
27 changes: 26 additions & 1 deletion ocp4/product.yml
Expand Up @@ -22,5 +22,30 @@ cpes:
title: "Red Hat OpenShift Container Platform 4 Node"
check_id: installed_app_is_ocp4_node

- ocp4.6:
name: "cpe:/a:redhat:openshift_container_platform:4.6"
title: "Red Hat OpenShift Container Platform 4.6"
check_id: installed_app_is_ocp4_6

- ocp4.7:
name: "cpe:/a:redhat:openshift_container_platform:4.7"
title: "Red Hat OpenShift Container Platform 4.7"
check_id: installed_app_is_ocp4_7

- ocp4.8:
name: "cpe:/a:redhat:openshift_container_platform:4.8"
title: "Red Hat OpenShift Container Platform 4.8"
check_id: installed_app_is_ocp4_8

- ocp4.9:
name: "cpe:/a:redhat:openshift_container_platform:4.9"
title: "Red Hat OpenShift Container Platform 4.9"
check_id: installed_app_is_ocp4_9

- ocp4.10:
name: "cpe:/a:redhat:openshift_container_platform:4.10"
title: "Red Hat OpenShift Container Platform 4.10"
check_id: installed_app_is_ocp4_10

# Requirement string, see: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#requirements-parsing
# requires: "openscap>=1.3.3"
# requires: "openscap>=1.3.4"
1 change: 1 addition & 0 deletions ocp4/profiles/cis.profile
Expand Up @@ -51,6 +51,7 @@ selections:
# 1.2.10 Ensure that the admission control plugin EventRateLimit is set
- api_server_api_priority_gate_enabled
- api_server_api_priority_flowschema_catch_all
- api_server_api_priority_v1alpha1_flowschema_catch_all
# 1.2.11 Ensure that the admission control plugin AlwaysAdmit is not set
- api_server_admission_control_plugin_AlwaysAdmit
# 1.2.12 Ensure that the admission control plugin AlwaysPullImages is set
Expand Down
31 changes: 31 additions & 0 deletions shared/checks/oval/installed_app_is_ocp4.xml
@@ -1,4 +1,5 @@
<def-group>
<!-- General check for OpenShift Container Platform 4 -->
<definition class="inventory" id="installed_app_is_ocp4" version="1">
<metadata>
<title>Red Hat OpenShift Container Platform</title>
Expand Down Expand Up @@ -41,4 +42,34 @@
<field name="#" datatype="string" operation="pattern match">4\..*</field>
</ind:value>
</ind:yamlfilecontent_state>

{{% for minorversion in range(6, 11) %}}
<!-- Check for OpenShift Container Platform 4.{{{ minorversion }}} -->
<definition class="inventory" id="installed_app_is_ocp4_{{{ minorversion }}}" version="1">
<metadata>
<title>Red Hat OpenShift Container Platform 4.{{{ minorversion }}}</title>
<affected family="unix">
<platform>Red Hat OpenShift Container Platform 4.{{{ minorversion }}}</platform>
</affected>
<reference ref_id="cpe:/a:redhat:openshift_container_platform:4.{{{ minorversion }}}" source="CPE" />
<description>The application installed installed on the system is OpenShift version 4.{{{ minorversion }}}.</description>
</metadata>
<criteria operator="AND">
<criterion comment="cluster is OpenShift 4.{{{ minorversion }}}" test_ref="test_ocp4_{{{ minorversion }}}" />
<criterion comment="Make sure OCP4 clusteroperators file is present" test_ref="test_file_for_ocp4"/>
</criteria>
</definition>

<ind:yamlfilecontent_test id="test_ocp4_{{{ minorversion }}}" check="at least one" comment="Find one match" version="1">
<ind:object object_ref="object_ocp4"/>
<ind:state state_ref="state_ocp4_{{{ minorversion }}}"/>
</ind:yamlfilecontent_test>

<ind:yamlfilecontent_state id="state_ocp4_{{{ minorversion }}}" version="1">
<ind:value datatype="record">
<field name="#" datatype="string" operation="pattern match">4\.{{{ minorversion }}}.*</field>
</ind:value>
</ind:yamlfilecontent_state>

{{% endfor %}}
</def-group>
1 change: 0 additions & 1 deletion shared/references/cce-redhat-avail.txt
Expand Up @@ -396,7 +396,6 @@ CCE-83998-5
CCE-83999-3
CCE-84000-9
CCE-84001-7
CCE-84002-5
CCE-84003-3
CCE-84004-1
CCE-84005-8
Expand Down
1 change: 1 addition & 0 deletions tests/ocp4e2e/e2e_test.go
Expand Up @@ -13,6 +13,7 @@ func TestE2e(t *testing.T) {
ctx.assertProfile(t)
ctx.assertContentImage(t)
ctx.assertKubeClient(t)
ctx.assertVersion(t)
})

t.Run("Operator setup", func(t *testing.T) {
Expand Down
70 changes: 62 additions & 8 deletions tests/ocp4e2e/helpers.go
Expand Up @@ -11,6 +11,7 @@ import (
"os"
"os/exec"
"path"
"regexp"
"strings"
"sync"
"testing"
Expand Down Expand Up @@ -83,6 +84,7 @@ type e2econtext struct {
product string
resourcespath string
benchmarkRoot string
version string
installOperator bool
dynclient dynclient.Client
kubecfg *rest.Config
Expand Down Expand Up @@ -213,6 +215,23 @@ func (ctx *e2econtext) assertKubeClient(t *testing.T) {
}
}

func (ctx *e2econtext) assertVersion(t *testing.T) {
// TODO(jaosorior): Make this pluggable (we might want to use
// kubectl instead in the future)
rawversion, err := exec.Command("oc", "version").Output()
if err != nil {
t.Fatalf("E2E-FAILURE: failed get cluster version: %s", err)
}

r := regexp.MustCompile(`Server Version: ([1-9]\.[0-9]+)\..*`)
matches := r.FindSubmatch(rawversion)

if len(matches) < 2 {
t.Fatalf("E2E-FAILURE: Couldn't get server version from output: %s", rawversion)
}
ctx.version = string(matches[1])
}

func (ctx *e2econtext) resetClientMappings() {
ctx.restMapper.Reset()
}
Expand Down Expand Up @@ -701,9 +720,8 @@ func (ctx *e2econtext) verifyRule(t *testing.T, result cmpv1alpha1.ComplianceChe
return "", err
}
rulePath := strings.Trim(string(rulePathBytes), "\n")
testFilePath := path.Join(rulePath, ruleTestFilePath)

buf, err := ioutil.ReadFile(testFilePath)
buf, err := ctx.getTestDefinition(rulePath)
if err != nil {
if os.IsNotExist(err) {
// There's no test file, so no need to verify
Expand All @@ -717,12 +735,7 @@ func (ctx *e2econtext) verifyRule(t *testing.T, result cmpv1alpha1.ComplianceChe
return "", err
}

remPath := path.Join(rulePath, ruleManualRemediationFilePath)
_, err = os.Stat(remPath)
if os.IsNotExist(err) {
// We reset the path to return in case there isn't a remediation
remPath = ""
}
remPath := ctx.getManualRemediationPath(rulePath)

// Initial run
if !afterRemediations {
Expand All @@ -748,6 +761,47 @@ func (ctx *e2econtext) verifyRule(t *testing.T, result cmpv1alpha1.ComplianceChe
return remPath, nil
}

// getTestDefinition attempts to use a versioned test (<version>.yml)
// definition, if it fails it'll try to use the standard test
// definition (e2e.yml).
func (ctx *e2econtext) getTestDefinition(rulePath string) ([]byte, error) {
versionedManifest := fmt.Sprintf("%s.yml", ctx.version)
versionedRuleTestFilePath := path.Join(ruleTestDir, versionedManifest)
vbuf, verr := ioutil.ReadFile(versionedRuleTestFilePath)

if verr == nil {
return vbuf, nil
}

if verr != nil && !os.IsNotExist(verr) {
return nil, verr
}

testFilePath := path.Join(rulePath, ruleTestFilePath)
return ioutil.ReadFile(testFilePath)
}

// getManualRemediationPath attempts to get a versioned remediation
// (<version>-remediation.sh) path, if it fails it'll try to use the
// standard test remediation path (e2e-remediation.sh).
// If both instances are not present, it'll return an empty string.
func (ctx *e2econtext) getManualRemediationPath(rulePath string) string {
versionedRemediation := fmt.Sprintf("%s-remediation.sh", ctx.version)
versionedRemediationPath := path.Join(ruleTestDir, versionedRemediation)
_, err := os.Stat(versionedRemediationPath)
if err == nil {
return versionedRemediationPath
}

remPath := path.Join(rulePath, ruleManualRemediationFilePath)
_, err = os.Stat(remPath)
if err == nil {
// We reset the path to return in case there isn't a remediation
return remPath
}
return ""
}

func verifyRuleResult(foundResult cmpv1alpha1.ComplianceCheckResult, expectedResult interface{}, testDef RuleTest, ruleName string) error {
if matches, err := matchFoundResultToExpectation(foundResult, expectedResult); !matches || err != nil {
if err != nil {
Expand Down

0 comments on commit 8900e4a

Please sign in to comment.