From 0d420cd9749e536bc4d36d7f15bfbb3c6dce15ba Mon Sep 17 00:00:00 2001 From: JasonPowr <20076537@mail.wit.ie> Date: Fri, 8 Mar 2024 11:17:40 +0000 Subject: [PATCH] fix-fulcio-config --- api/v1alpha1/fulcio_types.go | 11 ++- api/v1alpha1/fulcio_types_test.go | 16 ++-- api/v1alpha1/zz_generated.deepcopy.go | 12 +-- .../rhtas-operator.clusterserviceversion.yaml | 2 +- bundle/manifests/rhtas.redhat.com_ctlogs.yaml | 35 ++++----- .../manifests/rhtas.redhat.com_fulcios.yaml | 59 ++++++++------- bundle/manifests/rhtas.redhat.com_rekors.yaml | 19 ++--- .../rhtas.redhat.com_securesigns.yaml | 73 ++++++++++--------- .../manifests/rhtas.redhat.com_trillians.yaml | 6 +- bundle/manifests/rhtas.redhat.com_tufs.yaml | 8 +- .../crd/bases/rhtas.redhat.com_fulcios.yaml | 30 ++++---- .../bases/rhtas.redhat.com_securesigns.yaml | 30 ++++---- config/samples/rhtas_v1alpha1_fulcio.yaml | 3 +- config/samples/rhtas_v1alpha1_securesign.yaml | 3 +- controllers/fulcio/actions/servrConfig.go | 28 ++++++- controllers/fulcio/fulcio_controller_test.go | 4 +- controllers/fulcio/fulcio_hot_update_test.go | 6 +- e2e/byodb_test.go | 4 +- e2e/common_install_test.go | 7 +- e2e/config_update_test.go | 16 ++-- e2e/key_autodiscovery_test.go | 7 +- e2e/provided_certs_test.go | 7 +- 22 files changed, 218 insertions(+), 168 deletions(-) diff --git a/api/v1alpha1/fulcio_types.go b/api/v1alpha1/fulcio_types.go index 965c3adad..d0ab39485 100644 --- a/api/v1alpha1/fulcio_types.go +++ b/api/v1alpha1/fulcio_types.go @@ -11,6 +11,7 @@ import ( type FulcioSpec struct { // Define whether you want to export service or not ExternalAccess ExternalAccess `json:"externalAccess,omitempty"` + // Fulcio Configuration //+required Config FulcioConfig `json:"config"` // Certificate configuration @@ -44,8 +45,9 @@ type FulcioCert struct { } type FulcioConfig struct { - //+kubebuilder:validation:MinProperties:=1 - OIDCIssuers map[string]OIDCIssuer `json:"OIDCIssuers"` + // OIDC Configuration + // +kubebuilder:validation:MinItems=1 + OIDCIssuers []OIDCIssuer `json:"OIDCIssuers"` // A meta issuer has a templated URL of the form: // https://oidc.eks.*.amazonaws.com/id/* @@ -55,12 +57,13 @@ type FulcioConfig struct { // * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB // * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster // +optional - MetaIssuers map[string]OIDCIssuer `json:"MetaIssuers,omitempty"` + MetaIssuers []OIDCIssuer `json:"MetaIssuers,omitempty"` } type OIDCIssuer struct { // The expected issuer of an OIDC token - IssuerURL string `json:"IssuerURL,omitempty"` + //+required + IssuerURL string `json:"IssuerURL"` // The expected client ID of the OIDC token //+required ClientID string `json:"ClientID"` diff --git a/api/v1alpha1/fulcio_types_test.go b/api/v1alpha1/fulcio_types_test.go index c1a2799c3..c71970e2c 100644 --- a/api/v1alpha1/fulcio_types_test.go +++ b/api/v1alpha1/fulcio_types_test.go @@ -29,7 +29,7 @@ var _ = Describe("Fulcio", func() { Expect(k8sClient.Get(context.Background(), getKey(created), fetched)).To(Succeed()) Expect(fetched).To(Equal(created)) - fetched.Spec.Config.OIDCIssuers["test"] = OIDCIssuer{ + fetched.Spec.Config.OIDCIssuers[0] = OIDCIssuer{ Type: "email", ClientID: "client", } @@ -128,11 +128,11 @@ var _ = Describe("Fulcio", func() { It("config is not empty", func() { invalidObject := generateFulcioObject("config-invalid") - invalidObject.Spec.Config.OIDCIssuers = make(map[string]OIDCIssuer) + invalidObject.Spec.Config.OIDCIssuers = []OIDCIssuer{} Expect(apierrors.IsInvalid(k8sClient.Create(context.Background(), invalidObject))).To(BeTrue()) Expect(k8sClient.Create(context.Background(), invalidObject)). - To(MatchError(ContainSubstring("in body should have at least 1 properties"))) + To(MatchError(ContainSubstring("in body should have at least 1 items"))) }) }) @@ -170,8 +170,8 @@ var _ = Describe("Fulcio", func() { Host: "hostname", }, Config: FulcioConfig{ - OIDCIssuers: map[string]OIDCIssuer{ - "oidc": { + OIDCIssuers: []OIDCIssuer{ + { ClientID: "client", Type: "email", IssuerURL: "url", @@ -180,7 +180,7 @@ var _ = Describe("Fulcio", func() { SPIFFETrustDomain: "SPIFFE", SubjectDomain: "domain", }, - "oidc2": { + { ClientID: "clien2", Type: "email2", IssuerURL: "url2", @@ -220,8 +220,8 @@ func generateFulcioObject(name string) *Fulcio { }, Spec: FulcioSpec{ Config: FulcioConfig{ - OIDCIssuers: map[string]OIDCIssuer{ - "oidc": { + OIDCIssuers: []OIDCIssuer{ + { ClientID: "client", Type: "email", IssuerURL: "url", diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e0a605e10..30d6712bb 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -268,17 +268,13 @@ func (in *FulcioConfig) DeepCopyInto(out *FulcioConfig) { *out = *in if in.OIDCIssuers != nil { in, out := &in.OIDCIssuers, &out.OIDCIssuers - *out = make(map[string]OIDCIssuer, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + *out = make([]OIDCIssuer, len(*in)) + copy(*out, *in) } if in.MetaIssuers != nil { in, out := &in.MetaIssuers, &out.MetaIssuers - *out = make(map[string]OIDCIssuer, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + *out = make([]OIDCIssuer, len(*in)) + copy(*out, *in) } } diff --git a/bundle/manifests/rhtas-operator.clusterserviceversion.yaml b/bundle/manifests/rhtas-operator.clusterserviceversion.yaml index 5d7d944b9..b8d607e8d 100644 --- a/bundle/manifests/rhtas-operator.clusterserviceversion.yaml +++ b/bundle/manifests/rhtas-operator.clusterserviceversion.yaml @@ -186,7 +186,7 @@ metadata: } ] capabilities: Basic Install - createdAt: "2024-03-05T14:59:04Z" + createdAt: "2024-03-08T11:05:02Z" operators.operatorframework.io/builder: operator-sdk-v1.32.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 name: rhtas-operator.v1.0.0 diff --git a/bundle/manifests/rhtas.redhat.com_ctlogs.yaml b/bundle/manifests/rhtas.redhat.com_ctlogs.yaml index ce940e18e..91befbd76 100644 --- a/bundle/manifests/rhtas.redhat.com_ctlogs.yaml +++ b/bundle/manifests/rhtas.redhat.com_ctlogs.yaml @@ -50,16 +50,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic privateKeyRef: @@ -68,16 +68,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic publicKeyRef: @@ -89,16 +89,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic rootCertificates: @@ -111,16 +111,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: array @@ -217,16 +217,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic privateKeyRef: @@ -235,16 +235,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic publicKeyRef: @@ -253,16 +253,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic rootCertificates: @@ -272,16 +272,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: array @@ -294,8 +294,9 @@ spec: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string + required: + - name type: object x-kubernetes-map-type: atomic type: object diff --git a/bundle/manifests/rhtas.redhat.com_fulcios.yaml b/bundle/manifests/rhtas.redhat.com_fulcios.yaml index c9ba56995..2572f2b8c 100644 --- a/bundle/manifests/rhtas.redhat.com_fulcios.yaml +++ b/bundle/manifests/rhtas.redhat.com_fulcios.yaml @@ -57,16 +57,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic commonName: @@ -81,16 +81,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic privateKeyRef: @@ -99,28 +99,39 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: object x-kubernetes-validations: - message: commonName cannot be empty rule: (has(self.caRef) || self.commonName != "") + - message: organizationName cannot be empty + rule: (has(self.caRef) || self.organizationName != "") - message: privateKeyRef cannot be empty rule: (!has(self.caRef) || has(self.privateKeyRef)) config: + description: Fulcio Configuration properties: MetaIssuers: - additionalProperties: + description: |- + A meta issuer has a templated URL of the form: + https://oidc.eks.*.amazonaws.com/id/* + Where * can match a single hostname or URI path parts + (in particular, no '.' or '/' are permitted, among + other special characters) Some examples we want to match: + * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB + * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster + items: properties: ChallengeClaim: description: |- @@ -157,17 +168,10 @@ spec: - ClientID - Type type: object - description: |- - A meta issuer has a templated URL of the form: - https://oidc.eks.*.amazonaws.com/id/* - Where * can match a single hostname or URI path parts - (in particular, no '.' or '/' are permitted, among - other special characters) Some examples we want to match: - * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB - * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster - type: object + type: array OIDCIssuers: - additionalProperties: + description: OIDC Configuration + items: properties: ChallengeClaim: description: |- @@ -204,8 +208,8 @@ spec: - ClientID - Type type: object - minProperties: 1 - type: object + minItems: 1 + type: array required: - OIDCIssuers type: object @@ -256,16 +260,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic commonName: @@ -280,16 +284,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic privateKeyRef: @@ -298,22 +302,24 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: object x-kubernetes-validations: - message: commonName cannot be empty rule: (has(self.caRef) || self.commonName != "") + - message: organizationName cannot be empty + rule: (has(self.caRef) || self.organizationName != "") - message: privateKeyRef cannot be empty rule: (!has(self.caRef) || has(self.privateKeyRef)) conditions: @@ -397,8 +403,9 @@ spec: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string + required: + - name type: object x-kubernetes-map-type: atomic url: diff --git a/bundle/manifests/rhtas.redhat.com_rekors.yaml b/bundle/manifests/rhtas.redhat.com_rekors.yaml index 74fce455d..1cc0fd6e1 100644 --- a/bundle/manifests/rhtas.redhat.com_rekors.yaml +++ b/bundle/manifests/rhtas.redhat.com_rekors.yaml @@ -160,16 +160,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic kms: @@ -183,16 +183,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: object @@ -291,8 +291,9 @@ spec: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string + required: + - name type: object x-kubernetes-map-type: atomic signer: @@ -303,16 +304,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic kms: @@ -326,16 +327,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: object diff --git a/bundle/manifests/rhtas.redhat.com_securesigns.yaml b/bundle/manifests/rhtas.redhat.com_securesigns.yaml index e8de2c90a..048ae7d42 100644 --- a/bundle/manifests/rhtas.redhat.com_securesigns.yaml +++ b/bundle/manifests/rhtas.redhat.com_securesigns.yaml @@ -65,16 +65,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic privateKeyRef: @@ -83,16 +83,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic publicKeyRef: @@ -104,16 +104,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic rootCertificates: @@ -126,16 +126,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: array @@ -163,16 +163,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic commonName: @@ -187,16 +187,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic privateKeyRef: @@ -205,28 +205,39 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: object x-kubernetes-validations: - message: commonName cannot be empty rule: (has(self.caRef) || self.commonName != "") + - message: organizationName cannot be empty + rule: (has(self.caRef) || self.organizationName != "") - message: privateKeyRef cannot be empty rule: (!has(self.caRef) || has(self.privateKeyRef)) config: + description: Fulcio Configuration properties: MetaIssuers: - additionalProperties: + description: |- + A meta issuer has a templated URL of the form: + https://oidc.eks.*.amazonaws.com/id/* + Where * can match a single hostname or URI path parts + (in particular, no '.' or '/' are permitted, among + other special characters) Some examples we want to match: + * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB + * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster + items: properties: ChallengeClaim: description: |- @@ -263,17 +274,10 @@ spec: - ClientID - Type type: object - description: |- - A meta issuer has a templated URL of the form: - https://oidc.eks.*.amazonaws.com/id/* - Where * can match a single hostname or URI path parts - (in particular, no '.' or '/' are permitted, among - other special characters) Some examples we want to match: - * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB - * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster - type: object + type: array OIDCIssuers: - additionalProperties: + description: OIDC Configuration + items: properties: ChallengeClaim: description: |- @@ -310,8 +314,8 @@ spec: - ClientID - Type type: object - minProperties: 1 - type: object + minItems: 1 + type: array required: - OIDCIssuers type: object @@ -467,16 +471,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic kms: @@ -491,16 +495,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic type: object @@ -543,8 +547,9 @@ spec: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string + required: + - name type: object x-kubernetes-map-type: atomic pvc: @@ -638,16 +643,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic required: diff --git a/bundle/manifests/rhtas.redhat.com_trillians.yaml b/bundle/manifests/rhtas.redhat.com_trillians.yaml index 1e81fc851..de8cfe443 100644 --- a/bundle/manifests/rhtas.redhat.com_trillians.yaml +++ b/bundle/manifests/rhtas.redhat.com_trillians.yaml @@ -73,8 +73,9 @@ spec: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string + required: + - name type: object x-kubernetes-map-type: atomic pvc: @@ -219,8 +220,9 @@ spec: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string + required: + - name type: object x-kubernetes-map-type: atomic pvc: diff --git a/bundle/manifests/rhtas.redhat.com_tufs.yaml b/bundle/manifests/rhtas.redhat.com_tufs.yaml index 6a309917e..b663d685f 100644 --- a/bundle/manifests/rhtas.redhat.com_tufs.yaml +++ b/bundle/manifests/rhtas.redhat.com_tufs.yaml @@ -87,16 +87,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic required: @@ -202,16 +202,16 @@ spec: key: description: The key of the secret to select from. Must be a valid secret key. - pattern: '[-._a-zA-Z0-9]+' + pattern: ^[-._a-zA-Z0-9]+$ type: string name: description: |- Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string required: - key + - name type: object x-kubernetes-map-type: atomic required: diff --git a/config/crd/bases/rhtas.redhat.com_fulcios.yaml b/config/crd/bases/rhtas.redhat.com_fulcios.yaml index 77271fd5d..715c8cfbe 100644 --- a/config/crd/bases/rhtas.redhat.com_fulcios.yaml +++ b/config/crd/bases/rhtas.redhat.com_fulcios.yaml @@ -120,9 +120,18 @@ spec: - message: privateKeyRef cannot be empty rule: (!has(self.caRef) || has(self.privateKeyRef)) config: + description: Fulcio Configuration properties: MetaIssuers: - additionalProperties: + description: |- + A meta issuer has a templated URL of the form: + https://oidc.eks.*.amazonaws.com/id/* + Where * can match a single hostname or URI path parts + (in particular, no '.' or '/' are permitted, among + other special characters) Some examples we want to match: + * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB + * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster + items: properties: ChallengeClaim: description: |- @@ -157,19 +166,13 @@ spec: type: string required: - ClientID + - IssuerURL - Type type: object - description: |- - A meta issuer has a templated URL of the form: - https://oidc.eks.*.amazonaws.com/id/* - Where * can match a single hostname or URI path parts - (in particular, no '.' or '/' are permitted, among - other special characters) Some examples we want to match: - * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB - * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster - type: object + type: array OIDCIssuers: - additionalProperties: + description: OIDC Configuration + items: properties: ChallengeClaim: description: |- @@ -204,10 +207,11 @@ spec: type: string required: - ClientID + - IssuerURL - Type type: object - minProperties: 1 - type: object + minItems: 1 + type: array required: - OIDCIssuers type: object diff --git a/config/crd/bases/rhtas.redhat.com_securesigns.yaml b/config/crd/bases/rhtas.redhat.com_securesigns.yaml index b03958adb..4a8ea0776 100644 --- a/config/crd/bases/rhtas.redhat.com_securesigns.yaml +++ b/config/crd/bases/rhtas.redhat.com_securesigns.yaml @@ -226,9 +226,18 @@ spec: - message: privateKeyRef cannot be empty rule: (!has(self.caRef) || has(self.privateKeyRef)) config: + description: Fulcio Configuration properties: MetaIssuers: - additionalProperties: + description: |- + A meta issuer has a templated URL of the form: + https://oidc.eks.*.amazonaws.com/id/* + Where * can match a single hostname or URI path parts + (in particular, no '.' or '/' are permitted, among + other special characters) Some examples we want to match: + * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB + * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster + items: properties: ChallengeClaim: description: |- @@ -263,19 +272,13 @@ spec: type: string required: - ClientID + - IssuerURL - Type type: object - description: |- - A meta issuer has a templated URL of the form: - https://oidc.eks.*.amazonaws.com/id/* - Where * can match a single hostname or URI path parts - (in particular, no '.' or '/' are permitted, among - other special characters) Some examples we want to match: - * https://oidc.eks.us-west-2.amazonaws.com/id/B02C93B6A2D30341AD01E1B6D48164CB - * https://container.googleapis.com/v1/projects/mattmoor-credit/locations/us-west1-b/clusters/tenant-cluster - type: object + type: array OIDCIssuers: - additionalProperties: + description: OIDC Configuration + items: properties: ChallengeClaim: description: |- @@ -310,10 +313,11 @@ spec: type: string required: - ClientID + - IssuerURL - Type type: object - minProperties: 1 - type: object + minItems: 1 + type: array required: - OIDCIssuers type: object diff --git a/config/samples/rhtas_v1alpha1_fulcio.yaml b/config/samples/rhtas_v1alpha1_fulcio.yaml index 1013fc448..3337dd22e 100644 --- a/config/samples/rhtas_v1alpha1_fulcio.yaml +++ b/config/samples/rhtas_v1alpha1_fulcio.yaml @@ -11,8 +11,7 @@ spec: enabled: true config: OIDCIssuers: - "https://your-oidc-issuer-url": - ClientID: "trusted-artifact-signer" + - ClientID: "trusted-artifact-signer" IssuerURL: "https://your-oidc-issuer-url" Type: "email" certificate: diff --git a/config/samples/rhtas_v1alpha1_securesign.yaml b/config/samples/rhtas_v1alpha1_securesign.yaml index 665fe48fe..7c591421a 100644 --- a/config/samples/rhtas_v1alpha1_securesign.yaml +++ b/config/samples/rhtas_v1alpha1_securesign.yaml @@ -20,8 +20,7 @@ spec: enabled: true config: OIDCIssuers: - "https://your-oidc-issuer-url": - ClientID: "trusted-artifact-signer" + - ClientID: "trusted-artifact-signer" IssuerURL: "https://your-oidc-issuer-url" Type: "email" certificate: diff --git a/controllers/fulcio/actions/servrConfig.go b/controllers/fulcio/actions/servrConfig.go index a4eeea415..d863a7a37 100644 --- a/controllers/fulcio/actions/servrConfig.go +++ b/controllers/fulcio/actions/servrConfig.go @@ -27,6 +27,11 @@ func (i serverConfig) Name() string { return "create server config" } +type FulcioMapConfig struct { + OIDCIssuers map[string]rhtasv1alpha1.OIDCIssuer + MetaIssuers map[string]rhtasv1alpha1.OIDCIssuer +} + func (i serverConfig) CanHandle(ctx context.Context, instance *rhtasv1alpha1.Fulcio) bool { c := meta.FindStatusCondition(instance.Status.Conditions, constants.Ready) if c.Reason != constants.Creating && c.Reason != constants.Ready { @@ -41,7 +46,7 @@ func (i serverConfig) CanHandle(ctx context.Context, instance *rhtasv1alpha1.Ful i.Logger.Error(err, "Cant load existing configuration") return false } - expected, err := json.Marshal(instance.Spec.Config) + expected, err := json.Marshal(ConvertToFulcioMapConfig(instance.Spec.Config)) if err != nil { i.Logger.Error(err, "Cant parse expected configuration") return false @@ -49,13 +54,32 @@ func (i serverConfig) CanHandle(ctx context.Context, instance *rhtasv1alpha1.Ful return existing.Data["config.json"] != string(expected) } +func ConvertToFulcioMapConfig(fulcioConfig rhtasv1alpha1.FulcioConfig) *FulcioMapConfig { + OIDCIssuers := make(map[string]rhtasv1alpha1.OIDCIssuer) + MetaIssuers := make(map[string]rhtasv1alpha1.OIDCIssuer) + + for _, issuer := range fulcioConfig.OIDCIssuers { + OIDCIssuers[issuer.IssuerURL] = issuer + } + + for _, issuer := range fulcioConfig.MetaIssuers { + MetaIssuers[issuer.IssuerURL] = issuer + } + + fulcioMapConfig := &FulcioMapConfig{ + OIDCIssuers: OIDCIssuers, + MetaIssuers: MetaIssuers, + } + return fulcioMapConfig +} + func (i serverConfig) Handle(ctx context.Context, instance *rhtasv1alpha1.Fulcio) *action.Result { var ( err error ) labels := constants.LabelsFor(ComponentName, DeploymentName, instance.Name) - config, err := json.Marshal(instance.Spec.Config) + config, err := json.Marshal(ConvertToFulcioMapConfig(instance.Spec.Config)) if err != nil { return i.FailedWithStatusUpdate(ctx, err, instance) } diff --git a/controllers/fulcio/fulcio_controller_test.go b/controllers/fulcio/fulcio_controller_test.go index 54ddf4b4b..581dbc6c4 100644 --- a/controllers/fulcio/fulcio_controller_test.go +++ b/controllers/fulcio/fulcio_controller_test.go @@ -96,8 +96,8 @@ var _ = Describe("Fulcio controller", func() { Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - "test": { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { IssuerURL: "test", ClientID: "test", Type: "email", diff --git a/controllers/fulcio/fulcio_hot_update_test.go b/controllers/fulcio/fulcio_hot_update_test.go index 22ca694d8..dbdf59e06 100644 --- a/controllers/fulcio/fulcio_hot_update_test.go +++ b/controllers/fulcio/fulcio_hot_update_test.go @@ -95,8 +95,8 @@ var _ = Describe("Fulcio hot update", func() { Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - "test": { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { IssuerURL: "test", ClientID: "test", Type: "email", @@ -189,7 +189,7 @@ var _ = Describe("Fulcio hot update", func() { By("Update OIDC") Expect(k8sClient.Get(ctx, typeNamespaceName, found)).Should(Succeed()) - found.Spec.Config.OIDCIssuers["fakeProvider"] = v1alpha1.OIDCIssuer{ + found.Spec.Config.OIDCIssuers[0] = v1alpha1.OIDCIssuer{ IssuerURL: "fake", ClientID: "fake", Type: "email", diff --git a/e2e/byodb_test.go b/e2e/byodb_test.go index e1fdb4911..a739e56f7 100644 --- a/e2e/byodb_test.go +++ b/e2e/byodb_test.go @@ -56,8 +56,8 @@ var _ = Describe("Securesign install with byodb", Ordered, func() { Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - support.OidcIssuerUrl(): { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { ClientID: support.OidcClientID(), IssuerURL: support.OidcIssuerUrl(), Type: "email", diff --git a/e2e/common_install_test.go b/e2e/common_install_test.go index 5cfe8db36..4c4d4d903 100644 --- a/e2e/common_install_test.go +++ b/e2e/common_install_test.go @@ -4,10 +4,11 @@ package e2e_test import ( "context" - "github.com/securesign/operator/controllers/common/utils" "net/http" "time" + "github.com/securesign/operator/controllers/common/utils" + "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -60,8 +61,8 @@ var _ = Describe("Securesign install with certificate generation", Ordered, func Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - support.OidcIssuerUrl(): { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { ClientID: support.OidcClientID(), IssuerURL: support.OidcIssuerUrl(), Type: "email", diff --git a/e2e/config_update_test.go b/e2e/config_update_test.go index c1644971d..7877284e7 100644 --- a/e2e/config_update_test.go +++ b/e2e/config_update_test.go @@ -5,9 +5,11 @@ package e2e_test import ( "context" "encoding/json" - "github.com/securesign/operator/controllers/common/utils" "time" + "github.com/securesign/operator/controllers/common/utils" + "github.com/securesign/operator/controllers/fulcio/actions" + "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -62,8 +64,8 @@ var _ = Describe("Securesign hot update", Ordered, func() { Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - support.OidcIssuerUrl(): { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { ClientID: support.OidcClientID(), IssuerURL: support.OidcIssuerUrl(), Type: "email", @@ -170,13 +172,13 @@ var _ = Describe("Securesign hot update", Ordered, func() { Describe("Fulcio Config update", func() { It("Pods are restarted after update", func() { Expect(cli.Get(ctx, runtimeCli.ObjectKeyFromObject(securesign), securesign)).To(Succeed()) - securesign.Spec.Fulcio.Config.OIDCIssuers = map[string]v1alpha1.OIDCIssuer{ - support.OidcIssuerUrl(): { + securesign.Spec.Fulcio.Config.OIDCIssuers = []v1alpha1.OIDCIssuer{ + { ClientID: support.OidcClientID(), IssuerURL: support.OidcIssuerUrl(), Type: "email", }, - "fake": { + { ClientID: "fake", IssuerURL: "fake", Type: "email", @@ -196,7 +198,7 @@ var _ = Describe("Securesign hot update", Ordered, func() { cm := &v1.ConfigMap{} Expect(cli.Get(ctx, types.NamespacedName{Namespace: namespace.Name, Name: fulcio.Status.ServerConfigRef.Name}, cm)).To(Succeed()) - config := &v1alpha1.FulcioConfig{} + config := &actions.FulcioMapConfig{} Expect(json.Unmarshal([]byte(cm.Data["config.json"]), config)).To(Succeed()) Expect(config.OIDCIssuers).To(HaveKey("fake")) }) diff --git a/e2e/key_autodiscovery_test.go b/e2e/key_autodiscovery_test.go index 6daf40349..34a6a0be7 100644 --- a/e2e/key_autodiscovery_test.go +++ b/e2e/key_autodiscovery_test.go @@ -4,9 +4,10 @@ package e2e_test import ( "context" - "github.com/securesign/operator/controllers/common/utils" "time" + "github.com/securesign/operator/controllers/common/utils" + "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -64,8 +65,8 @@ var _ = Describe("Securesign key autodiscovery test", Ordered, func() { Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - support.OidcIssuerUrl(): { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { ClientID: support.OidcClientID(), IssuerURL: support.OidcIssuerUrl(), Type: "email", diff --git a/e2e/provided_certs_test.go b/e2e/provided_certs_test.go index 246b4ddcd..28c3ba37b 100644 --- a/e2e/provided_certs_test.go +++ b/e2e/provided_certs_test.go @@ -10,10 +10,11 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" - "github.com/securesign/operator/controllers/common/utils" "math/big" "time" + "github.com/securesign/operator/controllers/common/utils" + "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -72,8 +73,8 @@ var _ = Describe("Securesign install with provided certs", Ordered, func() { Enabled: true, }, Config: v1alpha1.FulcioConfig{ - OIDCIssuers: map[string]v1alpha1.OIDCIssuer{ - support.OidcIssuerUrl(): { + OIDCIssuers: []v1alpha1.OIDCIssuer{ + { ClientID: support.OidcClientID(), IssuerURL: support.OidcIssuerUrl(), Type: "email",