diff --git a/api/unversioned/policy_types.go b/api/unversioned/policy_types.go index 528f9e0f37..f61246a63e 100644 --- a/api/unversioned/policy_types.go +++ b/api/unversioned/policy_types.go @@ -25,6 +25,9 @@ import ( type PolicySpec struct { // Important: Run "make" to regenerate code after modifying this file + // Type of the polocy + Type string `json:"type,omitempty"` + // Parameters for this policy Parameters runtime.RawExtension `json:"parameters,omitempty"` } diff --git a/api/v1alpha1/policy_types.go b/api/v1alpha1/policy_types.go index 63e4f5314b..43faed955f 100644 --- a/api/v1alpha1/policy_types.go +++ b/api/v1alpha1/policy_types.go @@ -28,6 +28,9 @@ import ( type PolicySpec struct { // Important: Run "make" to regenerate code after modifying this file + // Type of the polocy + Type string `json:"type,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields // Parameters for this policy Parameters runtime.RawExtension `json:"parameters,omitempty"` diff --git a/api/v1alpha1/zz_generated.conversion.go b/api/v1alpha1/zz_generated.conversion.go index 18e3e83380..dd2ac0e4a9 100644 --- a/api/v1alpha1/zz_generated.conversion.go +++ b/api/v1alpha1/zz_generated.conversion.go @@ -399,6 +399,7 @@ func Convert_unversioned_PolicyList_To_v1alpha1_PolicyList(in *unversioned.Polic } func autoConvert_v1alpha1_PolicySpec_To_unversioned_PolicySpec(in *PolicySpec, out *unversioned.PolicySpec, s conversion.Scope) error { + out.Type = in.Type out.Parameters = in.Parameters return nil } @@ -409,6 +410,7 @@ func Convert_v1alpha1_PolicySpec_To_unversioned_PolicySpec(in *PolicySpec, out * } func autoConvert_unversioned_PolicySpec_To_v1alpha1_PolicySpec(in *unversioned.PolicySpec, out *PolicySpec, s conversion.Scope) error { + out.Type = in.Type out.Parameters = in.Parameters return nil } diff --git a/charts/ratify/crds/policy-customresourcedefinition.yaml b/charts/ratify/crds/policy-customresourcedefinition.yaml index 75ed67ec07..d4957133d5 100644 --- a/charts/ratify/crds/policy-customresourcedefinition.yaml +++ b/charts/ratify/crds/policy-customresourcedefinition.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -14,36 +15,37 @@ spec: singular: policy scope: Cluster versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Policy is the Schema for the policies API - properties: - apiVersion: - description: - "APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" - type: string - kind: - description: - "Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" - type: string - metadata: - type: object - spec: - description: PolicySpec defines the desired state of Policy - properties: - parameters: - description: Parameters for this policy - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - status: - description: PolicyStatus defines the observed state of Policy - type: object - type: object - served: true - storage: true + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Policy is the Schema for the policies API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: PolicySpec defines the desired state of Policy + properties: + parameters: + description: Parameters for this policy + type: object + x-kubernetes-preserve-unknown-fields: true + type: + description: Type of the polocy + type: string + type: object + status: + description: PolicyStatus defines the observed state of Policy + type: object + type: object + served: true + storage: true diff --git a/config/crd/bases/config.ratify.deislabs.io_certificatestores.yaml b/config/crd/bases/config.ratify.deislabs.io_certificatestores.yaml index ffd4668177..abafa948bd 100644 --- a/config/crd/bases/config.ratify.deislabs.io_certificatestores.yaml +++ b/config/crd/bases/config.ratify.deislabs.io_certificatestores.yaml @@ -111,7 +111,7 @@ spec: format: date-time type: string properties: - description: provider specific parameters of the each individual certificate + description: provider specific properties of the each individual certificate type: object x-kubernetes-preserve-unknown-fields: true required: diff --git a/config/crd/bases/config.ratify.deislabs.io_policies.yaml b/config/crd/bases/config.ratify.deislabs.io_policies.yaml index d01200d814..d4957133d5 100644 --- a/config/crd/bases/config.ratify.deislabs.io_policies.yaml +++ b/config/crd/bases/config.ratify.deislabs.io_policies.yaml @@ -39,6 +39,9 @@ spec: description: Parameters for this policy type: object x-kubernetes-preserve-unknown-fields: true + type: + description: Type of the polocy + type: string type: object status: description: PolicyStatus defines the observed state of Policy diff --git a/config/samples/policy/config_v1alpha1_policy_json.yaml b/config/samples/policy/config_v1alpha1_policy_json.yaml index 127bab714e..2ba5743ff8 100644 --- a/config/samples/policy/config_v1alpha1_policy_json.yaml +++ b/config/samples/policy/config_v1alpha1_policy_json.yaml @@ -1,8 +1,9 @@ apiVersion: config.ratify.deislabs.io/v1alpha1 kind: Policy metadata: - name: "configpolicy" + name: "ratify-policy" spec: + type: "configpolicy" parameters: artifactVerificationPolicies: default: "all" diff --git a/config/samples/policy/config_v1alpha1_policy_rego.yaml b/config/samples/policy/config_v1alpha1_policy_rego.yaml index f809783094..8a5d8577c3 100644 --- a/config/samples/policy/config_v1alpha1_policy_rego.yaml +++ b/config/samples/policy/config_v1alpha1_policy_rego.yaml @@ -1,8 +1,9 @@ apiVersion: config.ratify.deislabs.io/v1alpha1 kind: Policy metadata: - name: "regopolicy" + name: "ratify-policy" spec: + type: "regopolicy" parameters: passthroughEnabled: false policy: | diff --git a/pkg/controllers/policy_controller.go b/pkg/controllers/policy_controller.go index 85290bb031..6bc5deea4b 100644 --- a/pkg/controllers/policy_controller.go +++ b/pkg/controllers/policy_controller.go @@ -31,6 +31,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +const ratifyPolicy = "ratify-policy" + // PolicyReconciler reconciles a Policy object type PolicyReconciler struct { client.Client @@ -74,33 +76,15 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr return ctrl.Result{}, client.IgnoreNotFound(err) } - if err := policyAddOrReplace(policy.Spec, resource); err != nil { - policyLogger.Error("unable to create policy from policy crd: ", err) - return ctrl.Result{}, err + if resource != ratifyPolicy { + return ctrl.Result{}, nil } - // List all policies in the same namespace. - policyList := &configv1alpha1.PolicyList{} - if err := r.List(ctx, policyList, client.InNamespace(req.Namespace)); err != nil { - policyLogger.Error("failed to list Policies: ", err) + if err := policyAddOrReplace(policy.Spec); err != nil { + policyLogger.Error("unable to create policy from policy crd: ", err) return ctrl.Result{}, err } - // Delete all policies except the current one. - for _, item := range policyList.Items { - item := item - if item.Name != resource { - policyLogger.Infof("Deleting policy %s", item.Name) - err := r.Delete(ctx, &item) - if err != nil { - policyLogger.Error("failed to delete Policy: ", err) - return ctrl.Result{}, err - } - policyLogger.Info("Deleted policy", "name", item.Name) - } - } - - // returning empty result and no error to indicate we’ve successfully reconciled this object return ctrl.Result{}, nil } @@ -111,19 +95,19 @@ func (r *PolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func policyAddOrReplace(spec configv1alpha1.PolicySpec, policyName string) error { - policyEnforcer, err := specToPolicyEnforcer(spec, policyName) +func policyAddOrReplace(spec configv1alpha1.PolicySpec) error { + policyEnforcer, err := specToPolicyEnforcer(spec) if err != nil { return fmt.Errorf("failed to create policy enforcer: %w", err) } - ActivePolicy.Name = policyName + ActivePolicy.Name = spec.Type ActivePolicy.Enforcer = policyEnforcer return nil } -func specToPolicyEnforcer(spec configv1alpha1.PolicySpec, policyName string) (policyprovider.PolicyProvider, error) { - policyConfig, err := rawToPolicyConfig(spec.Parameters.Raw, policyName) +func specToPolicyEnforcer(spec configv1alpha1.PolicySpec) (policyprovider.PolicyProvider, error) { + policyConfig, err := rawToPolicyConfig(spec.Parameters.Raw, spec.Type) if err != nil { return nil, fmt.Errorf("failed to parse policy config: %w", err) } @@ -160,7 +144,6 @@ func (p *policy) deletePolicy(resource string) { } } -// IsEmpty returns true if there is no policy set up. func (p *policy) IsEmpty() bool { return p.Name == "" && p.Enforcer == nil } diff --git a/pkg/controllers/policy_controller_test.go b/pkg/controllers/policy_controller_test.go index 45b305ff1d..1d1dc6eeff 100644 --- a/pkg/controllers/policy_controller_test.go +++ b/pkg/controllers/policy_controller_test.go @@ -147,28 +147,30 @@ func TestSpecToPolicyEnforcer(t *testing.T) { { name: "invalid spec", policyName: policyName1, - spec: configv1alpha1.PolicySpec{}, + spec: configv1alpha1.PolicySpec{ + Type: policyName1, + }, expectErr: true, expectProvider: false, }, { name: "non-supported policy", - policyName: policyName1, spec: configv1alpha1.PolicySpec{ Parameters: runtime.RawExtension{ Raw: []byte("{\"name\": \"policy1\"}"), }, + Type: policyName1, }, expectErr: true, expectProvider: false, }, { name: "valid spec", - policyName: "configpolicy", spec: configv1alpha1.PolicySpec{ Parameters: runtime.RawExtension{ Raw: []byte("{\"name\": \"configpolicy\"}"), }, + Type: "configpolicy", }, expectErr: false, expectProvider: true, @@ -177,7 +179,7 @@ func TestSpecToPolicyEnforcer(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - provider, err := specToPolicyEnforcer(tc.spec, tc.policyName) + provider, err := specToPolicyEnforcer(tc.spec) if tc.expectErr != (err != nil) { t.Fatalf("Expected error to be %t, got %t", tc.expectErr, err != nil) @@ -198,8 +200,9 @@ func TestPolicyAddOrReplace(t *testing.T) { }{ { name: "invalid spec", - spec: configv1alpha1.PolicySpec{}, - policyName: policyName1, + spec: configv1alpha1.PolicySpec{ + Type: policyName1, + }, expectErr: true, }, { @@ -208,15 +211,15 @@ func TestPolicyAddOrReplace(t *testing.T) { Parameters: runtime.RawExtension{ Raw: []byte("{\"name\": \"configpolicy\"}"), }, + Type: "configpolicy", }, - policyName: "configpolicy", expectErr: false, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - err := policyAddOrReplace(tc.spec, tc.policyName) + err := policyAddOrReplace(tc.spec) if tc.expectErr != (err != nil) { t.Fatalf("Expected error to be %t, got %t", tc.expectErr, err != nil)