Skip to content

Commit

Permalink
feat: vap update to reduce operations, v1beta1, and fail open
Browse files Browse the repository at this point in the history
Signed-off-by: Rita Zhang <[email protected]>
  • Loading branch information
ritazh committed Feb 17, 2024
1 parent 930072e commit fe02898
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 118 deletions.
33 changes: 17 additions & 16 deletions constraint/pkg/client/drivers/k8scel/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/open-policy-agent/frameworks/constraint/pkg/core/templates"
admissionv1 "k8s.io/api/admissionregistration/v1"
admissionv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
admissionv1beta1 "k8s.io/api/admissionregistration/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/admission/plugin/cel"
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy"
Expand Down Expand Up @@ -99,14 +99,14 @@ func (in *Source) GetMatchConditions() ([]cel.ExpressionAccessor, error) {
return matchConditions, nil
}

func (in *Source) GetV1Alpha1MatchConditions() ([]admissionv1alpha1.MatchCondition, error) {
func (in *Source) GetV1Beta1MatchConditions() ([]admissionv1beta1.MatchCondition, error) {
if err := in.validateMatchConditions(); err != nil {
return nil, err
}

var matchConditions []admissionv1alpha1.MatchCondition
var matchConditions []admissionv1beta1.MatchCondition
for _, mc := range in.MatchConditions {
matchConditions = append(matchConditions, admissionv1alpha1.MatchCondition{
matchConditions = append(matchConditions, admissionv1beta1.MatchCondition{
Name: mc.Name,
Expression: mc.Expression,
})
Expand Down Expand Up @@ -142,14 +142,14 @@ func (in *Source) GetVariables() ([]cel.NamedExpressionAccessor, error) {
return vars, nil
}

func (in *Source) GetV1Alpha1Variables() ([]admissionv1alpha1.Variable, error) {
func (in *Source) GetV1Beta1Variables() ([]admissionv1beta1.Variable, error) {
if err := in.validateVariables(); err != nil {
return nil, err
}

var variables []admissionv1alpha1.Variable
var variables []admissionv1beta1.Variable
for _, v := range in.Variables {
variables = append(variables, admissionv1alpha1.Variable{
variables = append(variables, admissionv1beta1.Variable{
Name: v.Name,
Expression: v.Expression,
})
Expand All @@ -169,10 +169,10 @@ func (in *Source) GetValidations() ([]cel.ExpressionAccessor, error) {
return validations, nil
}

func (in *Source) GetV1Alpha1Validatons() ([]admissionv1alpha1.Validation, error) {
var validations []admissionv1alpha1.Validation
func (in *Source) GetV1Beta1Validatons() ([]admissionv1beta1.Validation, error) {
var validations []admissionv1beta1.Validation
for _, v := range in.Validations {
validations = append(validations, admissionv1alpha1.Validation{
validations = append(validations, admissionv1beta1.Validation{
Expression: v.Expression,
Message: v.Message,
MessageExpression: v.MessageExpression,
Expand Down Expand Up @@ -213,18 +213,19 @@ func (in *Source) GetFailurePolicy() (*admissionv1.FailurePolicyType, error) {
return &out, nil
}

func (in *Source) GetV1alpha1FailurePolicy() (*admissionv1alpha1.FailurePolicyType, error) {
func (in *Source) GetV1Beta1FailurePolicy() (*admissionv1beta1.FailurePolicyType, error) {
var out admissionv1beta1.FailurePolicyType
/// TODO(ritazh): default for now until the feature is safe to fail close
if in.FailurePolicy == nil {
return nil, nil
out = admissionv1beta1.Ignore
return &out, nil
}

var out admissionv1alpha1.FailurePolicyType

switch *in.FailurePolicy {
case string(admissionv1.Fail):
out = admissionv1alpha1.Fail
out = admissionv1beta1.Fail
case string(admissionv1.Ignore):
out = admissionv1alpha1.Ignore
out = admissionv1beta1.Ignore
default:
return nil, fmt.Errorf("%w: unrecognized failure policy: %s", ErrBadFailurePolicy, *in.FailurePolicy)
}
Expand Down
50 changes: 25 additions & 25 deletions constraint/pkg/client/drivers/k8scel/transform/cel_snippets.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package transform

import (
"github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema"
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
"k8s.io/apiserver/pkg/admission/plugin/cel"
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy"
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
Expand Down Expand Up @@ -84,15 +84,15 @@ const (
`
)

func MatchExcludedNamespacesGlobV1Alpha1() admissionregistrationv1alpha1.MatchCondition {
return admissionregistrationv1alpha1.MatchCondition{
func MatchExcludedNamespacesGlobV1Beta1() admissionregistrationv1beta1.MatchCondition {
return admissionregistrationv1beta1.MatchCondition{
Name: "gatekeeper_internal_match_excluded_namespaces",
Expression: matchExcludedNamespacesGlob,
}
}

func MatchExcludedNamespacesGlobCEL() []cel.ExpressionAccessor {
mc := MatchExcludedNamespacesGlobV1Alpha1()
mc := MatchExcludedNamespacesGlobV1Beta1()
return []cel.ExpressionAccessor{
&matchconditions.MatchCondition{
Name: mc.Name,
Expand All @@ -101,15 +101,15 @@ func MatchExcludedNamespacesGlobCEL() []cel.ExpressionAccessor {
}
}

func MatchNamespacesGlobV1Alpha1() admissionregistrationv1alpha1.MatchCondition {
return admissionregistrationv1alpha1.MatchCondition{
func MatchNamespacesGlobV1Beta1() admissionregistrationv1beta1.MatchCondition {
return admissionregistrationv1beta1.MatchCondition{
Name: "gatekeeper_internal_match_namespaces",
Expression: matchNamespacesGlob,
}
}

func MatchNamespacesGlobCEL() []cel.ExpressionAccessor {
mc := MatchNamespacesGlobV1Alpha1()
mc := MatchNamespacesGlobV1Beta1()
return []cel.ExpressionAccessor{
&matchconditions.MatchCondition{
Name: mc.Name,
Expand All @@ -118,15 +118,15 @@ func MatchNamespacesGlobCEL() []cel.ExpressionAccessor {
}
}

func MatchNameGlobV1Alpha1() admissionregistrationv1alpha1.MatchCondition {
return admissionregistrationv1alpha1.MatchCondition{
func MatchNameGlobV1Beta1() admissionregistrationv1beta1.MatchCondition {
return admissionregistrationv1beta1.MatchCondition{
Name: "gatekeeper_internal_match_name",
Expression: matchNameGlob,
}
}

func MatchNameGlobCEL() []cel.ExpressionAccessor {
mc := MatchNameGlobV1Alpha1()
mc := MatchNameGlobV1Beta1()
return []cel.ExpressionAccessor{
&matchconditions.MatchCondition{
Name: mc.Name,
Expand All @@ -135,15 +135,15 @@ func MatchNameGlobCEL() []cel.ExpressionAccessor {
}
}

func MatchKindsV1Alpha1() admissionregistrationv1alpha1.MatchCondition {
return admissionregistrationv1alpha1.MatchCondition{
func MatchKindsV1Beta1() admissionregistrationv1beta1.MatchCondition {
return admissionregistrationv1beta1.MatchCondition{
Name: "gatekeeper_internal_match_kinds",
Expression: matchKinds,
}
}

func MatchKindsCEL() []cel.ExpressionAccessor {
mc := MatchKindsV1Alpha1()
mc := MatchKindsV1Beta1()
return []cel.ExpressionAccessor{
&matchconditions.MatchCondition{
Name: mc.Name,
Expand All @@ -152,15 +152,15 @@ func MatchKindsCEL() []cel.ExpressionAccessor {
}
}

func BindParamsV1Alpha1() admissionregistrationv1alpha1.Variable {
return admissionregistrationv1alpha1.Variable{
func BindParamsV1Beta1() admissionregistrationv1beta1.Variable {
return admissionregistrationv1beta1.Variable{
Name: schema.ParamsName,
Expression: "!has(params.spec) ? null : !has(params.spec.parameters) ? null: params.spec.parameters",
}
}

func BindParamsCEL() []cel.NamedExpressionAccessor {
v := BindParamsV1Alpha1()
v := BindParamsV1Beta1()
return []cel.NamedExpressionAccessor{
&validatingadmissionpolicy.Variable{
Name: v.Name,
Expand All @@ -169,21 +169,21 @@ func BindParamsCEL() []cel.NamedExpressionAccessor {
}
}

func AllMatchersV1Alpha1() []admissionregistrationv1alpha1.MatchCondition {
return []admissionregistrationv1alpha1.MatchCondition{
MatchExcludedNamespacesGlobV1Alpha1(),
MatchNamespacesGlobV1Alpha1(),
MatchNameGlobV1Alpha1(),
MatchKindsV1Alpha1(),
func AllMatchersV1Beta1() []admissionregistrationv1beta1.MatchCondition {
return []admissionregistrationv1beta1.MatchCondition{
MatchExcludedNamespacesGlobV1Beta1(),
MatchNamespacesGlobV1Beta1(),
MatchNameGlobV1Beta1(),
MatchKindsV1Beta1(),
}
}

func AllVariablesCEL() []cel.NamedExpressionAccessor {
return BindParamsCEL()
}

func AllVariablesV1Alpha1() []admissionregistrationv1alpha1.Variable {
return []admissionregistrationv1alpha1.Variable{
BindParamsV1Alpha1(),
func AllVariablesV1Beta1() []admissionregistrationv1beta1.Variable {
return []admissionregistrationv1beta1.Variable{
BindParamsV1Beta1(),
}
}
53 changes: 27 additions & 26 deletions constraint/pkg/client/drivers/k8scel/transform/make_vap_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,56 +8,57 @@ import (
templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1"
"github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema"
"github.com/open-policy-agent/frameworks/constraint/pkg/core/templates"
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/ptr"
)

func TemplateToPolicyDefinition(template *templates.ConstraintTemplate) (*admissionregistrationv1alpha1.ValidatingAdmissionPolicy, error) {
func TemplateToPolicyDefinition(template *templates.ConstraintTemplate) (*admissionregistrationv1beta1.ValidatingAdmissionPolicy, error) {
source, err := schema.GetSourceFromTemplate(template)
if err != nil {
return nil, err
}

matchConditions, err := source.GetV1Alpha1MatchConditions()
matchConditions, err := source.GetV1Beta1MatchConditions()
if err != nil {
return nil, err
}
matchConditions = append(matchConditions, AllMatchersV1Alpha1()...)
matchConditions = append(matchConditions, AllMatchersV1Beta1()...)

validations, err := source.GetV1Alpha1Validatons()
validations, err := source.GetV1Beta1Validatons()
if err != nil {
return nil, err
}

variables, err := source.GetV1Alpha1Variables()
variables, err := source.GetV1Beta1Variables()
if err != nil {
return nil, err
}
variables = append(variables, AllVariablesV1Alpha1()...)
variables = append(variables, AllVariablesV1Beta1()...)

failurePolicy, err := source.GetV1alpha1FailurePolicy()
failurePolicy, err := source.GetV1Beta1FailurePolicy()
if err != nil {
return nil, err
}

policy := &admissionregistrationv1alpha1.ValidatingAdmissionPolicy{
policy := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("gatekeeper-%s", template.GetName()),
},
Spec: admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{
ParamKind: &admissionregistrationv1alpha1.ParamKind{
Spec: admissionregistrationv1beta1.ValidatingAdmissionPolicySpec{
ParamKind: &admissionregistrationv1beta1.ParamKind{
APIVersion: fmt.Sprintf("%s/%s", apiconstraints.Group, templatesv1beta1.SchemeGroupVersion.Version),
Kind: template.Spec.CRD.Spec.Names.Kind,
},
MatchConstraints: &admissionregistrationv1alpha1.MatchResources{
ResourceRules: []admissionregistrationv1alpha1.NamedRuleWithOperations{
MatchConstraints: &admissionregistrationv1beta1.MatchResources{
ResourceRules: []admissionregistrationv1beta1.NamedRuleWithOperations{
{
RuleWithOperations: admissionregistrationv1alpha1.RuleWithOperations{
Operations: []admissionregistrationv1alpha1.OperationType{admissionregistrationv1alpha1.OperationAll},
Rule: admissionregistrationv1alpha1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"*"}},
RuleWithOperations: admissionregistrationv1beta1.RuleWithOperations{
/// TODO(ritazh): default for now until we can safely expose these to users
Operations: []admissionregistrationv1beta1.OperationType{admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update},
Rule: admissionregistrationv1beta1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"*"}},
},
},
},
Expand All @@ -72,34 +73,34 @@ func TemplateToPolicyDefinition(template *templates.ConstraintTemplate) (*admiss
return policy, nil
}

func ConstraintToBinding(constraint *unstructured.Unstructured) (*admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, error) {
func ConstraintToBinding(constraint *unstructured.Unstructured) (*admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding, error) {
enforcementActionStr, err := apiconstraints.GetEnforcementAction(constraint)
if err != nil {
return nil, err
}

var enforcementAction admissionregistrationv1alpha1.ValidationAction
var enforcementAction admissionregistrationv1beta1.ValidationAction
switch enforcementActionStr {
case apiconstraints.EnforcementActionDeny:
enforcementAction = admissionregistrationv1alpha1.Deny
enforcementAction = admissionregistrationv1beta1.Deny
case "warn":
enforcementAction = admissionregistrationv1alpha1.Warn
enforcementAction = admissionregistrationv1beta1.Warn
default:
return nil, fmt.Errorf("%w: unrecognized enforcement action %s, must be `warn` or `deny`", ErrBadEnforcementAction, enforcementActionStr)
}

binding := &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{
binding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("gatekeeper-%s", constraint.GetName()),
},
Spec: admissionregistrationv1alpha1.ValidatingAdmissionPolicyBindingSpec{
Spec: admissionregistrationv1beta1.ValidatingAdmissionPolicyBindingSpec{
PolicyName: fmt.Sprintf("gatekeeper-%s", strings.ToLower(constraint.GetKind())),
ParamRef: &admissionregistrationv1alpha1.ParamRef{
ParamRef: &admissionregistrationv1beta1.ParamRef{
Name: constraint.GetName(),
ParameterNotFoundAction: ptr.To[admissionregistrationv1alpha1.ParameterNotFoundActionType](admissionregistrationv1alpha1.AllowAction),
ParameterNotFoundAction: ptr.To[admissionregistrationv1beta1.ParameterNotFoundActionType](admissionregistrationv1beta1.AllowAction),
},
MatchResources: &admissionregistrationv1alpha1.MatchResources{},
ValidationActions: []admissionregistrationv1alpha1.ValidationAction{enforcementAction},
MatchResources: &admissionregistrationv1beta1.MatchResources{},
ValidationActions: []admissionregistrationv1beta1.ValidationAction{enforcementAction},
},
}
objectSelectorMap, found, err := unstructured.NestedMap(constraint.Object, "spec", "match", "labelSelector")
Expand Down
Loading

0 comments on commit fe02898

Please sign in to comment.