Adds venafi CertificateSigningRequest controller

Signed-off-by: joshvanl <vleeuwenjoshua@gmail.com>
This commit is contained in:
joshvanl
2021-07-19 15:50:23 +01:00
parent dcc3ad44b4
commit c4914f7103
4 changed files with 1212 additions and 0 deletions
@@ -74,6 +74,7 @@ filegroup(
"//pkg/controller/certificatesigningrequests/selfsigned:all-srcs",
"//pkg/controller/certificatesigningrequests/util:all-srcs",
"//pkg/controller/certificatesigningrequests/vault:all-srcs",
"//pkg/controller/certificatesigningrequests/venafi:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
@@ -0,0 +1,73 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["venafi.go"],
importpath = "github.com/jetstack/cert-manager/pkg/controller/certificatesigningrequests/venafi",
visibility = ["//visibility:public"],
deps = [
"//pkg/api/util:go_default_library",
"//pkg/apis/certmanager/v1:go_default_library",
"//pkg/apis/experimental/v1alpha1:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller/certificatesigningrequests:go_default_library",
"//pkg/controller/certificatesigningrequests/util:go_default_library",
"//pkg/issuer/venafi/client:go_default_library",
"//pkg/issuer/venafi/client/api:go_default_library",
"//pkg/logs:go_default_library",
"//pkg/util/pki:go_default_library",
"@com_github_venafi_vcert_v4//pkg/endpoint:go_default_library",
"@io_k8s_api//certificates/v1:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_apimachinery//pkg/api/errors:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_client_go//kubernetes/typed/certificates/v1:go_default_library",
"@io_k8s_client_go//listers/core/v1:go_default_library",
"@io_k8s_client_go//tools/record:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["venafi_test.go"],
embed = [":go_default_library"],
deps = [
"//pkg/api/util:go_default_library",
"//pkg/apis/certmanager:go_default_library",
"//pkg/apis/certmanager/v1:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/controller/certificatesigningrequests:go_default_library",
"//pkg/controller/certificatesigningrequests/util:go_default_library",
"//pkg/controller/test:go_default_library",
"//pkg/issuer/venafi/client:go_default_library",
"//pkg/issuer/venafi/client/api:go_default_library",
"//pkg/issuer/venafi/client/fake:go_default_library",
"//pkg/util/pki:go_default_library",
"//test/unit/gen:go_default_library",
"@com_github_venafi_vcert_v4//pkg/endpoint:go_default_library",
"@io_k8s_api//authorization/v1:go_default_library",
"@io_k8s_api//certificates/v1:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_apimachinery//pkg/api/errors:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
"@io_k8s_apimachinery//pkg/runtime/schema:go_default_library",
"@io_k8s_client_go//listers/core/v1:go_default_library",
"@io_k8s_client_go//testing:go_default_library",
"@io_k8s_utils//clock/testing:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -0,0 +1,217 @@
/*
Copyright 2020 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 venafi
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/Venafi/vcert/v4/pkg/endpoint"
certificatesv1 "k8s.io/api/certificates/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1"
corelisters "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/record"
apiutil "github.com/jetstack/cert-manager/pkg/api/util"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
experimentalapi "github.com/jetstack/cert-manager/pkg/apis/experimental/v1alpha1"
controllerpkg "github.com/jetstack/cert-manager/pkg/controller"
"github.com/jetstack/cert-manager/pkg/controller/certificatesigningrequests"
"github.com/jetstack/cert-manager/pkg/controller/certificatesigningrequests/util"
venaficlient "github.com/jetstack/cert-manager/pkg/issuer/venafi/client"
venafiapi "github.com/jetstack/cert-manager/pkg/issuer/venafi/client/api"
logf "github.com/jetstack/cert-manager/pkg/logs"
"github.com/jetstack/cert-manager/pkg/util/pki"
utilpki "github.com/jetstack/cert-manager/pkg/util/pki"
)
const (
CSRControllerName = "certificatesigningrequests-issuer-venafi"
)
// Venafi is a Kubernetes CertificateSigningRequest controller, responsible for
// signing CertificateSigningRequests that reference a cert-manager Venafi
// Issuer or ClusterIssuer
type Venafi struct {
issuerOptions controllerpkg.IssuerOptions
secretsLister corelisters.SecretLister
certClient certificatesclient.CertificateSigningRequestInterface
recorder record.EventRecorder
clientBuilder venaficlient.VenafiClientBuilder
}
func init() {
controllerpkg.Register(CSRControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
return controllerpkg.NewBuilder(ctx, CSRControllerName).
For(certificatesigningrequests.New(apiutil.IssuerVenafi, NewVenafi(ctx))).
Complete()
})
}
func NewVenafi(ctx *controllerpkg.Context) *Venafi {
return &Venafi{
issuerOptions: ctx.IssuerOptions,
secretsLister: ctx.KubeSharedInformerFactory.Core().V1().Secrets().Lister(),
certClient: ctx.Client.CertificatesV1().CertificateSigningRequests(),
recorder: ctx.Recorder,
clientBuilder: venaficlient.New,
}
}
// Sign attempts to sign the given CertificateSigningRequest based on the
// provided Venafi Issuer or ClusterIssuer. This function will update the resource
// if signing was successful. Returns an error which, if not nil, should
// trigger a retry.
// Since this signer takes some time to sign the request, this controller will
// set a "pick ID" annotation value that is used to fetch the latest state of
// the request in subsequent re-syncs.
func (v *Venafi) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningRequest, issuerObj cmapi.GenericIssuer) error {
log := logf.FromContext(ctx, "sign")
log = logf.WithRelatedResource(log, issuerObj)
resourceNamespace := v.issuerOptions.ResourceNamespace(issuerObj)
client, err := v.clientBuilder(resourceNamespace, v.secretsLister, issuerObj)
if apierrors.IsNotFound(err) {
message := "Required secret resource not found"
v.recorder.Event(csr, corev1.EventTypeWarning, "SecretNotFound", message)
log.Error(err, message)
return nil
}
if err != nil {
message := fmt.Sprintf("Failed to initialise venafi client for signing: %s", err)
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorVenafiInit", message)
log.Error(err, message)
return err
}
var customFields []venafiapi.CustomField
if annotation, exists := csr.GetAnnotations()[experimentalapi.CertificateSigningRequestVenafiCustomFieldsAnnotationKey]; exists && annotation != "" {
err := json.Unmarshal([]byte(annotation), &customFields)
if err != nil {
message := fmt.Sprintf("Failed to parse %q annotation: %s", experimentalapi.CertificateSigningRequestVenafiCustomFieldsAnnotationKey, err)
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorCustomFields", message)
util.CertificateSigningRequestSetFailed(csr, "ErrorCustomFields", message)
_, err = v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
return err
}
}
duration, err := pki.DurationFromCertificateSigningRequest(csr)
if err != nil {
message := fmt.Sprintf("Failed to parse requested duration: %s", err)
log.Error(err, message)
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorParseDuration", message)
util.CertificateSigningRequestSetFailed(csr, "ErrorParseDuration", message)
_, err := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
return err
}
pickupID := csr.GetAnnotations()[experimentalapi.CertificateSigningRequestVenafiPickupIDAnnotationKey]
// check if the pickup ID annotation is there, if not set it up.
if len(pickupID) == 0 {
pickupID, err := client.RequestCertificate(csr.Spec.Request, duration, customFields)
// Check some known error types
if err != nil {
switch err.(type) {
case venaficlient.ErrCustomFieldsType:
log.Error(err, "")
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorCustomFields", err.Error())
util.CertificateSigningRequestSetFailed(csr, "ErrorCustomFields", err.Error())
_, err := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
return err
default:
message := fmt.Sprintf("Failed to request venafi certificate: %s", err)
log.Error(err, message)
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorRequest", message)
util.CertificateSigningRequestSetFailed(csr, "ErrorRequest", message)
_, err := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
return err
}
}
if csr.Annotations == nil {
csr.Annotations = make(map[string]string)
}
csr.Annotations[experimentalapi.CertificateSigningRequestVenafiPickupIDAnnotationKey] = pickupID
_, err = v.certClient.Update(ctx, csr, metav1.UpdateOptions{})
return err
}
certPem, err := client.RetrieveCertificate(pickupID, csr.Spec.Request, duration, customFields)
if err != nil {
switch err.(type) {
case endpoint.ErrCertificatePending, endpoint.ErrRetrieveCertificateTimeout:
message := "Venafi certificate still in a pending state, the request will be retried"
log.Error(err, message)
v.recorder.Event(csr, corev1.EventTypeNormal, "IssuancePending", message)
return err
default:
message := fmt.Sprintf("Failed to obtain venafi certificate: %s", err)
log.Error(err, message)
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorRetrieve", message)
return err
}
}
bundle, err := utilpki.ParseSingleCertificateChainPEM(certPem)
if err != nil {
message := fmt.Sprintf("Failed to parse returned certificate bundle: %s", err)
log.Error(err, message)
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorParse", message)
util.CertificateSigningRequestSetFailed(csr, "ErrorParse", message)
_, err := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
return err
}
// Update the status.certificate first so that the sync from updating will
// not cause another issuance before setting the CA.
csr.Status.Certificate = bundle.ChainPEM
csr, err = v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
if err != nil {
message := "Error updating certificate"
v.recorder.Eventf(csr, corev1.EventTypeWarning, "SigningError", "%s: %s", message, err)
return err
}
if csr.Annotations == nil {
csr.Annotations = make(map[string]string)
}
csr.Annotations[experimentalapi.CertificateSigningRequestCAAnnotationKey] = base64.StdEncoding.EncodeToString(bundle.CAPEM)
_, err = v.certClient.Update(ctx, csr, metav1.UpdateOptions{})
if err != nil {
message := fmt.Sprintf("Error setting %q", experimentalapi.CertificateSigningRequestCAAnnotationKey)
v.recorder.Eventf(csr, corev1.EventTypeWarning, "SigningError", "%s: %s", message, err)
return err
}
log.V(logf.DebugLevel).Info("certificate issued")
v.recorder.Event(csr, corev1.EventTypeNormal, "CertificateIssued", "Certificate fetched from venafi issuer successfully")
return nil
}
@@ -0,0 +1,921 @@
/*
Copyright 2021 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 venafi
import (
"context"
"crypto/x509"
"errors"
"fmt"
"testing"
"time"
"github.com/Venafi/vcert/v4/pkg/endpoint"
authzv1 "k8s.io/api/authorization/v1"
certificatesv1 "k8s.io/api/certificates/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
corelisters "k8s.io/client-go/listers/core/v1"
coretesting "k8s.io/client-go/testing"
fakeclock "k8s.io/utils/clock/testing"
apiutil "github.com/jetstack/cert-manager/pkg/api/util"
"github.com/jetstack/cert-manager/pkg/apis/certmanager"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
"github.com/jetstack/cert-manager/pkg/controller/certificatesigningrequests"
"github.com/jetstack/cert-manager/pkg/controller/certificatesigningrequests/util"
testpkg "github.com/jetstack/cert-manager/pkg/controller/test"
venaficlient "github.com/jetstack/cert-manager/pkg/issuer/venafi/client"
venafiapi "github.com/jetstack/cert-manager/pkg/issuer/venafi/client/api"
fakevenaficlient "github.com/jetstack/cert-manager/pkg/issuer/venafi/client/fake"
"github.com/jetstack/cert-manager/pkg/util/pki"
"github.com/jetstack/cert-manager/test/unit/gen"
)
var (
fixedClockStart = time.Now()
fixedClock = fakeclock.NewFakeClock(fixedClockStart)
)
func TestProcessItem(t *testing.T) {
metaFixedClockStart := metav1.NewTime(fixedClockStart)
util.Clock = fixedClock
rootCSRPEM, rootPK, err := gen.CSR(x509.RSA,
gen.SetCSRCommonName("root"),
)
if err != nil {
t.Fatal(err)
}
rootTmpl, err := pki.GenerateTemplateFromCSRPEM(rootCSRPEM, time.Hour, true)
if err != nil {
t.Fatal(err)
}
_, rootCert, err := pki.SignCertificate(rootTmpl, rootTmpl, rootPK.Public(), rootPK)
if err != nil {
t.Fatal(err)
}
leafCSRPEM, leafPK, err := gen.CSR(x509.RSA,
gen.SetCSRCommonName("leaf"),
)
if err != nil {
t.Fatal(err)
}
leafTmpl, err := pki.GenerateTemplateFromCSRPEM(leafCSRPEM, time.Hour, false)
if err != nil {
t.Fatal(err)
}
_, leafCert, err := pki.SignCertificate(leafTmpl, rootCert, leafPK.Public(), rootPK)
if err != nil {
t.Fatal(err)
}
certBundle, err := pki.ParseSingleCertificateChain([]*x509.Certificate{leafCert, rootCert})
if err != nil {
t.Fatal(err)
}
baseIssuer := gen.Issuer("test-issuer",
gen.SetIssuerVenafi(cmapi.VenafiIssuer{
Cloud: &cmapi.VenafiCloud{},
}),
gen.AddIssuerCondition(cmapi.IssuerCondition{
Type: cmapi.IssuerConditionReady,
Status: cmmeta.ConditionTrue,
}),
)
baseCSR := gen.CertificateSigningRequest("test-cr",
gen.SetCertificateSigningRequestRequest(leafCSRPEM),
gen.SetCertificateSigningRequestSignerName("issuers.cert-manager.io/default-unit-test-ns.test-issuer"),
gen.SetCertificateSigningRequestDuration("1440h"),
gen.SetCertificateSigningRequestUsername("user-1"),
gen.SetCertificateSigningRequestGroups([]string{"group-1", "group-2"}),
gen.SetCertificateSigningRequestUID("uid-1"),
gen.SetCertificateSigningRequestExtra(map[string]certificatesv1.ExtraValue{
"extra": []string{"1", "2"},
}),
)
tests := map[string]struct {
builder *testpkg.Builder
csr *certificatesv1.CertificateSigningRequest
clientBuilder venaficlient.VenafiClientBuilder
expectedErr bool
}{
"a CertificateSigningRequest without an approved condition should do nothing": {
csr: gen.CertificateSigningRequestFrom(baseCSR),
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
},
},
"a CertificateSigningRequest with a denied condition should do nothing": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateDenied,
Status: corev1.ConditionTrue,
}),
),
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{},
ExpectedActions: nil,
},
},
"an approved CSR where the venafi client builder returns a not found error should fire event and do nothing": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return nil, apierrors.NewNotFound(schema.GroupResource{}, "test-secret")
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Warning SecretNotFound Required secret resource not found",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
},
},
},
"an approved CSR where the venafi client builder returns a generic error should mark as Failed": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return nil, errors.New("generic error")
},
expectedErr: true,
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Warning ErrorVenafiInit Failed to initialise venafi client for signing: generic error",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
},
},
},
"an approved CSR where the custom fields annotations contain garbage data should mark as Failed": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": "garbage-data",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
`Warning ErrorCustomFields Failed to parse "venafi.experimental.cert-manager.io/custom-fields" annotation: invalid character 'g' looking for beginning of value`,
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"status",
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": "garbage-data",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateFailed,
Status: corev1.ConditionTrue,
Reason: "ErrorCustomFields",
Message: `Failed to parse "venafi.experimental.cert-manager.io/custom-fields" annotation: invalid character 'g' looking for beginning of value`,
LastTransitionTime: metaFixedClockStart,
LastUpdateTime: metaFixedClockStart,
}),
),
)),
},
},
},
"an approved CSR where the requested duration annotations contains garbage data should mark as Failed": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestDuration("garbage-duration"),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
`Warning ErrorParseDuration Failed to parse requested duration: failed to parse requested duration on annotation "experimental.cert-manager.io/request-duration": time: invalid duration "garbage-duration"`,
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"status",
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.SetCertificateSigningRequestDuration("garbage-duration"),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateFailed,
Status: corev1.ConditionTrue,
Reason: "ErrorParseDuration",
Message: `Failed to parse requested duration: failed to parse requested duration on annotation "experimental.cert-manager.io/request-duration": time: invalid duration "garbage-duration"`,
LastTransitionTime: metaFixedClockStart,
LastUpdateTime: metaFixedClockStart,
}),
),
)),
},
},
},
"an approved CSR which does not yet have a pickup ID, but the client responds with fields type error, should mark as Failed": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RequestCertificateFn: func(_ []byte, _ time.Duration, _ []venafiapi.CustomField) (string, error) {
return "", venaficlient.ErrCustomFieldsType{Type: "test-type"}
},
}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
`Warning ErrorCustomFields certificate request contains an invalid Venafi custom fields type: "test-type"`,
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"status",
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateFailed,
Status: corev1.ConditionTrue,
Reason: "ErrorCustomFields",
Message: `certificate request contains an invalid Venafi custom fields type: "test-type"`,
LastTransitionTime: metaFixedClockStart,
LastUpdateTime: metaFixedClockStart,
}),
),
)),
},
},
},
"an approved CSR which does not yet have a pickup ID, but the client responds a generic error, should mark as Failed": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RequestCertificateFn: func(_ []byte, _ time.Duration, _ []venafiapi.CustomField) (string, error) {
return "", errors.New("generic error")
},
}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Warning ErrorRequest Failed to request venafi certificate: generic error",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"status",
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateFailed,
Status: corev1.ConditionTrue,
Reason: "ErrorRequest",
Message: "Failed to request venafi certificate: generic error",
LastTransitionTime: metaFixedClockStart,
LastUpdateTime: metaFixedClockStart,
}),
),
)),
},
},
},
"an approved CSR which does not yet have a pickup ID, should update the annotation with one and return": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RequestCertificateFn: func(_ []byte, _ time.Duration, _ []venafiapi.CustomField) (string, error) {
return "test-pickup-id", nil
},
}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
)),
},
},
},
"an approved CSR which has a pickup ID, retrieve certificate returns a pending error, fire event and return error": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RetrieveCertificateFn: func(_ string, _ []byte, _ time.Duration, _ []venafiapi.CustomField) ([]byte, error) {
return nil, endpoint.ErrCertificatePending{}
},
}, nil
},
expectedErr: true,
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Normal IssuancePending Venafi certificate still in a pending state, the request will be retried",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
},
},
},
"an approved CSR which has a pickup ID, retrieve certificate returns a timeout error, fire event and return error": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RetrieveCertificateFn: func(_ string, _ []byte, _ time.Duration, _ []venafiapi.CustomField) ([]byte, error) {
return nil, endpoint.ErrRetrieveCertificateTimeout{}
},
}, nil
},
expectedErr: true,
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Normal IssuancePending Venafi certificate still in a pending state, the request will be retried",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
},
},
},
"an approved CSR which has a pickup ID, retrieve certificate returns a generic error, fire event and return error": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RetrieveCertificateFn: func(_ string, _ []byte, _ time.Duration, _ []venafiapi.CustomField) ([]byte, error) {
return nil, errors.New("generic error")
},
}, nil
},
expectedErr: true,
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Warning ErrorRetrieve Failed to obtain venafi certificate: generic error",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
},
},
},
"an approved CSR which has a pickup ID, retrieve certificate returns garbage certificates, should mark as Failed": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RetrieveCertificateFn: func(_ string, _ []byte, _ time.Duration, _ []venafiapi.CustomField) ([]byte, error) {
return []byte("garbage"), nil
},
}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Warning ErrorParse Failed to parse returned certificate bundle: error decoding certificate PEM block",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"status",
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateFailed,
Status: corev1.ConditionTrue,
Reason: "ErrorParse",
Message: "Failed to parse returned certificate bundle: error decoding certificate PEM block",
LastTransitionTime: metaFixedClockStart,
LastUpdateTime: metaFixedClockStart,
}),
),
)),
},
},
},
"an approved CSR which has a pickup ID, retrieve certificate returns a CA and certificate should update with CA and certificate": {
csr: gen.CertificateSigningRequestFrom(baseCSR,
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
),
clientBuilder: func(_ string, _ corelisters.SecretLister, _ cmapi.GenericIssuer) (venaficlient.Interface, error) {
return &fakevenaficlient.Venafi{
RetrieveCertificateFn: func(_ string, _ []byte, _ time.Duration, _ []venafiapi.CustomField) ([]byte, error) {
return []byte(fmt.Sprintf("%s%s", certBundle.ChainPEM, certBundle.CAPEM)), nil
},
}, nil
},
builder: &testpkg.Builder{
CertManagerObjects: []runtime.Object{baseIssuer.DeepCopy()},
ExpectedEvents: []string{
"Normal CertificateIssued Certificate fetched from venafi issuer successfully",
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews"),
"",
&authzv1.SubjectAccessReview{
Spec: authzv1.SubjectAccessReviewSpec{
User: "user-1",
Groups: []string{"group-1", "group-2"},
Extra: map[string]authzv1.ExtraValue{
"extra": []string{"1", "2"},
},
UID: "uid-1",
ResourceAttributes: &authzv1.ResourceAttributes{
Group: certmanager.GroupName,
Resource: "signers",
Verb: "reference",
Namespace: baseIssuer.Namespace,
Name: baseIssuer.Name,
Version: "*",
},
},
},
)),
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"status",
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestCertificate(certBundle.ChainPEM),
),
)),
testpkg.NewAction(coretesting.NewUpdateAction(
certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"),
"",
gen.CertificateSigningRequestFrom(baseCSR.DeepCopy(),
gen.AddCertificateSigningRequestAnnotations(map[string]string{
"venafi.experimental.cert-manager.io/custom-fields": `[ {"name": "field-name", "value": "vield value"}]`,
"venafi.experimental.cert-manager.io/pickup-id": "test-pickup-id",
}),
gen.SetCertificateSigningRequestStatusCondition(certificatesv1.CertificateSigningRequestCondition{
Type: certificatesv1.CertificateApproved,
Status: corev1.ConditionTrue,
}),
gen.SetCertificateSigningRequestCertificate(certBundle.ChainPEM),
gen.SetCertificateSigningRequestCA(certBundle.CAPEM),
),
)),
},
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
if test.csr != nil {
test.builder.KubeObjects = append(test.builder.KubeObjects, test.csr)
}
fixedClock.SetTime(fixedClockStart)
test.builder.Clock = fixedClock
test.builder.T = t
test.builder.Init()
// Always return true for SubjectAccessReviews in tests
test.builder.FakeKubeClient().PrependReactor("create", "*", func(action coretesting.Action) (bool, runtime.Object, error) {
if action.GetResource() != authzv1.SchemeGroupVersion.WithResource("subjectaccessreviews") {
return false, nil, nil
}
return true, &authzv1.SubjectAccessReview{
Status: authzv1.SubjectAccessReviewStatus{
Allowed: true,
},
}, nil
})
defer test.builder.Stop()
venafi := NewVenafi(test.builder.Context)
venafi.clientBuilder = test.clientBuilder
controller := certificatesigningrequests.New(apiutil.IssuerVenafi, venafi)
controller.Register(test.builder.Context)
test.builder.Start()
err := controller.ProcessItem(context.Background(), test.csr.Name)
if err != nil && !test.expectedErr {
t.Errorf("expected to not get an error, but got: %v", err)
}
if err == nil && test.expectedErr {
t.Errorf("expected to get an error but did not get one")
}
test.builder.CheckAndFinish(err)
})
}
}