Skip to content
Merged
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
16 changes: 7 additions & 9 deletions .github/workflows/check-crd-compatibility.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,17 @@ jobs:

- name: Run crdify for platform operator
run: |
set -e
set -euo pipefail
old_path="$PWD/.old-stackrox/operator/config/crd/bases"
new_path="$PWD/operator/config/crd/bases"
crdify="go run -C operator/tools/crdify sigs.k8s.io/crdify --config=config.yaml"
set -x
$crdify "file://${old_path}/platform.stackrox.io_securedclusters.yaml" "file://${new_path}/platform.stackrox.io_securedclusters.yaml"
$crdify "file://${old_path}/platform.stackrox.io_centrals.yaml" "file://${new_path}/platform.stackrox.io_centrals.yaml"
crdify=".github/workflows/scripts/crdify.sh"
$crdify "${old_path}/platform.stackrox.io_securedclusters.yaml" "${new_path}/platform.stackrox.io_securedclusters.yaml"
$crdify "${old_path}/platform.stackrox.io_centrals.yaml" "${new_path}/platform.stackrox.io_centrals.yaml"

- name: Run crdify for config operator
run: |
set -e
set -euo pipefail
old_path="$PWD/.old-stackrox/config-controller/config/crd/bases"
new_path="$PWD/config-controller/config/crd/bases"
crdify="go run -C operator/tools/crdify sigs.k8s.io/crdify --config=config.yaml"
set -x
$crdify "file://${old_path}/config.stackrox.io_securitypolicies.yaml" "file://${new_path}/config.stackrox.io_securitypolicies.yaml"
crdify=".github/workflows/scripts/crdify.sh"
$crdify "${old_path}/config.stackrox.io_securitypolicies.yaml" "${new_path}/config.stackrox.io_securitypolicies.yaml"
75 changes: 75 additions & 0 deletions .github/workflows/scripts/crdify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Run crdify on copies of CRDs after stripping out known false positives.
# Usage:
# crdify.sh <old-crd> <new-crd> [crdify flags]

set -euo pipefail

ROOT_DIR="$(dirname "${BASH_SOURCE[0]}")/../../.."
readonly ROOT_DIR

if [[ $# -lt 2 ]]; then
echo "usage: $0 <old-crd> <new-crd> [crdify flags]" >&2
exit 2
fi

old_crd="${1:?missing required argument 'old-crd'}"
new_crd="${2:?missing required argument 'new-crd'}"
shift
shift

if [[ ! -f "$old_crd" ]]; then
echo "::error::CRD file not found: $old_crd" >&2
exit 1
fi

if [[ ! -f "$new_crd" ]]; then
echo "::error::CRD file not found: $new_crd" >&2
exit 1
fi


# The addition of this particular validation rule, even though considered a breaking change by definition
# (https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/api_changes.md#backward-compatibility-gotchas)
# is fine in practice, since the `excludeByKind` branch is being added in the same release cycle as the rule itself,
# meaning no production CRS could have existed that violated the validation.
filter_spec_exclusions_one_of() {
local input="$1"
local output="$2"

local message='at most one of the fields in [deployment excludeByKind] may be set'
local rule='(has(self.deployment)?1:0)+(has(self.excludeByKind)?1:0) <= 1'

# Remove matching rule, and the validations list if empty afterwards.
message="${message}" rule="${rule}" \
go run -C "${ROOT_DIR}/operator/tools/yq" github.com/mikefarah/yq/v4 eval '
del(
.spec.versions[].schema.openAPIV3Schema.properties.spec.properties.exclusions.items."x-kubernetes-validations"[]
| select(.message == strenv(message) and .rule == strenv(rule))
)
| del(
.spec.versions[].schema.openAPIV3Schema.properties.spec.properties.exclusions.items."x-kubernetes-validations"
| select(length == 0)
)
' "$input" > "$output"
}


crd_basename="$(basename "${old_crd}")"
case "$crd_basename" in
config.stackrox.io_securitypolicies.yaml)
filtered_dir="$(mktemp -d)"
echo >&2 "Filtering known false positives from ${old_crd} and ${new_crd}"
filter_spec_exclusions_one_of "${old_crd}" "${filtered_dir}/old-${crd_basename}"
filter_spec_exclusions_one_of "${new_crd}" "${filtered_dir}/new-${crd_basename}"
old_crd="${filtered_dir}/old-${crd_basename}"
new_crd="${filtered_dir}/new-${crd_basename}"
;;
*)
echo >&2 "No filtering rules for ${old_crd}, running crdify on original CRDs."
;;
esac

set -x
go run -C "${ROOT_DIR}/operator/tools/crdify" sigs.k8s.io/crdify --config=config.yaml "$@" \
"file://${old_crd}" "file://${new_crd}"
3 changes: 2 additions & 1 deletion config-controller/api/v1alpha1/policy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ type SecurityPolicySpec struct {
MitreVectorsLocked bool `json:"mitreVectorsLocked,omitempty"`
}

// +kubebuilder:validation:AtMostOneOf=deployment;excludeByKind
Comment thread
coderabbitai[bot] marked this conversation as resolved.
type Exclusion struct {
Name string `json:"name,omitempty"`
// +optional
Deployment Deployment `json:"deployment,omitempty"`
Deployment Deployment `json:"deployment,omitzero"`
Image Image `json:"image,omitempty"`
// +optional
// ExcludeByKind excludes all workloads of the selected Kubernetes kinds.
Expand Down
19 changes: 19 additions & 0 deletions config-controller/api/v1alpha1/policy_types_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v1alpha1

import (
"encoding/json"
"testing"

"github.com/stackrox/rox/generated/storage"
Expand Down Expand Up @@ -358,3 +359,21 @@ func TestToProtobufExcludeByKind(t *testing.T) {
assert.EqualError(t, err, `excludeByKind contains unknown workload kind "CRONJOB"`)
})
}

func TestExclusionJSONOmitsZeroDeployment(t *testing.T) {
kindOnly, err := json.Marshal(Exclusion{
Name: "skip jobs",
ExcludeByKind: &ExcludeByKind{Kinds: []WorkloadKind{"JOB"}},
})
assert.NoError(t, err)
assert.NotContains(t, string(kindOnly), `"deployment"`)
assert.Contains(t, string(kindOnly), `"excludeByKind"`)

withDeployment, err := json.Marshal(Exclusion{
Name: "skip web",
Deployment: Deployment{Name: "web"},
})
assert.NoError(t, err)
assert.Contains(t, string(withDeployment), `"deployment"`)
assert.Contains(t, string(withDeployment), `"web"`)
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ spec:
name:
type: string
type: object
x-kubernetes-validations:
- message: at most one of the fields in [deployment excludeByKind]
may be set
rule: (has(self.deployment)?1:0)+(has(self.excludeByKind)?1:0)
<= 1
type: array
isDefault:
description: IsDefault is unused
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ spec:
name:
type: string
type: object
x-kubernetes-validations:
- message: at most one of the fields in [deployment excludeByKind]
may be set
rule: (has(self.deployment)?1:0)+(has(self.excludeByKind)?1:0)
<= 1
type: array
isDefault:
description: IsDefault is unused
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading