Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions cmd/manager/scap.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,30 +539,46 @@ func fetch(ctx context.Context, streamDispatcher streamerDispatcherFn, rfClients
return results, warnings, nil
}

func filter(ctx context.Context, rawobj []byte, filter string) ([]byte, error) {
fltr, fltrErr := gojq.Parse(filter)
if fltrErr != nil {
return nil, fmt.Errorf("could not create filter '%s': %w", filter, fltrErr)
}
obj := map[string]interface{}{}
unmarshallErr := json.Unmarshal(rawobj, &obj)
if unmarshallErr != nil {
return nil, fmt.Errorf("Error unmarshalling json: %w", unmarshallErr)
func execFilter(ctx context.Context, obj map[string]interface{}, filterExpr string) (interface{}, gojq.Iter, error) {
fltr, err := gojq.Parse(filterExpr)
if err != nil {
return nil, nil, fmt.Errorf("could not create filter '%s': %w", filterExpr, err)
}
iter := fltr.RunWithContext(ctx, obj)
v, ok := iter.Next()
if !ok {
DBG("No result from filter. This is an issue and an error will be returned.")
return nil, fmt.Errorf("couldn't get filtered object")
return nil, nil, fmt.Errorf("couldn't get filtered object")
}
if err, ok := v.(error); ok {
DBG("Error while filtering: %s", err)
// gojq may return a diverse set of internal errors caused by null values.
// These errors are happen when a piped filter ends up acting on a null value.
if strings.HasSuffix(err.Error(), ": null") {
return nil, fmt.Errorf("Skipping empty filter result from '%s': %w", filter, NullValErr)
return nil, nil, err
}
return v, iter, nil
}

func filter(ctx context.Context, rawobj []byte, filterExpr string) ([]byte, error) {
obj := map[string]interface{}{}
unmarshallErr := json.Unmarshal(rawobj, &obj)
if unmarshallErr != nil {
return nil, fmt.Errorf("Error unmarshalling json: %w", unmarshallErr)
}

v, iter, execErr := execFilter(ctx, obj, filterExpr)
if execErr != nil {
DBG("Error while filtering: %s", execErr)
if strings.HasSuffix(execErr.Error(), ": null") {
// Retry with optional iteration to gracefully skip null values
// instead of failing the entire filter.
optFilter := strings.ReplaceAll(filterExpr, "[]", "[]?")
if optFilter != filterExpr {
DBG("Retrying with optional iteration: '%s'", optFilter)
v, iter, execErr = execFilter(ctx, obj, optFilter)
}
if execErr != nil {
return nil, fmt.Errorf("Skipping empty filter result from '%s': %w", filterExpr, NullValErr)
}
} else {
return nil, execErr
}
return nil, err
}

var out []byte
Expand Down Expand Up @@ -591,7 +607,7 @@ func filter(ctx context.Context, rawobj []byte, filter string) ([]byte, error) {
_, isNotEOF := iter.Next()
if isNotEOF {
DBG("No more results should have come from the filter. This is an issue with the content.")
return out, fmt.Errorf("Skipping extra results from filter '%s': %w", filter, MoreThanOneObjErr)
return out, fmt.Errorf("Skipping extra results from filter '%s': %w", filterExpr, MoreThanOneObjErr)
}
return out, nil
}
Expand Down
37 changes: 34 additions & 3 deletions cmd/manager/scap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,40 @@ var _ = Describe("Testing filtering", func() {
rawmc, readErr = io.ReadAll(nsFile)
Expect(readErr).To(BeNil())
})
It("skips filter piping errors", func() {
_, filterErr := filter(context.TODO(), rawmc, `[.items[] | select(.metadata.name | test("^rendered-worker-[0-9a-z]+$|^rendered-master-[0-9a-z]+$"))] | map(.spec.fips == true)`)
Expect(filterErr).Should(MatchError(NullValErr))
It("retries with optional iteration on null items", func() {
filteredOut, filterErr := filter(context.TODO(), rawmc, `[.items[] | select(.metadata.name | test("^rendered-worker-[0-9a-z]+$|^rendered-master-[0-9a-z]+$"))] | map(.spec.fips == true)`)
Expect(filterErr).To(BeNil())
Expect(string(filteredOut)).To(Equal("[]"))
})
})
Context("PrometheusRule with empty spec", func() {
var rawpr []byte
BeforeEach(func() {
prFile, err := os.Open("../../tests/data/prometheusrules_mixed.json")
Expect(err).To(BeNil())
var readErr error
rawpr, readErr = io.ReadAll(prFile)
Expect(readErr).To(BeNil())
})
It("retries with optional iteration and preserves valid data", func() {
filteredOut, filterErr := filter(context.TODO(), rawpr,
`[.items[].spec.groups[].rules[].expr]`)
Expect(filterErr).To(BeNil())
var exprArr []interface{}
unmErr := json.Unmarshal(filteredOut, &exprArr)
Expect(unmErr).To(BeNil())
Expect(exprArr).To(HaveLen(1))
Expect(exprArr[0]).To(Equal("apiserver_audit_error_total / apiserver_audit_event_total > 0"))
})
It("succeeds directly with optional iterator", func() {
filteredOut, filterErr := filter(context.TODO(), rawpr,
`[.items[]?.spec.groups[]?.rules[]?.expr]`)
Expect(filterErr).To(BeNil())
var exprArr []interface{}
unmErr := json.Unmarshal(filteredOut, &exprArr)
Expect(unmErr).To(BeNil())
Expect(exprArr).To(HaveLen(1))
Expect(exprArr[0]).To(Equal("apiserver_audit_error_total / apiserver_audit_event_total > 0"))
})
})
})
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/cel_content/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13350,7 +13350,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">/apis/monitoring.coreos.com/v1/prometheusrules</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules#5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7</html:code>
file.
Expand Down Expand Up @@ -39366,7 +39366,7 @@ openvswitch
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
$ oc get --all-namespaces prometheusrules -o json | jq '[.items[].spec.groups[].rules[].expr]' | grep apiserver_audit
$ oc get --all-namespaces prometheusrules -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]' | grep apiserver_audit
Make sure that there's a prometheus rule that verifies the apiserver_audit_error_total and
apiserver_audit_event_total metrics and will alert based on an error threshold.
Is it the case that Audit log errors do not generate an alert?
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/deprecated_profile/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13350,7 +13350,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">/apis/monitoring.coreos.com/v1/prometheusrules</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules#5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7</html:code>
file.
Expand Down Expand Up @@ -39366,7 +39366,7 @@ openvswitch
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
$ oc get --all-namespaces prometheusrules -o json | jq '[.items[].spec.groups[].rules[].expr]' | grep apiserver_audit
$ oc get --all-namespaces prometheusrules -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]' | grep apiserver_audit
Make sure that there's a prometheus rule that verifies the apiserver_audit_error_total and
apiserver_audit_event_total metrics and will alert based on an error threshold.
Is it the case that Audit log errors do not generate an alert?
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/from/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15697,7 +15697,7 @@ and make sure it outputs a value.
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
oc get prometheusrules instances -o json | jq '[.items[].spec.groups[].rules[].expr]'
oc get prometheusrules instances -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]'
The output should return a list of URL entries with https:// or tls:// transport.
Is it the case that Audit log errors do not generate an alert?
</ocil:question_text>
Expand Down Expand Up @@ -23385,7 +23385,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">/apis/monitoring.coreos.com/v1/prometheusrules?limit=500</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules?limit=500#0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464</html:code>
file.
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/hide_rule/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12935,7 +12935,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6">/apis/monitoring.coreos.com/v1/prometheusrules?limit=500</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules?limit=500#72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6</html:code>
file.
Expand Down Expand Up @@ -40075,7 +40075,7 @@ and make sure it outputs 0.
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
oc get --all-namespaces prometheusrules -o json | jq '[.items[].spec.groups[].rules[].expr]' | grep apiserver_audit
oc get --all-namespaces prometheusrules -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]' | grep apiserver_audit
Make sure that there's a prometheus rule that verifies the apiserver_audit_error_total and
apiserver_audit_event_total metrics and will alert based on an error threshold.
Is it the case that Audit log errors do not generate an alert?
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/kubelet_default/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13064,7 +13064,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6">/apis/monitoring.coreos.com/v1/prometheusrules?limit=500</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules?limit=500#72e9ad360bb6bdf4ad9e43217cd0ec9cb90e7c3b08d4fbe0edf087ad899e05a6</html:code>
file.
Expand Down Expand Up @@ -40387,7 +40387,7 @@ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
oc get --all-namespaces prometheusrules -o json | jq '[.items[].spec.groups[].rules[].expr]' | grep apiserver_audit
oc get --all-namespaces prometheusrules -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]' | grep apiserver_audit
Make sure that there's a prometheus rule that verifies the apiserver_audit_error_total and
apiserver_audit_event_total metrics and will alert based on an error threshold.
Is it the case that Audit log errors do not generate an alert?
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/kubeletconfig/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15657,7 +15657,7 @@ and make sure it outputs a value.
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
oc get prometheusrules instances -o json | jq '[.items[].spec.groups[].rules[].expr]'
oc get prometheusrules instances -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]'
The output should return a list of URL entries with https:// or tls:// transport.
Is it the case that Audit log errors do not generate an alert?
</ocil:question_text>
Expand Down Expand Up @@ -23297,7 +23297,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">/apis/monitoring.coreos.com/v1/prometheusrules?limit=500</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules?limit=500#0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464</html:code>
file.
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/new_kubeletconfig/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10270,7 +10270,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">/apis/monitoring.coreos.com/v1/prometheusrules</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules#5fd5244e3dcae63319f7e86b918cb8ea6ce1b4124670ccb43750d7a75ca03cb7</html:code>
file.
Expand Down Expand Up @@ -36063,7 +36063,7 @@ and make sure it outputs 0.
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
oc get --all-namespaces prometheusrules -o json | jq '[.items[].spec.groups[].rules[].expr]' | grep apiserver_audit
oc get --all-namespaces prometheusrules -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]' | grep apiserver_audit
Make sure that there's a prometheus rule that verifies the apiserver_audit_error_total and
apiserver_audit_event_total metrics and will alert based on an error threshold.
Is it the case that Audit log errors do not generate an alert?
Expand Down
4 changes: 2 additions & 2 deletions images/testcontent/to/ssg-ocp4-ds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15697,7 +15697,7 @@ and make sure it outputs a value.
</ocil:boolean_question>
<ocil:boolean_question id="ocil:ssg-audit_error_alert_exists_question:question:1">
<ocil:question_text>Run the following command:
oc get prometheusrules instances -o json | jq '[.items[].spec.groups[].rules[].expr]'
oc get prometheusrules instances -o json | jq '[.items[]?.spec.groups[]?.rules[]?.expr]'
The output should return a list of URL entries with https:// or tls:// transport.
Is it the case that Audit log errors do not generate an alert?
</ocil:question_text>
Expand Down Expand Up @@ -23386,7 +23386,7 @@ For more information, consult the
Therefore, you need to use a tool that can query the OCP API, retrieve the following:
<html:ul><html:li><html:code class="ocp-api-endpoint" id="0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">/apis/monitoring.coreos.com/v1/prometheusrules?limit=500</html:code>
API endpoint, filter with with the <html:code>jq</html:code> utility using the following filter
<html:code class="ocp-api-filter" id="filter-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">[.items[].spec.groups[].rules[].expr]</html:code>
<html:code class="ocp-api-filter" id="filter-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464">[.items[]?.spec.groups[]?.rules[]?.expr]</html:code>
and persist it to the local
<html:code class="ocp-dump-location" id="dump-0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464"><xccdf-1.2:sub idref="xccdf_org.ssgproject.content_value_ocp_data_root" use="legacy"/>/apis/monitoring.coreos.com/v1/prometheusrules?limit=500#0fd94c224732cf855db0ac2a1e214959fdf670d9066fb8ae5485ec5ab748f464</html:code>
file.
Expand Down
Loading
Loading