Skip to content

Conversation

@ljluestc
Copy link

This PR implements the ability to filter resources by their API version in the Match criteria, addressing issue #171.

Previously, constraints could only match based on Group and Kind. This change allows users to specify apiVersions in their match configuration, enabling policies that target specific API versions (e.g., applying a policy only to v1 resources while ignoring v1beta1).

Changes

  • API: Added apiVersions field to the Kinds struct in pkg/mutation/match/match_types.go.
  • Logic: Updated kindsMatch in pkg/mutation/match/match.go to validate the resource's API version against the allowed list if provided.
  • DeepCopy: Updated zz_generated.deepcopy.go to handle the new field.
  • Tests: Added unit tests covering exact matches, mismatches, and wildcard behavior for API versions.

Example Usage

spec:
match:
kinds:
- apiGroups: ["extensions"]
kinds: ["Ingress"]
apiVersions: ["v1beta1"] # Only matches v1beta1 Ingress## Type of Change

  • New feature (non-breaking change which adds functionality)

Testing

  • Added unit tests in pkg/mutation/match/match_test.go
  • Verified deepcopy generation
  • Ran go test -v ./pkg/mutation/match/...

What this PR does / why we need it:
This PR implements the ability to filter resources by their API version in the Match criteria, addressing issue #171. Previously, constraints could only match based on Group and Kind. This change allows users to specify apiVersions in their match configuration, enabling policies that target specific API versions.

Which issue(s) this PR fixes:
Fixes #171

Special notes for your reviewer:
This change introduces a new field apiVersions to the Kinds struct in the match configuration. I've added comprehensive unit tests in pkg/mutation/match/match_test.go to cover various scenarios including exact matches, mismatches, and wildcard usage. The deepcopy generation has also been updated.

This PR implements the ability to filter resources by their API version in the Match criteria, addressing issue open-policy-agent#171.

Previously, constraints could only match based on Group and Kind. This change allows users to specify apiVersions in their match configuration, enabling policies that target specific API versions (e.g., applying a policy only to v1 resources while ignoring v1beta1).

Changes:
- API: Added apiVersions field to the Kinds struct in pkg/mutation/match/match_types.go.
- Logic: Updated kindsMatch in pkg/mutation/match/match.go to validate the resource's API version against the allowed list if provided.
- DeepCopy: Updated zz_generated.deepcopy.go to handle the new field.
- Tests: Added unit tests covering exact matches, mismatches, and wildcard behavior for API versions.

Example Usage:
spec:
  match:
    kinds:
      - apiGroups: ["extensions"]
        kinds: ["Ingress"]
        apiVersions: ["v1beta1"] # Only matches v1beta1 Ingress

Type of Change:
- [x] New feature (non-breaking change which adds functionality)

Testing:
- [x] Added unit tests in pkg/mutation/match/match_test.go
- [x] Verified deepcopy generation
- [x] Ran go test -v ./pkg/mutation/match/...

Related Issues:
Fixes open-policy-agent#171
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds API version filtering capability to the Match criteria for Gatekeeper policies, allowing users to target specific API versions (e.g., v1 vs v1beta1) when defining mutation policies.

Key Changes:

  • Added APIVersions field to the Kinds struct for version-based filtering
  • Updated matching logic to validate API versions using the same wildcard pattern as groups and kinds
  • Maintained backward compatibility (empty APIVersions matches all versions)

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pkg/mutation/match/match_types.go Added APIVersions field to the Kinds struct for API version filtering
pkg/mutation/match/match.go Updated kindsMatch function to check API version against allowed list when specified
pkg/mutation/match/zz_generated.deepcopy.go Auto-generated deepcopy methods updated to handle the new APIVersions field
pkg/mutation/match/match_test.go Added unit tests for API version matching, including exact match, mismatch, and wildcard scenarios

// If '*' is present, the length of the slice must be one.
// Required.
APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"`
Kinds []string `json:"kinds,omitempty"`
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new APIVersions field should include a comment describing its purpose and behavior, similar to the documentation provided for APIGroups and Kinds. Consider adding a comment like:

// APIVersions is the API versions the resources belong to. '*' is all versions.
// If '*' is present, the length of the slice must be one.
// If empty, all versions are matched.
APIVersions []string `json:"apiVersions,omitempty"`

This helps users understand that an empty array means "match all versions" (backward compatibility) and documents the wildcard behavior.

Suggested change
Kinds []string `json:"kinds,omitempty"`
Kinds []string `json:"kinds,omitempty"`
// APIVersions is the API versions the resources belong to. '*' is all versions.
// If '*' is present, the length of the slice must be one.
// If empty, all versions are matched.

Copilot uses AI. Check for mistakes.
Comment on lines +187 to +234
{
name: "match api version",
object: makeObject(schema.GroupVersionKind{Group: "group", Version: "v1", Kind: "kind"}, "", "name"),
matcher: Match{
Kinds: []Kinds{
{
APIGroups: []string{"group"},
Kinds: []string{"kind"},
APIVersions: []string{"v1"},
},
},
},
namespace: nil,
source: types.SourceTypeOriginal,
wantMatch: true,
},
{
name: "match api version mismatch",
object: makeObject(schema.GroupVersionKind{Group: "group", Version: "v1", Kind: "kind"}, "", "name"),
matcher: Match{
Kinds: []Kinds{
{
APIGroups: []string{"group"},
Kinds: []string{"kind"},
APIVersions: []string{"v2"},
},
},
},
namespace: nil,
source: types.SourceTypeOriginal,
wantMatch: false,
},
{
name: "match api version wildcard",
object: makeObject(schema.GroupVersionKind{Group: "group", Version: "v1", Kind: "kind"}, "", "name"),
matcher: Match{
Kinds: []Kinds{
{
APIGroups: []string{"group"},
Kinds: []string{"kind"},
APIVersions: []string{"*"},
},
},
},
namespace: nil,
source: types.SourceTypeOriginal,
wantMatch: true,
},
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a test case that verifies matching behavior with multiple API versions in the APIVersions array. For example:

{
    name:   "match api version with multiple versions",
    object: makeObject(schema.GroupVersionKind{Group: "group", Version: "v2", Kind: "kind"}, "", "name"),
    matcher: Match{
        Kinds: []Kinds{
            {
                APIGroups:   []string{"group"},
                Kinds:       []string{"kind"},
                APIVersions: []string{"v1", "v2", "v3"},
            },
        },
    },
    namespace: nil,
    source:    types.SourceTypeOriginal,
    wantMatch: true,
},

This would ensure the contains function correctly handles arrays with multiple values.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to Handle apiVersions for Objects Under Test

1 participant