Add Rego engine parity, pure-engine architecture, and dynamic resource fetching#1
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR brings the Rego evaluation engine to full functional parity with the Go engine, restructures scan execution around a pure single-engine model, and adds infrastructure for custom policy bundles to declare and fetch arbitrary Kubernetes resource types at scan time.
Changes
Pure engine architecture
Previously,
--engine regoran Rego for catalog checks and then fell back to the Go engine for cluster (preflight) checks — a hidden hybrid that caused different output between the two engines. This has been removed.scan.gonow always builds aClusterSnapshotfirst, then passes it to whichever engine is selected. Neither engine calls the other.eval.RunRequestcarries a*kube.ClusterSnapshotinstead of raw findings.input.cluster.ClusterSnapshot + BuildClusterSnapshot
All cluster state is now serialised into a single
kube.ClusterSnapshotstruct before evaluation. This makes the snapshot independently testable and reusable across engines.internal/kube/snapshot.go:ClusterSnapshot,DeploymentSnapshot,NodeSnapshot, etc.internal/kube/build_snapshot.go:BuildClusterSnapshot()andDegradedSnapshot().ClusterSnapshot.Resources map[string][]ResourceSnapshotcarries dynamically-fetched resource types.Dynamic resource fetching (
--resourceflag + bundle metadata)Policy bundles can now declare the Kubernetes resource types they need in
metadata.json. The scanner fetches them via the dynamic client and exposes them to Rego asinput.cluster.resources["GROUP/VERSION/resources"]. A--resourceCLI flag provides the same capability for ad-hoc use.kube.Clientsgains adynamic.Interfacefield.PreflightOptions.ResourceTypes []stringdrives fetching withinBuildClusterSnapshot.bundleMetadata.Resources []stringin the Rego engine is read before snapshot building.ResourceTypesFromBundle(bundlePath)is exported for use inscan.go.mergeResourceTypesdeduplicates the union of flag and bundle resource lists.v1/configmaps,apps/v1/deployments) to match Kubernetes REST URL conventions.Default Rego bundle (
policy/)A new standalone policy bundle under
policy/covers all checks previously handled by the Go engine:policy/catalog.regopolicy/cluster.regopolicy/main.regodata.kvirtbp.findingsentrypointpolicy/metadata.jsonThe embedded
internal/eval/rego/policy/baseline.regowas updated to the same combined logic for use with--engine regowithout any flags.Rego unit tests
New
policy/catalog_test.rego(8 tests) andpolicy/cluster_test.rego(11 tests) cover the policy rules directly usingopa test.Custom bundle e2e test
A lightweight e2e scenario that exercises the full dynamic resource-fetching path without requiring KubeVirt:
test/fixtures/custom-bundle/— policy that checks for a ConfigMap namedkvirtbp-e2e-marker;metadata.jsondeclares"resources": ["v1/configmaps"]scripts/e2e_kind_custom_bundle.sh— creates a single-node kind cluster; pass mode deploys the ConfigMap, fail mode removes itNew Makefile targets
make rego-checkopa check --v0-compatible— syntax validationmake rego-fmtopa fmt --v0-compatible --write— formattingmake rego-testopa test --v0-compatible -v— unit tests (19/19 pass)make e2e-kind-custom-bundle-pass/make e2e-kind-custom-bundle-failTest coverage additions
internal/kube/preflight_controls_test.go— 4 tests forparseResourceType(core group, named group, CRD, invalid inputs)internal/cli/scan_metadata_test.go— 3 tests formergeResourceTypes(dedup, empty inputs, all-in-a)internal/eval/rego/engine_test.go— 4 tests forResourceTypesFromBundle(with resources, no resources field, missing metadata, non-existent path)internal/eval/snapshot_rego_test.go— snapshot ↔ Rego equivalence testsinternal/eval/equivalence_bundle_test.go— Go engine vs Rego bundle parity tests