From 49f63e1e89617c1ff7d8ad1eb03aaa60699f5044 Mon Sep 17 00:00:00 2001 From: Susan Shi Date: Tue, 19 Dec 2023 14:37:11 -0800 Subject: [PATCH] feat: add version to CRD spec (#1215) --- api/v1beta1/store_types.go | 6 ++++-- api/v1beta1/verifier_types.go | 9 +++++--- .../crds/store-customresourcedefinition.yaml | 9 ++++++-- .../verifier-customresourcedefinition.yaml | 8 ++++++- charts/ratify/templates/store.yaml | 1 + charts/ratify/templates/verifier.yaml | 4 ++++ config/config.go | 5 +++++ ....ratify.deislabs.io_certificatestores.yaml | 2 +- .../config.ratify.deislabs.io_stores.yaml | 5 +++++ .../config.ratify.deislabs.io_verifiers.yaml | 6 ++++++ .../config_v1beta1_verifier_sbom_deny.yaml | 1 + pkg/controllers/store_controller.go | 12 +++++++---- pkg/controllers/verifier_controller.go | 21 +++++++++++-------- 13 files changed, 67 insertions(+), 22 deletions(-) diff --git a/api/v1beta1/store_types.go b/api/v1beta1/store_types.go index c9de67757..d47eadf11 100644 --- a/api/v1beta1/store_types.go +++ b/api/v1beta1/store_types.go @@ -23,10 +23,12 @@ import ( // StoreSpec defines the desired state of Store type StoreSpec struct { - // Important: Run "make" to regenerate code after modifying this file + // Important: Run "make install-crds" to regenerate code after modifying this file // Name of the store - Name string `json:"name,omitempty"` + Name string `json:"name"` + // Version of the store plugin. Optional + Version string `json:"version,omitempty"` // Plugin path, optional Address string `json:"address,omitempty"` // OCI Artifact source to download the plugin from, optional diff --git a/api/v1beta1/verifier_types.go b/api/v1beta1/verifier_types.go index 41668b09c..6f3c6e141 100644 --- a/api/v1beta1/verifier_types.go +++ b/api/v1beta1/verifier_types.go @@ -23,13 +23,16 @@ import ( // VerifierSpec defines the desired state of Verifier type VerifierSpec struct { - // Important: Run "make" to regenerate code after modifying this file + // Important: Run "make install-crds" to regenerate code after modifying this file // Name of the verifier - Name string `json:"name,omitempty"` + Name string `json:"name"` + + // Version of the verifier plugin. Optional + Version string `json:"version,omitempty"` // The type of artifact this verifier handles - ArtifactTypes string `json:"artifactTypes,omitempty"` + ArtifactTypes string `json:"artifactTypes"` // # Optional. URL/file path Address string `json:"address,omitempty"` diff --git a/charts/ratify/crds/store-customresourcedefinition.yaml b/charts/ratify/crds/store-customresourcedefinition.yaml index cfef6bbcf..8827fa0b0 100644 --- a/charts/ratify/crds/store-customresourcedefinition.yaml +++ b/charts/ratify/crds/store-customresourcedefinition.yaml @@ -15,7 +15,7 @@ spec: scope: Cluster versions: - deprecated: true - deprecationWarning: v1alpha1 of the eraser API has been deprecated. Please migrate + deprecationWarning: v1alpha1 of the Store API has been deprecated. Please migrate to v1beta1. name: v1alpha1 schema: @@ -92,6 +92,9 @@ spec: name: description: Name of the store type: string + version: + description: Version of the store plugin. Optional + type: string parameters: description: Parameters of the store type: object @@ -107,7 +110,9 @@ spec: source, optional type: object x-kubernetes-preserve-unknown-fields: true - type: object + type: object + required: + - name type: object status: description: StoreStatus defines the observed state of Store diff --git a/charts/ratify/crds/verifier-customresourcedefinition.yaml b/charts/ratify/crds/verifier-customresourcedefinition.yaml index f5da1f4d0..ccaaddc0e 100644 --- a/charts/ratify/crds/verifier-customresourcedefinition.yaml +++ b/charts/ratify/crds/verifier-customresourcedefinition.yaml @@ -15,7 +15,7 @@ spec: scope: Cluster versions: - deprecated: true - deprecationWarning: v1alpha1 of the eraser API has been deprecated. Please migrate + deprecationWarning: v1alpha1 of the Verifier API has been deprecated. Please migrate to v1beta1. name: v1alpha1 schema: @@ -98,6 +98,9 @@ spec: name: description: Name of the verifier type: string + version: + description: Version of the verifier plugin. Optional + type: string parameters: description: Parameters for this verifier type: object @@ -114,6 +117,9 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true type: object + required: + - artifactTypes + - name type: object status: description: VerifierStatus defines the observed state of Verifier diff --git a/charts/ratify/templates/store.yaml b/charts/ratify/templates/store.yaml index 0af78a2d8..665a75c73 100644 --- a/charts/ratify/templates/store.yaml +++ b/charts/ratify/templates/store.yaml @@ -7,6 +7,7 @@ metadata: helm.sh/hook-weight: "5" spec: name: oras + version: 1.0.0 parameters: {{- if .Values.oras.useHttp }} useHttp: true diff --git a/charts/ratify/templates/verifier.yaml b/charts/ratify/templates/verifier.yaml index 5682d1df5..93b9c5c81 100644 --- a/charts/ratify/templates/verifier.yaml +++ b/charts/ratify/templates/verifier.yaml @@ -9,6 +9,7 @@ metadata: helm.sh/hook-weight: "5" spec: name: notation + version: 1.0.0 artifactTypes: application/vnd.cncf.notary.signature parameters: verificationCertStores: @@ -49,6 +50,7 @@ metadata: helm.sh/hook-weight: "5" spec: name: cosign + version: 1.0.0 artifactTypes: application/vnd.dev.cosign.artifact.sig.v1+json parameters: key: /usr/local/ratify-certs/cosign/cosign.pub @@ -64,6 +66,7 @@ metadata: helm.sh/hook-weight: "5" spec: name: vulnerabilityreport + version: 1.0.0 artifactTypes: application/sarif+json parameters: {{- if .Values.vulnerabilityreport.notaryProjectSignatureRequired }} @@ -103,6 +106,7 @@ metadata: name: verifier-sbom spec: name: sbom + version: 2.0.0-alpha.1 artifactTypes: application/spdx+json parameters: {{- if gt (len .Values.sbom.disallowedPackages) 0 }} diff --git a/config/config.go b/config/config.go index 92a31f2c6..901a0eb74 100644 --- a/config/config.go +++ b/config/config.go @@ -140,6 +140,11 @@ func GetDefaultPluginPath() string { return defaultPluginsPath } +// returns default plugin version of 1.0.0 +func GetDefaultPluginVersion() string { + return "1.0.0" +} + // GetLoggerConfig returns logger configuration from config file at specified path. func GetLoggerConfig(configFilePath string) (logger.Config, error) { config, err := Load(configFilePath) diff --git a/config/crd/bases/config.ratify.deislabs.io_certificatestores.yaml b/config/crd/bases/config.ratify.deislabs.io_certificatestores.yaml index ffd466817..abafa948b 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_stores.yaml b/config/crd/bases/config.ratify.deislabs.io_stores.yaml index d64f7109a..409dc7d19 100644 --- a/config/crd/bases/config.ratify.deislabs.io_stores.yaml +++ b/config/crd/bases/config.ratify.deislabs.io_stores.yaml @@ -93,6 +93,9 @@ spec: name: description: Name of the store type: string + version: + description: Version of the store plugin. Optional + type: string parameters: description: Parameters of the store type: object @@ -109,6 +112,8 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true type: object + required: + - name type: object status: description: StoreStatus defines the observed state of Store diff --git a/config/crd/bases/config.ratify.deislabs.io_verifiers.yaml b/config/crd/bases/config.ratify.deislabs.io_verifiers.yaml index 6d10254a0..36584a928 100644 --- a/config/crd/bases/config.ratify.deislabs.io_verifiers.yaml +++ b/config/crd/bases/config.ratify.deislabs.io_verifiers.yaml @@ -99,6 +99,9 @@ spec: name: description: Name of the verifier type: string + version: + description: Version of the verifier plugin. Optional + type: string parameters: description: Parameters for this verifier type: object @@ -115,6 +118,9 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true type: object + required: + - artifactTypes + - name type: object status: description: VerifierStatus defines the observed state of Verifier diff --git a/config/samples/config_v1beta1_verifier_sbom_deny.yaml b/config/samples/config_v1beta1_verifier_sbom_deny.yaml index 0106e40c8..9497d3350 100644 --- a/config/samples/config_v1beta1_verifier_sbom_deny.yaml +++ b/config/samples/config_v1beta1_verifier_sbom_deny.yaml @@ -4,6 +4,7 @@ metadata: name: verifier-sbom spec: name: sbom + version: 2.0.0-alpha.1 artifactTypes: application/spdx+json parameters: disallowedLicenses: diff --git a/pkg/controllers/store_controller.go b/pkg/controllers/store_controller.go index a12b89af4..5f0b1e13e 100644 --- a/pkg/controllers/store_controller.go +++ b/pkg/controllers/store_controller.go @@ -94,14 +94,18 @@ func storeAddOrReplace(spec configv1beta1.StoreSpec, fullname string) error { if err != nil { return fmt.Errorf("unable to convert store spec to store config, err: %w", err) } - // factory only support a single version of configuration today - // when we support multi version store CRD, we will also pass in the corresponding config version so factory can create different version of the object - storeConfigVersion := "1.0.0" + + // if the default version is not suitable, the plugin configuration should specify the desired version + if len(spec.Version) == 0 { + spec.Version = config.GetDefaultPluginVersion() + logrus.Infof("Version was empty, setting to default version: %v", spec.Version) + } + if spec.Address == "" { spec.Address = config.GetDefaultPluginPath() logrus.Infof("Address was empty, setting to default path %v", spec.Address) } - storeReference, err := sf.CreateStoreFromConfig(storeConfig, storeConfigVersion, []string{spec.Address}) + storeReference, err := sf.CreateStoreFromConfig(storeConfig, spec.Version, []string{spec.Address}) if err != nil || storeReference == nil { logrus.Error(err, "store factory failed to create store from store config") diff --git a/pkg/controllers/verifier_controller.go b/pkg/controllers/verifier_controller.go index f8f6ff829..ee59fb6e0 100644 --- a/pkg/controllers/verifier_controller.go +++ b/pkg/controllers/verifier_controller.go @@ -102,15 +102,18 @@ func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string, na logrus.Error(err, "unable to convert crd specification to verifier config") return fmt.Errorf("unable to convert crd specification to verifier config, err: %w", err) } - // verifier factory only support a single version of configuration today - // when we support multi version verifier CRD, we will also pass in the corresponding config version so factory can create different version of the object - verifierConfigVersion := "1.0.0" // TODO: move default values to defaulting webhook in the future #413 + + if len(spec.Version) == 0 { + spec.Version = config.GetDefaultPluginVersion() + logrus.Infof("Version was empty, setting to default version: %v", spec.Version) + } + if spec.Address == "" { spec.Address = config.GetDefaultPluginPath() logrus.Infof("Address was empty, setting to default path: %v", spec.Address) } - referenceVerifier, err := vf.CreateVerifierFromConfig(verifierConfig, verifierConfigVersion, []string{spec.Address}, namespace) + referenceVerifier, err := vf.CreateVerifierFromConfig(verifierConfig, spec.Version, []string{spec.Address}, namespace) if err != nil || referenceVerifier == nil { logrus.Error(err, "unable to create verifier from verifier config") @@ -155,11 +158,11 @@ func (r *VerifierReconciler) SetupWithManager(mgr ctrl.Manager) error { } // Historically certStore defined in trust policy only contains name which means the CertStore cannot be uniquely identified -// If verifierNamesapce is not empty, this method returns the default cert store namespace else returns the ratify deployed namespace -func getCertStoreNamespace(verifierNamesapce string) (string, error) { - // first, check if we can use the verifier namespace - if verifierNamesapce != "" { - return verifierNamesapce, nil +// If verifierNamespace is not empty, this method returns the default cert store namespace else returns the ratify deployed namespace +func getCertStoreNamespace(verifierNamespace string) (string, error) { + // first, check if we can use the verifier namespace as the cert store namespace + if verifierNamespace != "" { + return verifierNamespace, nil } // next, return the ratify deployed namespace