diff --git a/README.md b/README.md index d155902a..3b6cfbdb 100644 --- a/README.md +++ b/README.md @@ -76,10 +76,9 @@ The business logic of the controllers can be provided to the libary through the If it returns a normal error, the controller will retry with backoff until the `Check` function succeeds. If the error is of type `signer.PermanentError`, the controller will not retry automatically. Instead, an increase in Generation is required to recheck the issuer. -- The `Sign` function is used by the CertificateRequest controller. +- The `Sign` function is used by the CertificateRequest controller. If it returns a normal error, the `Sign` function will be retried as long as we have not spent more than the configured `MaxRetryDuration` after the certificate request was created. If the error is of type `signer.IssuerError`, the error is an error that should be set on the issuer instead of the CertificateRequest. -If the error is of type `signer.SetCertificateRequestConditionError`, the controller will, additional to setting the ready condition, also set the specified condition. This can be used in case we have to store some additional state in the status. If the error is of type `signer.PermanentError`, the controller will not retry automatically. Instead, a new CertificateRequest has to be created. ## Reconciliation loops diff --git a/controllers/certificaterequest_controller_integration_test.go b/controllers/certificaterequest_controller_integration_test.go index 308a85da..5980a2b6 100644 --- a/controllers/certificaterequest_controller_integration_test.go +++ b/controllers/certificaterequest_controller_integration_test.go @@ -90,11 +90,11 @@ func TestCertificateRequestControllerIntegrationIssuerInitiallyNotFoundAndNotRea MaxRetryDuration: time.Minute, EventSource: kubeutil.NewEventStore(), Client: mgr.GetClient(), - Sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { + Sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { atomic.AddUint64(&counters[extractIdFromNamespace(t, cr.GetNamespace())], 1) return signer.PEMBundle{ ChainPEM: []byte("cert"), - }, nil + }, signer.ExtraConditions{}, nil }, EventRecorder: record.NewFakeRecorder(100), Clock: clock.RealClock{}, @@ -202,6 +202,11 @@ func TestCertificateRequestControllerIntegrationIssuerInitiallyNotFoundAndNotRea } } +type signResults struct { + err error + extraConditions []cmapi.CertificateRequestCondition +} + // TestCertificateRequestControllerIntegrationSetCondition runs the // CertificateRequestController against a real Kubernetes API server. func TestCertificateRequestControllerIntegrationSetCondition(t *testing.T) { @@ -218,7 +223,7 @@ func TestCertificateRequestControllerIntegrationSetCondition(t *testing.T) { kubeClients := testresource.KubeClients(t, nil) counter := uint64(0) - signResult := make(chan error, 10) + signResult := make(chan signResults, 10) ctx = setupControllersAPIServerAndClient(t, ctx, kubeClients, func(mgr ctrl.Manager) controllerInterface { return &CertificateRequestReconciler{ @@ -229,13 +234,13 @@ func TestCertificateRequestControllerIntegrationSetCondition(t *testing.T) { MaxRetryDuration: time.Minute, EventSource: kubeutil.NewEventStore(), Client: mgr.GetClient(), - Sign: func(ctx context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { + Sign: func(ctx context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { atomic.AddUint64(&counter, 1) select { - case err := <-signResult: - return signer.PEMBundle{}, err + case res := <-signResult: + return signer.PEMBundle{}, res.extraConditions, res.err case <-ctx.Done(): - return signer.PEMBundle{}, ctx.Err() + return signer.PEMBundle{}, signer.ExtraConditions{}, ctx.Err() } }, EventRecorder: record.NewFakeRecorder(100), @@ -308,19 +313,24 @@ func TestCertificateRequestControllerIntegrationSetCondition(t *testing.T) { markIssuerReady(t, ctx, kubeClients.Client, clock.RealClock{}, fieldOwner, issuer) checkComplete = kubeClients.StartObjectWatch(t, ctx, cr) - signResult <- signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("[err message1]"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", + signResult <- signResults{ + err: fmt.Errorf("[err message1]"), + extraConditions: []cmapi.CertificateRequestCondition{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message1]", + }, + }, } err = checkComplete(func(obj runtime.Object) error { customCondition := cmutil.GetCertificateRequestCondition(obj.(*cmapi.CertificateRequest), "[condition type]") if (customCondition == nil) || (customCondition.Status != cmmeta.ConditionTrue) || - (customCondition.Reason != "[reason]") || - (customCondition.Message != "[err message1]") { + (customCondition.Reason != "[condition reason]") || + (customCondition.Message != "[condition message1]") { return fmt.Errorf("incorrect custom condition: %v", customCondition) } @@ -329,19 +339,24 @@ func TestCertificateRequestControllerIntegrationSetCondition(t *testing.T) { require.NoError(t, err) checkComplete = kubeClients.StartObjectWatch(t, ctx, cr) - signResult <- signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("[err message2]"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", + signResult <- signResults{ + err: fmt.Errorf("[err message2]"), + extraConditions: []cmapi.CertificateRequestCondition{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message2]", + }, + }, } err = checkComplete(func(obj runtime.Object) error { customCondition := cmutil.GetCertificateRequestCondition(obj.(*cmapi.CertificateRequest), "[condition type]") if (customCondition == nil) || (customCondition.Status != cmmeta.ConditionTrue) || - (customCondition.Reason != "[reason]") || - (customCondition.Message != "[err message2]") { + (customCondition.Reason != "[condition reason]") || + (customCondition.Message != "[condition message2]") { return fmt.Errorf("incorrect custom condition: %v", customCondition) } @@ -350,7 +365,7 @@ func TestCertificateRequestControllerIntegrationSetCondition(t *testing.T) { require.NoError(t, err) checkComplete = kubeClients.StartObjectWatch(t, ctx, cr) - signResult <- nil + signResult <- signResults{} t.Log("Waiting for the controller to marks the CertificateRequest as Ready") err = checkComplete(func(obj runtime.Object) error { readyCondition := cmutil.GetCertificateRequestCondition(obj.(*cmapi.CertificateRequest), cmapi.CertificateRequestConditionReady) diff --git a/controllers/certificaterequest_controller_test.go b/controllers/certificaterequest_controller_test.go index 78af4652..df6523c5 100644 --- a/controllers/certificaterequest_controller_test.go +++ b/controllers/certificaterequest_controller_test.go @@ -127,10 +127,10 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { ) successSigner := func(cert string) signer.Sign { - return func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { + return func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { return signer.PEMBundle{ ChainPEM: []byte(cert), - }, nil + }, signer.ExtraConditions{}, nil } } @@ -393,8 +393,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { // condition to Failed. { name: "timeout-permanent-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, fmt.Errorf("a specific error") + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, fmt.Errorf("a specific error") }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -426,12 +426,12 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns a reason for being pending, set the Ready condition to Pending (even if + // If the sign function returns a Pending error, set the Ready condition to Pending (even if // the MaxRetryDuration has been exceeded). { name: "retry-on-pending-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.PendingError{Err: fmt.Errorf("reason for being pending")} + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, signer.PendingError{Err: fmt.Errorf("reason for being pending")} }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -468,8 +468,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { // the MaxRetryDuration has been exceeded). { name: "retry-on-pending-error-custom", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.PendingError{Err: fmt.Errorf("reason for being pending"), RequeueAfter: 5 * time.Second} + sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, nil, signer.PendingError{Err: fmt.Errorf("reason for being pending"), RequeueAfter: 5 * time.Second} }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -502,21 +502,21 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *not present* in the status, the new condition is *added* to the - // CertificateRequest. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we still *have time left* to retry, set the Ready - // condition to *Pending*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *not present* in the status, the new condition is *added* to the CertificateRequest. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we still *have time left* to retry, set the Ready condition to *Pending*. { name: "error-set-certificate-request-condition-should-add-new-condition-and-retry", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, fmt.Errorf("test error") }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -535,8 +535,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: &fakeTimeObj2, }, { @@ -554,21 +554,21 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *already present* in the status, the existing condition is *updated* with - // the values specified in the error. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we still *have time left* to retry, set the Ready - // condition to *Pending*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *already present* in the status, the existing condition is *updated* with the specified values. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we still *have time left* to retry, set the Ready condition to *Pending*. { name: "error-set-certificate-request-condition-should-update-existing-condition-and-retry", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error2"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason2]", + Message: "[condition message2]", + }, + }, fmt.Errorf("test error2") }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -582,8 +582,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { cmgen.AddCertificateRequestStatusCondition(cmapi.CertificateRequestCondition{ Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: &fakeTimeObj2, }), ), @@ -594,8 +594,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error2", + Reason: "[condition reason2]", + Message: "[condition message2]", LastTransitionTime: &fakeTimeObj2, }, { @@ -613,21 +613,21 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *not present* in the status, the new condition is *added* to the - // CertificateRequest. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we have *no time left* to retry, set the Ready condition - // to *Failed*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *not present* in the status, the new condition is *added* to the CertificateRequest. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we have *no time left* to retry, set the Ready condition to *Failed*. { name: "error-set-certificate-request-condition-should-add-new-condition-and-timeout", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, fmt.Errorf("test error") }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -646,8 +646,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: &fakeTimeObj2, }, { @@ -666,21 +666,21 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *already present* in the status, the existing condition is *updated* with - // the values specified in the error. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we have *no time left* to retry, set the Ready condition - // to *Failed*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *already present* in the status, the existing condition is *updated* with the specified values. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we have *no time left* to retry, set the Ready condition to *Failed*. { name: "error-set-certificate-request-condition-should-update-existing-condition-and-timeout", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error2"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason2]", + Message: "[condition message2]", + }, + }, fmt.Errorf("test error2") }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -694,8 +694,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { cmgen.AddCertificateRequestStatusCondition(cmapi.CertificateRequestCondition{ Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: &fakeTimeObj1, }), ), @@ -706,8 +706,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error2", + Reason: "[condition reason2]", + Message: "[condition message2]", LastTransitionTime: &fakeTimeObj1, // since the status is not updated, the LastTransitionTime is not updated either }, { @@ -726,20 +726,21 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError, the specified - // conditions value is updated/ added to the CertificateRequest status. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is a PendingError - // error, the Ready condition is set to Pending (even if the MaxRetryDuration has been - // exceeded). + // If the sign function returns signer.ExtraConditions, the specified conditions value + // is updated/ added to the CertificateRequest status. + // Additionally, if the returned error is a PendingError error, the Ready condition is + // set to Pending (even if the MaxRetryDuration has been exceeded). { name: "error-set-certificate-request-condition-should-not-timeout-if-pending", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: signer.PendingError{Err: fmt.Errorf("test error")}, - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, signer.PendingError{Err: fmt.Errorf("test error")} }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -758,8 +759,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: &fakeTimeObj2, }, { @@ -776,20 +777,21 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError, the specified - // conditions value is updated/ added to the CertificateRequest status. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is a PendingError - // error, the Ready condition is set to Failed (even if the MaxRetryDuration has NOT been - // exceeded). + // If the sign function returns signer.ExtraConditions, the specified conditions value + // is updated/ added to the CertificateRequest status. + // Additionally, if the returned error is a PermanentError error, the Ready condition is + // set to Failed (even if the MaxRetryDuration has NOT been exceeded). { name: "error-set-certificate-request-condition-should-not-retry-on-permanent-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: signer.PermanentError{Err: fmt.Errorf("test error")}, - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, signer.PermanentError{Err: fmt.Errorf("test error")} }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -805,8 +807,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: cmmeta.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: &fakeTimeObj2, }, { @@ -828,8 +830,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { // Set the Ready condition to Failed if the sign function returns a permanent error. { name: "fail-on-permanent-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.PermanentError{Err: fmt.Errorf("a specific error")} + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, signer.PermanentError{Err: fmt.Errorf("a specific error")} }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, @@ -862,8 +864,8 @@ func TestCertificateRequestReconcilerReconcile(t *testing.T) { // to retry. { name: "retry-on-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, errors.New("waiting for approval") + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, errors.New("waiting for approval") }, objects: []client.Object{ cmgen.CertificateRequestFrom(cr1, diff --git a/controllers/certificatesigningrequest_controller_test.go b/controllers/certificatesigningrequest_controller_test.go index 30b0ddd8..335273ec 100644 --- a/controllers/certificatesigningrequest_controller_test.go +++ b/controllers/certificatesigningrequest_controller_test.go @@ -117,10 +117,10 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { ) successSigner := func(cert string) signer.Sign { - return func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { + return func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { return signer.PEMBundle{ ChainPEM: []byte(cert), - }, nil + }, signer.ExtraConditions{}, nil } } @@ -289,8 +289,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { // condition to Failed. { name: "timeout-permanent-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, fmt.Errorf("a specific error") + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, fmt.Errorf("a specific error") }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -325,8 +325,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { // the MaxRetryDuration has been exceeded). { name: "retry-on-pending-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.PendingError{Err: fmt.Errorf("pending error")} + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, signer.PendingError{Err: fmt.Errorf("pending error")} }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -354,8 +354,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { // the MaxRetryDuration has been exceeded). { name: "retry-on-pending-error-custom", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.PendingError{Err: fmt.Errorf("pending error"), RequeueAfter: 5 * time.Second} + sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, nil, signer.PendingError{Err: fmt.Errorf("pending error"), RequeueAfter: 5 * time.Second} }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -379,21 +379,21 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *not present* in the status, the new condition is *added* to the - // CertificateSigningRequest. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we still *have time left* to retry, set the Ready - // condition to *Pending*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *not present* in the status, the new condition is *added* to the CertificateSigningRequest. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we still *have time left* to retry, set the Ready condition to *Pending*. { name: "error-set-certificate-request-condition-should-add-new-condition-and-retry", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, fmt.Errorf("test error") }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -411,8 +411,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: fakeTimeObj2, LastUpdateTime: fakeTimeObj2, }, @@ -424,21 +424,21 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *already present* in the status, the existing condition is *updated* with - // the values specified in the error. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we still *have time left* to retry, set the Ready - // condition to *Pending*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *already present* in the status, the existing condition is *updated* with the specified values. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we still *have time left* to retry, set the Ready condition to *Pending*. { name: "error-set-certificate-request-condition-should-update-existing-condition-and-retry", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error2"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason2]", + Message: "[condition message2]", + }, + }, fmt.Errorf("test error2") }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -451,8 +451,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { cmgen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{ Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: fakeTimeObj2, LastUpdateTime: fakeTimeObj2, }), @@ -464,8 +464,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error2", + Reason: "[condition reason2]", + Message: "[condition message2]", LastTransitionTime: fakeTimeObj2, LastUpdateTime: fakeTimeObj2, }, @@ -477,21 +477,21 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *not present* in the status, the new condition is *added* to the - // CertificateSigningRequest. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we have *no time left* to retry, set the Ready condition - // to *Failed*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *not present* in the status, the new condition is *added* to the CertificateSigningRequest. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we have *no time left* to retry, set the Ready condition to *Failed*. { name: "error-set-certificate-request-condition-should-add-new-condition-and-timeout", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, fmt.Errorf("test error") }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -509,8 +509,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: fakeTimeObj2, LastUpdateTime: fakeTimeObj2, }, @@ -530,21 +530,21 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError error with a condition - // type that is *already present* in the status, the existing condition is *updated* with - // the values specified in the error. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is not one of the - // supported 'signer API' errors an we have *no time left* to retry, set the Ready condition - // to *Failed*. + // If the sign function returns signer.ExtraConditions with a condition type that is + // *already present* in the status, the existing condition is *updated* with the specified values. + // Additionally, if the returned error is not one of the supported 'signer API' errors + // an we have *no time left* to retry, set the Ready condition to *Failed*. { name: "error-set-certificate-request-condition-should-update-existing-condition-and-timeout", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: fmt.Errorf("test error2"), - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason2]", + Message: "[condition message2]", + }, + }, fmt.Errorf("test error2") }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -557,8 +557,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { cmgen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{ Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: fakeTimeObj1, LastUpdateTime: fakeTimeObj1, }), @@ -570,8 +570,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error2", + Reason: "[condition reason2]", + Message: "[condition message2]", LastTransitionTime: fakeTimeObj1, // since the status is not updated, the LastTransitionTime is not updated either LastUpdateTime: fakeTimeObj2, }, @@ -591,20 +591,21 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError, the specified - // conditions value is updated/ added to the CertificateSigningRequest status. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is a PendingError - // error, the Ready condition is set to Pending (even if the MaxRetryDuration has been - // exceeded). + // If the sign function returns signer.ExtraConditions, the specified conditions value + // is updated/ added to the CertificateSigningRequest status. + // Additionally, if the returned error is a PendingError error, the Ready condition is + // set to Pending (even if the MaxRetryDuration has been exceeded). { name: "error-set-certificate-request-condition-should-not-timeout-if-pending", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: signer.PendingError{Err: fmt.Errorf("test error")}, - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, signer.PendingError{Err: fmt.Errorf("test error")} }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -622,8 +623,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: fakeTimeObj2, LastUpdateTime: fakeTimeObj2, }, @@ -634,20 +635,21 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { }, }, - // If the sign function returns an SetCertificateRequestConditionError, the specified - // conditions value is updated/ added to the CertificateSigningRequest status. - // Additionally, if the error wrapped by SetCertificateRequestConditionError is a PendingError - // error, the Ready condition is set to Failed (even if the MaxRetryDuration has NOT been - // exceeded). + // If the sign function returns signer.ExtraConditions, the specified conditions value + // is updated/ added to the CertificateSigningRequest status. + // Additionally, if the returned error is a PermanentError error, the Ready condition is + // set to Failed (even if the MaxRetryDuration has NOT been exceeded). { name: "error-set-certificate-request-condition-should-not-retry-on-permanent-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.SetCertificateRequestConditionError{ - Err: signer.PermanentError{Err: fmt.Errorf("test error")}, - ConditionType: "[condition type]", - Status: cmmeta.ConditionTrue, - Reason: "[reason]", - } + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{ + { + Type: "[condition type]", + Status: cmmeta.ConditionTrue, + Reason: "[condition reason]", + Message: "[condition message]", + }, + }, signer.PermanentError{Err: fmt.Errorf("test error")} }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -662,8 +664,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { { Type: "[condition type]", Status: v1.ConditionTrue, - Reason: "[reason]", - Message: "test error", + Reason: "[condition reason]", + Message: "[condition message]", LastTransitionTime: fakeTimeObj2, LastUpdateTime: fakeTimeObj2, }, @@ -686,8 +688,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { // Set the Ready condition to Failed if the sign function returns a permanent error. { name: "fail-on-permanent-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, signer.PermanentError{Err: fmt.Errorf("a specific error")} + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, signer.PermanentError{Err: fmt.Errorf("a specific error")} }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, @@ -719,8 +721,8 @@ func TestCertificateSigningRequestReconcilerReconcile(t *testing.T) { // to retry. { name: "retry-on-error", - sign: func(_ context.Context, cr signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { - return signer.PEMBundle{}, errors.New("waiting for approval") + sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { + return signer.PEMBundle{}, signer.ExtraConditions{}, errors.New("waiting for approval") }, objects: []client.Object{ cmgen.CertificateSigningRequestFrom(cr1, diff --git a/controllers/combined_controller_integration_test.go b/controllers/combined_controller_integration_test.go index 0e198d58..6ba55ddd 100644 --- a/controllers/combined_controller_integration_test.go +++ b/controllers/combined_controller_integration_test.go @@ -83,12 +83,12 @@ func TestCombinedControllerTemporaryFailedCertificateRequestRetrigger(t *testing return ctx.Err() } }, - Sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { + Sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { select { case err := <-signResult: - return signer.PEMBundle{}, err + return signer.PEMBundle{}, signer.ExtraConditions{}, err case <-ctx.Done(): - return signer.PEMBundle{}, ctx.Err() + return signer.PEMBundle{}, signer.ExtraConditions{}, ctx.Err() } }, EventRecorder: record.NewFakeRecorder(100), @@ -483,7 +483,7 @@ func TestCombinedControllerTiming(t *testing.T) { //nolint:tparallel } return results[resultsIndex].simulatedCheckResult.err }, - Sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, error) { + Sign: func(_ context.Context, _ signer.CertificateRequestObject, _ v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { resultsMutex.Lock() defer resultsMutex.Unlock() defer func() { resultsIndex++ }() @@ -491,19 +491,19 @@ func TestCombinedControllerTiming(t *testing.T) { //nolint:tparallel if resultsIndex >= len(results)-1 { if resultsIndex > len(results)-1 { errorCh <- fmt.Errorf("too many calls to Sign") - return signer.PEMBundle{}, nil + return signer.PEMBundle{}, signer.ExtraConditions{}, nil } defer close(done) } durations[resultsIndex] = time.Now() if results[resultsIndex].simulatedSignResult == nil { errorCh <- fmt.Errorf("unexpected call to Sign") - return signer.PEMBundle{}, nil + return signer.PEMBundle{}, signer.ExtraConditions{}, nil } result := results[resultsIndex].simulatedSignResult return signer.PEMBundle{ ChainPEM: result.cert, - }, result.err + }, signer.ExtraConditions{}, result.err }, EventRecorder: record.NewFakeRecorder(100), diff --git a/controllers/request_controller.go b/controllers/request_controller.go index 26a20863..25cccce0 100644 --- a/controllers/request_controller.go +++ b/controllers/request_controller.go @@ -269,7 +269,20 @@ func (r *RequestController) reconcileStatusPatch( return result, statusPatch, nil // apply patch, done } - signedCertificate, err := r.Sign(log.IntoContext(ctx, logger), requestObjectHelper.RequestObject(), issuerObject) + signedCertificate, extraConditions, err := r.Sign(log.IntoContext(ctx, logger), requestObjectHelper.RequestObject(), issuerObject) + didCustomConditionTransition := false + for _, condition := range extraConditions { + logger.V(1).Info("Set RequestCondition error. Setting condition.", "error", err) + if statusPatch.SetCustomCondition( + string(condition.Type), + metav1.ConditionStatus(condition.Status), + condition.Reason, + condition.Message, + ) { + didCustomConditionTransition = true + } + } + if err == nil { logger.V(1).Info("Successfully finished the reconciliation.") statusPatch.SetIssued(signedCertificate) @@ -293,17 +306,6 @@ func (r *RequestController) reconcileStatusPatch( return result, statusPatch, nil // apply patch, done } - didCustomConditionTransition := false - if targetCustom := new(signer.SetCertificateRequestConditionError); errors.As(err, targetCustom) { - logger.V(1).Info("Set RequestCondition error. Setting condition.", "error", err) - didCustomConditionTransition = statusPatch.SetCustomCondition( - string(targetCustom.ConditionType), - metav1.ConditionStatus(targetCustom.Status), - targetCustom.Reason, - targetCustom.Error(), - ) - } - // Check if we have still time to requeue & retry pendingError := &signer.PendingError{} isPending := errors.As(err, pendingError) diff --git a/controllers/signer/err_set_condition.go b/controllers/signer/err_set_condition.go deleted file mode 100644 index 2fc443bc..00000000 --- a/controllers/signer/err_set_condition.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2023 The cert-manager Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package signer - -import ( - cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" -) - -// The SetCertificateRequestConditionError error is meant to be returned by the -// Sign function. When Sign returns this error, the caller (i.e., the certificate -// request controller) is expected to update the CertificateRequest with the -// condition contained in the error. -// -// The error wrapped by this error is the error can still be a signer.Permanent or -// signer.Pending error and will be handled accordingly. -// -// > This error should be returned only by the Sign function. -type SetCertificateRequestConditionError struct { - Err error - ConditionType cmapi.CertificateRequestConditionType - Status cmmeta.ConditionStatus - Reason string -} - -var _ error = SetCertificateRequestConditionError{} - -func (ve SetCertificateRequestConditionError) Unwrap() error { - return ve.Err -} - -func (ve SetCertificateRequestConditionError) Error() string { - return ve.Err.Error() -} diff --git a/controllers/signer/interface.go b/controllers/signer/interface.go index c940f6c4..f3281d0b 100644 --- a/controllers/signer/interface.go +++ b/controllers/signer/interface.go @@ -40,9 +40,11 @@ import ( // discouraged, instead the CA should be provisioned separately (e.g. using trust-manager). type PEMBundle pki.PEMBundle -type Sign func(ctx context.Context, cr CertificateRequestObject, issuerObject v1alpha1.Issuer) (PEMBundle, error) +type Sign func(ctx context.Context, cr CertificateRequestObject, issuerObject v1alpha1.Issuer) (PEMBundle, ExtraConditions, error) type Check func(ctx context.Context, issuerObject v1alpha1.Issuer) error +type ExtraConditions []cmapi.CertificateRequestCondition + // CertificateRequestObject is an interface that represents either a // cert-manager CertificateRequest or a Kubernetes CertificateSigningRequest // resource. This interface hides the spec fields of the underlying resource @@ -53,8 +55,6 @@ type Check func(ctx context.Context, issuerObject v1alpha1.Issuer) error // labels and annotations of the underlying resource or any other metadata // fields that might be useful to the signer. Also, the signer can use the // GetConditions method to retrieve the conditions of the underlying resource. -// To update the conditions, the special error "SetCertificateRequestConditionError" -// can be returned from the Sign method. type CertificateRequestObject interface { metav1.Object diff --git a/examples/simple/controller/signer.go b/examples/simple/controller/signer.go index ca76bb33..5437fbcf 100644 --- a/examples/simple/controller/signer.go +++ b/examples/simple/controller/signer.go @@ -67,11 +67,11 @@ func (Signer) Check(ctx context.Context, issuerObject v1alpha1.Issuer) error { return nil } -func (Signer) Sign(ctx context.Context, cr signer.CertificateRequestObject, issuerObject v1alpha1.Issuer) (signer.PEMBundle, error) { +func (Signer) Sign(ctx context.Context, cr signer.CertificateRequestObject, issuerObject v1alpha1.Issuer) (signer.PEMBundle, signer.ExtraConditions, error) { // generate random ca private key caPrivateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { - return signer.PEMBundle{}, err + return signer.PEMBundle{}, nil, err } caCRT := &x509.Certificate{ @@ -90,12 +90,12 @@ func (Signer) Sign(ctx context.Context, cr signer.CertificateRequestObject, issu // load client certificate request certDetails, err := cr.GetCertificateDetails() if err != nil { - return signer.PEMBundle{}, err + return signer.PEMBundle{}, nil, err } clientCRTTemplate, err := certDetails.CertificateTemplate() if err != nil { - return signer.PEMBundle{}, err + return signer.PEMBundle{}, nil, err } // create client certificate from template and CA public key @@ -107,5 +107,5 @@ func (Signer) Sign(ctx context.Context, cr signer.CertificateRequestObject, issu clientCrt := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: clientCRTRaw}) return signer.PEMBundle{ ChainPEM: clientCrt, - }, nil + }, nil, nil }