From e09e726275831b23069fc82339956c2e04017732 Mon Sep 17 00:00:00 2001 From: Terin Stock Date: Sat, 28 Sep 2024 18:12:09 +0200 Subject: [PATCH] feat(types): make ServiceKeyRef optional Prepare to allow multiple authentication types by allowing ServiceKeyRef to become nil, and requiring the controllers to properly handle no authentication types being set. Bug: #135 --- pkgs/apis/v1/types_originissuer.go | 2 +- pkgs/apis/v1/zz_generated.deepcopy.go | 12 ++-- pkgs/controllers/certificaterequest.go | 60 ++++++++++++-------- pkgs/controllers/certificaterequest_test.go | 49 ++++++++++++++-- pkgs/controllers/clusteroriginissuer.go | 46 ++++++++------- pkgs/controllers/clusteroriginissuer_test.go | 42 ++++++++++++-- pkgs/controllers/originissuer.go | 50 ++++++++-------- pkgs/controllers/originissuer_suite_test.go | 2 +- pkgs/controllers/originissuer_test.go | 42 ++++++++++++-- 9 files changed, 212 insertions(+), 93 deletions(-) diff --git a/pkgs/apis/v1/types_originissuer.go b/pkgs/apis/v1/types_originissuer.go index 7e48798..1826399 100644 --- a/pkgs/apis/v1/types_originissuer.go +++ b/pkgs/apis/v1/types_originissuer.go @@ -84,7 +84,7 @@ type OriginIssuerStatus struct { type OriginIssuerAuthentication struct { // ServiceKeyRef authenticates with an API Service Key. // +optional - ServiceKeyRef SecretKeySelector `json:"serviceKeyRef,omitempty"` + ServiceKeyRef *SecretKeySelector `json:"serviceKeyRef,omitempty"` } // SecretKeySelector contains a reference to a secret. diff --git a/pkgs/apis/v1/zz_generated.deepcopy.go b/pkgs/apis/v1/zz_generated.deepcopy.go index 477e1c5..cde284b 100644 --- a/pkgs/apis/v1/zz_generated.deepcopy.go +++ b/pkgs/apis/v1/zz_generated.deepcopy.go @@ -13,7 +13,7 @@ func (in *ClusterOriginIssuer) DeepCopyInto(out *ClusterOriginIssuer) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) } @@ -72,7 +72,7 @@ func (in *OriginIssuer) DeepCopyInto(out *OriginIssuer) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) } @@ -97,7 +97,11 @@ func (in *OriginIssuer) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OriginIssuerAuthentication) DeepCopyInto(out *OriginIssuerAuthentication) { *out = *in - out.ServiceKeyRef = in.ServiceKeyRef + if in.ServiceKeyRef != nil { + in, out := &in.ServiceKeyRef, &out.ServiceKeyRef + *out = new(SecretKeySelector) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OriginIssuerAuthentication. @@ -164,7 +168,7 @@ func (in *OriginIssuerList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OriginIssuerSpec) DeepCopyInto(out *OriginIssuerSpec) { *out = *in - out.Auth = in.Auth + in.Auth.DeepCopyInto(&out.Auth) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OriginIssuerSpec. diff --git a/pkgs/controllers/certificaterequest.go b/pkgs/controllers/certificaterequest.go index d4296a4..5faf74f 100644 --- a/pkgs/controllers/certificaterequest.go +++ b/pkgs/controllers/certificaterequest.go @@ -112,8 +112,8 @@ func (r *CertificateRequestController) Reconcile(ctx context.Context, cr *certma } var ( - secretNamespaceName types.NamespacedName - issuerspec v1.OriginIssuerSpec + secretNamespace string + issuerspec v1.OriginIssuerSpec ) switch cr.Spec.IssuerRef.Kind { @@ -139,10 +139,7 @@ func (r *CertificateRequestController) Reconcile(ctx context.Context, cr *certma return reconcile.Result{}, err } - secretNamespaceName = types.NamespacedName{ - Namespace: iss.Namespace, - Name: iss.Spec.Auth.ServiceKeyRef.Name, - } + secretNamespace = iss.Namespace issuerspec = iss.Spec case "ClusterOriginIssuer": iss := v1.ClusterOriginIssuer{} @@ -165,10 +162,7 @@ func (r *CertificateRequestController) Reconcile(ctx context.Context, cr *certma return reconcile.Result{}, err } - secretNamespaceName = types.NamespacedName{ - Namespace: r.ClusterResourceNamespace, - Name: iss.Spec.Auth.ServiceKeyRef.Name, - } + secretNamespace = r.ClusterResourceNamespace issuerspec = iss.Spec default: err := fmt.Errorf("unknown issuer kind: %s", cr.Spec.IssuerRef.Kind) @@ -178,28 +172,44 @@ func (r *CertificateRequestController) Reconcile(ctx context.Context, cr *certma return reconcile.Result{}, err } - var secret core.Secret - if err := r.Reader.Get(ctx, secretNamespaceName, &secret); err != nil { - log.Error(err, "failed to retieve OriginIssuer auth secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name) - if apierrors.IsNotFound(err) { - _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - } else { - _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, "Error", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + var c *cfapi.Client + switch { + case issuerspec.Auth.ServiceKeyRef != nil: + var secret core.Secret + + secretNamespaceName := types.NamespacedName{ + Namespace: secretNamespace, + Name: issuerspec.Auth.ServiceKeyRef.Name, } - return reconcile.Result{}, err - } + if err := r.Reader.Get(ctx, secretNamespaceName, &secret); err != nil { + log.Error(err, "failed to retieve OriginIssuer auth secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name) + if apierrors.IsNotFound(err) { + _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + } else { + _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, "Error", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + } + + return reconcile.Result{}, err + } - serviceKey, ok := secret.Data[issuerspec.Auth.ServiceKeyRef.Key] - if !ok { - err := fmt.Errorf("secret %s does not contain key %q", secret.Name, issuerspec.Auth.ServiceKeyRef.Key) - log.Error(err, "failed to retrieve OriginIssuer auth secret") - _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + serviceKey, ok := secret.Data[issuerspec.Auth.ServiceKeyRef.Key] + if !ok { + err := fmt.Errorf("secret %s does not contain key %q", secret.Name, issuerspec.Auth.ServiceKeyRef.Key) + log.Error(err, "failed to retrieve OriginIssuer auth secret") + _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + return reconcile.Result{}, err + } + + c = r.Builder.Clone().WithServiceKey(serviceKey).Build() + default: + // This issuer should not be ready! + err := fmt.Errorf("issuer %s does not have an authentication method configured", cr.Spec.IssuerRef.Name) + log.Error(err, "failed to retrieve issuer auth secret") return reconcile.Result{}, err } - c := r.Builder.Clone().WithServiceKey(serviceKey).Build() p, err := provisioners.New(c, issuerspec.RequestType, log) if err != nil { log.Error(err, "failed to create provisioner") diff --git a/pkgs/controllers/certificaterequest_test.go b/pkgs/controllers/certificaterequest_test.go index be90efd..f9a2f2d 100644 --- a/pkgs/controllers/certificaterequest_test.go +++ b/pkgs/controllers/certificaterequest_test.go @@ -49,7 +49,7 @@ func TestCertificateRequestReconcile(t *testing.T) { namespaceName types.NamespacedName }{ { - name: "working OriginIssuer", + name: "working OriginIssuer with serviceKeyRef", objects: []runtime.Object{ cmgen.CertificateRequest("foobar", cmgen.SetCertificateRequestNamespace("default"), @@ -69,7 +69,7 @@ func TestCertificateRequestReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginECC, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "service-key-issuer", Key: "key", }, @@ -113,7 +113,7 @@ func TestCertificateRequestReconcile(t *testing.T) { }, }, { - name: "working ClusterOriginIssuer", + name: "working ClusterOriginIssuer with serviceKeyRef", objects: []runtime.Object{ cmgen.CertificateRequest("foobar", cmgen.SetCertificateRequestNamespace("default"), @@ -132,7 +132,7 @@ func TestCertificateRequestReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginECC, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "service-key-issuer", Key: "key", }, @@ -175,6 +175,41 @@ func TestCertificateRequestReconcile(t *testing.T) { Name: "foobar", }, }, + { + name: "OriginIssuer without authentication", + objects: []runtime.Object{ + cmgen.CertificateRequest("foobar", + cmgen.SetCertificateRequestNamespace("default"), + cmgen.SetCertificateRequestDuration(&metav1.Duration{Duration: 7 * 24 * time.Hour}), + cmgen.SetCertificateRequestCSR(golden.Get(t, "csr.golden")), + cmgen.SetCertificateRequestIssuer(cmmeta.ObjectReference{ + Name: "foobar", + Kind: "OriginIssuer", + Group: "cert-manager.k8s.cloudflare.com", + }), + ), + &v1.OriginIssuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foobar", + Namespace: "default", + }, + Spec: v1.OriginIssuerSpec{}, + Status: v1.OriginIssuerStatus{ + Conditions: []v1.OriginIssuerCondition{ + { + Type: v1.ConditionReady, + Status: v1.ConditionTrue, + }, + }, + }, + }, + }, + namespaceName: types.NamespacedName{ + Namespace: "default", + Name: "foobar", + }, + error: "issuer foobar does not have an authentication method configured", + }, { name: "requeue after API error", objects: []runtime.Object{ @@ -196,7 +231,7 @@ func TestCertificateRequestReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginECC, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "service-key-issuer", Key: "key", }, @@ -239,7 +274,9 @@ func TestCertificateRequestReconcile(t *testing.T) { WithStatusSubresource(&cmapi.CertificateRequest{}). Build() - defer tt.recorder.Stop() + if tt.recorder != nil { + defer tt.recorder.Stop() + } controller := &CertificateRequestController{ Client: client, diff --git a/pkgs/controllers/clusteroriginissuer.go b/pkgs/controllers/clusteroriginissuer.go index 7d1a941..c09a0d3 100644 --- a/pkgs/controllers/clusteroriginissuer.go +++ b/pkgs/controllers/clusteroriginissuer.go @@ -41,31 +41,37 @@ func (r *ClusterOriginIssuerController) Reconcile(ctx context.Context, iss *v1.C return reconcile.Result{}, err } - secret := core.Secret{} - secretNamespaceName := types.NamespacedName{ - Namespace: r.ClusterResourceNamespace, - Name: iss.Spec.Auth.ServiceKeyRef.Name, - } + switch { + case iss.Spec.Auth.ServiceKeyRef != nil: + secret := &core.Secret{} + secretNamespaceName := types.NamespacedName{ + Namespace: r.ClusterResourceNamespace, + Name: iss.Spec.Auth.ServiceKeyRef.Name, + } - if err := r.Reader.Get(ctx, secretNamespaceName, &secret); err != nil { - log.Error(err, "failed to retieve ClusterOriginIssuer auth secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name) + if err := r.Reader.Get(ctx, secretNamespaceName, secret); err != nil { + log.Error(err, "failed to retieve ClusterOriginIssuer auth secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name) - if apierrors.IsNotFound(err) { - _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - } else { - _ = r.setStatus(ctx, iss, v1.ConditionFalse, "Error", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - } + if apierrors.IsNotFound(err) { + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + } else { + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "Error", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + } - return reconcile.Result{}, err - } + return reconcile.Result{}, err + } - _, ok := secret.Data[iss.Spec.Auth.ServiceKeyRef.Key] - if !ok { - err := fmt.Errorf("secret %s does not contain key %q", secret.Name, iss.Spec.Auth.ServiceKeyRef.Key) - log.Error(err, "failed to retrieve ClusterOriginIssuer auth secret") - _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + _, ok := secret.Data[iss.Spec.Auth.ServiceKeyRef.Key] + if !ok { + err := fmt.Errorf("secret %s does not contain key %q", secret.Name, iss.Spec.Auth.ServiceKeyRef.Key) + log.Error(err, "failed to retrieve ClusterOriginIssuer auth secret") + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - return reconcile.Result{}, err + return reconcile.Result{}, err + } + default: + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "MissingAuthentication", "No authentication methods were configured") + return reconcile.Result{}, nil } return reconcile.Result{}, r.setStatus(ctx, iss, v1.ConditionTrue, "Verified", "ClusterOriginIssuer verified and ready to sign certificates") diff --git a/pkgs/controllers/clusteroriginissuer_test.go b/pkgs/controllers/clusteroriginissuer_test.go index c3426d0..eae5dd9 100644 --- a/pkgs/controllers/clusteroriginissuer_test.go +++ b/pkgs/controllers/clusteroriginissuer_test.go @@ -39,7 +39,7 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { namespaceName types.NamespacedName }{ { - name: "working with secrets", + name: "working serviceKeyRef", objects: []runtime.Object{ &v1.ClusterOriginIssuer{ ObjectMeta: metav1.ObjectMeta{ @@ -48,7 +48,7 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, @@ -81,7 +81,7 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { }, }, { - name: "missing secret", + name: "missing serviceKeyRef", objects: []runtime.Object{ &v1.ClusterOriginIssuer{ ObjectMeta: metav1.ObjectMeta{ @@ -90,7 +90,7 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, @@ -115,7 +115,7 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { }, }, { - name: "secret missing key", + name: "serviceKeyRef missing key", objects: []runtime.Object{ &v1.ClusterOriginIssuer{ ObjectMeta: metav1.ObjectMeta{ @@ -124,7 +124,7 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, @@ -155,6 +155,36 @@ func TestClusterOriginIssuerReconcile(t *testing.T) { Name: "foo", }, }, + { + name: "unset authentication", + objects: []runtime.Object{ + &v1.ClusterOriginIssuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: v1.OriginIssuerSpec{ + RequestType: v1.RequestTypeOriginRSA, + }, + }, + }, + expected: v1.OriginIssuerStatus{ + Conditions: []v1.OriginIssuerCondition{ + { + Type: v1.ConditionReady, + Status: v1.ConditionFalse, + LastTransitionTime: &now, + Reason: "MissingAuthentication", + Message: "No authentication methods were configured", + }, + }, + }, + error: `secret issuer-service-key does not contain key "key"`, + namespaceName: types.NamespacedName{ + Namespace: "default", + Name: "foo", + }, + }, } for _, tt := range tests { diff --git a/pkgs/controllers/originissuer.go b/pkgs/controllers/originissuer.go index 31c3e40..8e6598a 100644 --- a/pkgs/controllers/originissuer.go +++ b/pkgs/controllers/originissuer.go @@ -40,31 +40,37 @@ func (r *OriginIssuerController) Reconcile(ctx context.Context, iss *v1.OriginIs return reconcile.Result{}, err } - secret := core.Secret{} - secretNamespaceName := types.NamespacedName{ - Namespace: iss.Namespace, - Name: iss.Spec.Auth.ServiceKeyRef.Name, - } + switch { + case iss.Spec.Auth.ServiceKeyRef != nil: + secret := &core.Secret{} + secretNamespaceName := types.NamespacedName{ + Namespace: iss.Namespace, + Name: iss.Spec.Auth.ServiceKeyRef.Name, + } - if err := r.Reader.Get(ctx, secretNamespaceName, &secret); err != nil { - log.Error(err, "failed to retieve OriginIssuer auth secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name) + if err := r.Reader.Get(ctx, secretNamespaceName, secret); err != nil { + log.Error(err, "failed to retieve OriginIssuer auth secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name) - if apierrors.IsNotFound(err) { - _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - } else { - _ = r.setStatus(ctx, iss, v1.ConditionFalse, "Error", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - } + if apierrors.IsNotFound(err) { + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + } else { + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "Error", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + } - return reconcile.Result{}, err - } + return reconcile.Result{}, err + } - _, ok := secret.Data[iss.Spec.Auth.ServiceKeyRef.Key] - if !ok { - err := fmt.Errorf("secret %s does not contain key %q", secret.Name, iss.Spec.Auth.ServiceKeyRef.Key) - log.Error(err, "failed to retrieve OriginIssuer auth secret") - _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) + _, ok := secret.Data[iss.Spec.Auth.ServiceKeyRef.Key] + if !ok { + err := fmt.Errorf("secret %s does not contain key %q", secret.Name, iss.Spec.Auth.ServiceKeyRef.Key) + log.Error(err, "failed to retrieve OriginIssuer auth secret") + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "NotFound", fmt.Sprintf("Failed to retrieve auth secret: %v", err)) - return reconcile.Result{}, err + return reconcile.Result{}, err + } + default: + _ = r.setStatus(ctx, iss, v1.ConditionFalse, "MissingAuthentication", "No authentication methods were configured") + return reconcile.Result{}, nil } return reconcile.Result{}, r.setStatus(ctx, iss, v1.ConditionTrue, "Verified", "OriginIssuer verified and ready to sign certificates") @@ -81,10 +87,6 @@ func (r *OriginIssuerController) setStatus(ctx context.Context, iss *v1.OriginIs // TODO: move this to another package? func validateOriginIssuer(s v1.OriginIssuerSpec) error { switch { - case s.Auth.ServiceKeyRef.Name == "": - return fmt.Errorf("spec.auth.serviceKeyRef.name cannot be empty") - case s.Auth.ServiceKeyRef.Key == "": - return fmt.Errorf("spec.auth.serviceKeyRef.key cannot be empty") case s.RequestType == "": return fmt.Errorf("spec.requestType cannot be empty") case s.RequestType != v1.RequestTypeOriginRSA && s.RequestType != v1.RequestTypeOriginECC: diff --git a/pkgs/controllers/originissuer_suite_test.go b/pkgs/controllers/originissuer_suite_test.go index 6e8ece0..e30350a 100644 --- a/pkgs/controllers/originissuer_suite_test.go +++ b/pkgs/controllers/originissuer_suite_test.go @@ -32,7 +32,7 @@ func TestOriginIssuerReconcileSuite(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, diff --git a/pkgs/controllers/originissuer_test.go b/pkgs/controllers/originissuer_test.go index a705cf7..1a92212 100644 --- a/pkgs/controllers/originissuer_test.go +++ b/pkgs/controllers/originissuer_test.go @@ -39,7 +39,7 @@ func TestOriginIssuerReconcile(t *testing.T) { namespaceName types.NamespacedName }{ { - name: "working with secrets", + name: "working serviceKeyRef", objects: []runtime.Object{ &v1.OriginIssuer{ ObjectMeta: metav1.ObjectMeta{ @@ -49,7 +49,7 @@ func TestOriginIssuerReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, @@ -83,7 +83,7 @@ func TestOriginIssuerReconcile(t *testing.T) { }, }, { - name: "missing secret", + name: "missing serviceKeyRef", objects: []runtime.Object{ &v1.OriginIssuer{ ObjectMeta: metav1.ObjectMeta{ @@ -93,7 +93,7 @@ func TestOriginIssuerReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, @@ -119,7 +119,7 @@ func TestOriginIssuerReconcile(t *testing.T) { }, }, { - name: "secret missing key", + name: "serviceKeyRef missing key", objects: []runtime.Object{ &v1.OriginIssuer{ ObjectMeta: metav1.ObjectMeta{ @@ -129,7 +129,7 @@ func TestOriginIssuerReconcile(t *testing.T) { Spec: v1.OriginIssuerSpec{ RequestType: v1.RequestTypeOriginRSA, Auth: v1.OriginIssuerAuthentication{ - ServiceKeyRef: v1.SecretKeySelector{ + ServiceKeyRef: &v1.SecretKeySelector{ Name: "issuer-service-key", Key: "key", }, @@ -161,6 +161,36 @@ func TestOriginIssuerReconcile(t *testing.T) { Name: "foo", }, }, + { + name: "unset authentication", + objects: []runtime.Object{ + &v1.OriginIssuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: v1.OriginIssuerSpec{ + RequestType: v1.RequestTypeOriginRSA, + }, + }, + }, + expected: v1.OriginIssuerStatus{ + Conditions: []v1.OriginIssuerCondition{ + { + Type: v1.ConditionReady, + Status: v1.ConditionFalse, + LastTransitionTime: &now, + Reason: "MissingAuthentication", + Message: "No authentication methods were configured", + }, + }, + }, + error: `secret issuer-service-key does not contain key "key"`, + namespaceName: types.NamespacedName{ + Namespace: "default", + Name: "foo", + }, + }, } for _, tt := range tests {