Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add ValidatingAdmissionPolicy generation function #376

Merged
merged 5 commits into from
Jan 5, 2024

Conversation

maxsmythe
Copy link
Contributor

Adds the ability to generate a VAP policy definition from a constraint template using the K8sNative engine.

This is an incremental step towards implementing the Gatekeeper-to-VAP User Flow

@maxsmythe maxsmythe changed the title Add ValidatingAdmissionPolicy generation function feat: Add ValidatingAdmissionPolicy generation function Nov 14, 2023
Signed-off-by: Max Smythe <smythe@google.com>
@codecov-commenter
Copy link

codecov-commenter commented Nov 14, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (af4fcdb) 54.06% compared to head (b8a5935) 54.38%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #376      +/-   ##
==========================================
+ Coverage   54.06%   54.38%   +0.31%     
==========================================
  Files          67       71       +4     
  Lines        4796     5176     +380     
==========================================
+ Hits         2593     2815     +222     
- Misses       1923     2064     +141     
- Partials      280      297      +17     
Flag Coverage Δ
unittests 54.38% <ø> (+0.31%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Signed-off-by: Max Smythe <smythe@google.com>
Copy link
Contributor

@acpana acpana left a comment

Choose a reason for hiding this comment

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

excited to see this happening 🎉

left some minor, non blocking comments


func NewWrapper(req *admissionv1.AdmissionRequest) (*RequestWrapper, error) {
var object runtime.Object
if len(req.Object.Raw) != 0 {
Copy link
Member

Choose a reason for hiding this comment

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

should we return error early for all the len == 0 cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

len == 0 is acceptable in some cases (e.g. object on delete, oldObject on create)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(in these cases, expected value is nil)

Expression string
Message string
MessageExpression string
// A CEL expression. Maps to ValidationAdmissionPolicy's spec.validations
Copy link
Member

Choose a reason for hiding this comment

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

I think this comment is meant for the Validation type so might be good to move it before the type definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Putting the comment here is what would generate the docstring for Open API schema.

For example, this field:

https://github.com/open-policy-agent/gatekeeper/blob/650397965cfd9dcfe3d2bd3456a13c04e8fc8338/apis/mutations/v1/externaldata_types.go#L13-L16

Turns into this schema:

https://github.com/open-policy-agent/gatekeeper/blob/650397965cfd9dcfe3d2bd3456a13c04e8fc8338/config/crd/bases/mutations.gatekeeper.sh_assign.yaml#L251-L253

I was aiming for consistency, but happy to move things if you like. LMK what you prefer.

Expression string `json:"expression"`
}

type Variable struct {
// A CEL variable definition. Maps to ValidationAdmissionPolicy's spec.variables
Copy link
Member

Choose a reason for hiding this comment

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

same, move comment before the type

Signed-off-by: Max Smythe <smythe@google.com>
Name = "K8sNativeValidation"
// ReservedPrefix signifies a prefix that no user-defined value (variable, matcher, etc.) is allowed to have.
// This gives us the ability to add new variables in the future without worrying about breaking pre-existing templates.
ReservedPrefix = "g8r_internal_"
Copy link
Member

@sozercan sozercan Dec 18, 2023

Choose a reason for hiding this comment

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

nit: Should we rename this to gatekeeper_...? Users/contributors might not know what g8r means. That made me think maybe we should rename "K8s" to "Kubernetes" too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TBH, I'm mostly concerned about brevity/uniqueness. Since this is more about reserving a namespace for us, ideally users never collide with the naming and therefore never need to know the details.

I'm okay with either, but would rather not rename things more than one more time in this PR.

@ritazh preferred name?

Copy link
Member

Choose a reason for hiding this comment

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

I'm ok with either as well. +1 on "gatekeeper_" since g8r is less well known.

return nil, err
}

matchConditions, err := source.GetV1Alpha1MatchConditions()
Copy link
Member

Choose a reason for hiding this comment

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

why do we only convert to the alpha one? backward compat? when should we consider beta and v1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd say we'd switch once its possible to generate v1beta1 (or greater) VAP resources.

If we wanted to avoid future breaking changes, I could rename this to TemplateToV1Alpha1PolicyDefinition() if you prefer?

Copy link
Member

Choose a reason for hiding this comment

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

I'm ok keeping it as is.

name: "Simple match",
matcher: nsMatcher{"somename"},
namespace: ptr.To[string]("somename"),
shouldMatch: false,
Copy link
Member

Choose a reason for hiding this comment

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

why is shouldMatch false for this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

b/c its testing excluded namespaces

Copy link
Contributor Author

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

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

Sorry, for some reason my comments were listed as "pending review", so some of these are older responses (but probably still relevant)

Expression string
Message string
MessageExpression string
// A CEL expression. Maps to ValidationAdmissionPolicy's spec.validations
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Putting the comment here is what would generate the docstring for Open API schema.

For example, this field:

https://github.com/open-policy-agent/gatekeeper/blob/650397965cfd9dcfe3d2bd3456a13c04e8fc8338/apis/mutations/v1/externaldata_types.go#L13-L16

Turns into this schema:

https://github.com/open-policy-agent/gatekeeper/blob/650397965cfd9dcfe3d2bd3456a13c04e8fc8338/config/crd/bases/mutations.gatekeeper.sh_assign.yaml#L251-L253

I was aiming for consistency, but happy to move things if you like. LMK what you prefer.


func NewWrapper(req *admissionv1.AdmissionRequest) (*RequestWrapper, error) {
var object runtime.Object
if len(req.Object.Raw) != 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

len == 0 is acceptable in some cases (e.g. object on delete, oldObject on create)


func NewWrapper(req *admissionv1.AdmissionRequest) (*RequestWrapper, error) {
var object runtime.Object
if len(req.Object.Raw) != 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

(in these cases, expected value is nil)

constraint/pkg/client/drivers/k8scel/schema/schema.go Outdated Show resolved Hide resolved
constraint/pkg/client/drivers/k8scel/schema/schema.go Outdated Show resolved Hide resolved
Name = "K8sNativeValidation"
// ReservedPrefix signifies a prefix that no user-defined value (variable, matcher, etc.) is allowed to have.
// This gives us the ability to add new variables in the future without worrying about breaking pre-existing templates.
ReservedPrefix = "g8r_internal_"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TBH, I'm mostly concerned about brevity/uniqueness. Since this is more about reserving a namespace for us, ideally users never collide with the naming and therefore never need to know the details.

I'm okay with either, but would rather not rename things more than one more time in this PR.

@ritazh preferred name?

return nil, err
}

matchConditions, err := source.GetV1Alpha1MatchConditions()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd say we'd switch once its possible to generate v1beta1 (or greater) VAP resources.

If we wanted to avoid future breaking changes, I could rename this to TemplateToV1Alpha1PolicyDefinition() if you prefer?

name: "Simple match",
matcher: nsMatcher{"somename"},
namespace: ptr.To[string]("somename"),
shouldMatch: false,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

b/c its testing excluded namespaces

Signed-off-by: Max Smythe <smythe@google.com>
Signed-off-by: Max Smythe <smythe@google.com>
Copy link
Member

@ritazh ritazh left a comment

Choose a reason for hiding this comment

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

LGTM

Excited to integrate this!

@maxsmythe maxsmythe merged commit 6adc486 into open-policy-agent:master Jan 5, 2024
4 checks passed
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.

None yet

5 participants