Merge pull request #4798 from JoshVanL/controllers-server-side-apply-certificatesigningrequests
Server Side Apply: Adds support for CertificateSigningRequest controllers to use SSA with Feature Gate
This commit is contained in:
commit
56d9423744
@ -515,7 +515,7 @@ rules:
|
||||
verbs: ["get", "list", "watch", "update"]
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["certificatesigningrequests/status"]
|
||||
verbs: ["update"]
|
||||
verbs: ["update", "patch"]
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["signers"]
|
||||
resourceNames: ["issuers.cert-manager.io/*", "clusterissuers.cert-manager.io/*"]
|
||||
|
||||
@ -59,6 +59,9 @@ type ACME struct {
|
||||
acmeClientV cmacmeclientset.AcmeV1Interface
|
||||
certClient certificatesclient.CertificateSigningRequestInterface
|
||||
|
||||
// fieldManager is the manager name used for the Apply operations.
|
||||
fieldManager string
|
||||
|
||||
recorder record.EventRecorder
|
||||
|
||||
copiedAnnotationPrefixes []string
|
||||
@ -84,6 +87,7 @@ func NewACME(ctx *controllerpkg.Context) certificatesigningrequests.Signer {
|
||||
certClient: ctx.Client.CertificatesV1().CertificateSigningRequests(),
|
||||
recorder: ctx.Recorder,
|
||||
copiedAnnotationPrefixes: ctx.CertificateOptions.CopiedAnnotationPrefixes,
|
||||
fieldManager: ctx.FieldManager,
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +108,7 @@ func (a *ACME) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningR
|
||||
log.Error(err, message)
|
||||
a.recorder.Event(csr, corev1.EventTypeWarning, "RequestParsingError", message)
|
||||
ctrlutil.CertificateSigningRequestSetFailed(csr, "RequestParsingError", message)
|
||||
_, uerr := a.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, uerr := ctrlutil.UpdateOrApplyStatus(ctx, a.certClient, csr, certificatesv1.CertificateFailed, a.fieldManager)
|
||||
return uerr
|
||||
}
|
||||
|
||||
@ -117,7 +121,7 @@ func (a *ACME) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningR
|
||||
log.Error(err, message)
|
||||
a.recorder.Event(csr, corev1.EventTypeWarning, "InvalidOrder", message)
|
||||
ctrlutil.CertificateSigningRequestSetFailed(csr, "InvalidOrder", message)
|
||||
_, uerr := a.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, uerr := ctrlutil.UpdateOrApplyStatus(ctx, a.certClient, csr, certificatesv1.CertificateFailed, a.fieldManager)
|
||||
return uerr
|
||||
}
|
||||
|
||||
@ -129,7 +133,7 @@ func (a *ACME) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningR
|
||||
log.Error(err, message)
|
||||
a.recorder.Event(csr, corev1.EventTypeWarning, "OrderBuildingError", message)
|
||||
ctrlutil.CertificateSigningRequestSetFailed(csr, "OrderBuildingError", message)
|
||||
_, uerr := a.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, uerr := ctrlutil.UpdateOrApplyStatus(ctx, a.certClient, csr, certificatesv1.CertificateFailed, a.fieldManager)
|
||||
return uerr
|
||||
}
|
||||
|
||||
@ -174,7 +178,7 @@ func (a *ACME) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningR
|
||||
|
||||
a.recorder.Event(csr, corev1.EventTypeWarning, "OrderFailed", message)
|
||||
ctrlutil.CertificateSigningRequestSetFailed(csr, "OrderFailed", message)
|
||||
_, uerr := a.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, uerr := ctrlutil.UpdateOrApplyStatus(ctx, a.certClient, csr, certificatesv1.CertificateFailed, a.fieldManager)
|
||||
return uerr
|
||||
}
|
||||
|
||||
@ -215,7 +219,7 @@ func (a *ACME) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningR
|
||||
}
|
||||
|
||||
csr.Status.Certificate = order.Status.Certificate
|
||||
csr, err = a.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
csr, err = ctrlutil.UpdateOrApplyStatus(ctx, a.certClient, csr, "", a.fieldManager)
|
||||
if err != nil {
|
||||
message := "Error updating certificate"
|
||||
a.recorder.Eventf(csr, corev1.EventTypeWarning, "SigningError", "%s: %s", message, err)
|
||||
|
||||
@ -18,7 +18,6 @@ go_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",
|
||||
|
||||
@ -25,7 +25,6 @@ import (
|
||||
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"
|
||||
@ -57,6 +56,9 @@ type CA struct {
|
||||
|
||||
certClient certificatesclient.CertificateSigningRequestInterface
|
||||
|
||||
// fieldManager is the manager name used for the Apply operations.
|
||||
fieldManager string
|
||||
|
||||
recorder record.EventRecorder
|
||||
|
||||
// Used for testing to get reproducible resulting certificates
|
||||
@ -78,6 +80,7 @@ func NewCA(ctx *controllerpkg.Context) certificatesigningrequests.Signer {
|
||||
issuerOptions: ctx.IssuerOptions,
|
||||
secretsLister: ctx.KubeSharedInformerFactory.Core().V1().Secrets().Lister(),
|
||||
certClient: ctx.Client.CertificatesV1().CertificateSigningRequests(),
|
||||
fieldManager: ctx.FieldManager,
|
||||
recorder: ctx.Recorder,
|
||||
templateGenerator: pki.GenerateTemplateFromCertificateSigningRequest,
|
||||
signingFn: pki.SignCSRTemplate,
|
||||
@ -120,7 +123,7 @@ func (c *CA) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningReq
|
||||
message := fmt.Sprintf("Error generating certificate template: %s", err)
|
||||
c.recorder.Event(csr, corev1.EventTypeWarning, "SigningError", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "SigningError", message)
|
||||
_, err = c.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err := util.UpdateOrApplyStatus(ctx, c.certClient, csr, certificatesv1.CertificateFailed, c.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -132,12 +135,12 @@ func (c *CA) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningReq
|
||||
message := fmt.Sprintf("Error signing certificate: %s", err)
|
||||
c.recorder.Event(csr, corev1.EventTypeWarning, "SigningError", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "SigningError", message)
|
||||
_, err := c.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err := util.UpdateOrApplyStatus(ctx, c.certClient, csr, certificatesv1.CertificateFailed, c.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
csr.Status.Certificate = bundle.ChainPEM
|
||||
csr, err = c.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
csr, err = util.UpdateOrApplyStatus(ctx, c.certClient, csr, "", c.fieldManager)
|
||||
if err != nil {
|
||||
message := "Error updating certificate"
|
||||
c.recorder.Eventf(csr, corev1.EventTypeWarning, "SigningError", "%s: %s", message, err)
|
||||
|
||||
@ -63,6 +63,9 @@ type Controller struct {
|
||||
csrLister certificateslisters.CertificateSigningRequestLister
|
||||
sarClient authzclient.SubjectAccessReviewInterface
|
||||
|
||||
// fieldManager is the manager name used for the Apply operations.
|
||||
fieldManager string
|
||||
|
||||
queue workqueue.RateLimitingInterface
|
||||
|
||||
// logger to be used by this controller
|
||||
@ -180,6 +183,7 @@ func (c *Controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin
|
||||
// recorder records events about resources to the Kubernetes api
|
||||
c.recorder = ctx.Recorder
|
||||
c.certClient = kubeClient.CertificatesV1().CertificateSigningRequests()
|
||||
c.fieldManager = ctx.FieldManager
|
||||
|
||||
// Construct the signer implementation with the built component context.
|
||||
c.signer = c.signerConstructor(ctx)
|
||||
|
||||
@ -19,7 +19,6 @@ go_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",
|
||||
|
||||
@ -26,7 +26,6 @@ import (
|
||||
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"
|
||||
@ -58,6 +57,9 @@ type SelfSigned struct {
|
||||
|
||||
certClient certificatesclient.CertificateSigningRequestInterface
|
||||
|
||||
// fieldManager is the manager name used for the Apply operations.
|
||||
fieldManager string
|
||||
|
||||
recorder record.EventRecorder
|
||||
|
||||
// Used for testing to get reproducible resulting certificates
|
||||
@ -79,6 +81,7 @@ func NewSelfSigned(ctx *controllerpkg.Context) certificatesigningrequests.Signer
|
||||
issuerOptions: ctx.IssuerOptions,
|
||||
secretsLister: ctx.KubeSharedInformerFactory.Core().V1().Secrets().Lister(),
|
||||
certClient: ctx.Client.CertificatesV1().CertificateSigningRequests(),
|
||||
fieldManager: ctx.FieldManager,
|
||||
recorder: ctx.Recorder,
|
||||
signingFn: pki.SignCertificate,
|
||||
}
|
||||
@ -101,7 +104,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(errors.New(message), "")
|
||||
s.recorder.Event(csr, corev1.EventTypeWarning, "MissingAnnotation", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "MissingAnnotation", message)
|
||||
_, err := s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err := util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -113,7 +116,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(err, message)
|
||||
s.recorder.Event(csr, corev1.EventTypeWarning, "SecretNotFound", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "SecretNotFound", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -122,7 +125,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(err, message)
|
||||
s.recorder.Eventf(csr, corev1.EventTypeWarning, "ErrorParsingKey", "%s: %s", message, err)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorParsingKey", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -132,7 +135,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(err, message)
|
||||
s.recorder.Eventf(csr, corev1.EventTypeWarning, "ErrorGettingSecret", "%s: %s", message, err)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorGettingSecret", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -142,7 +145,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(err, message)
|
||||
s.recorder.Event(csr, corev1.EventTypeWarning, "ErrorGenerating", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorGenerating", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -155,7 +158,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(err, message)
|
||||
s.recorder.Event(csr, corev1.EventTypeWarning, "ErrorPublicKey", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorPublicKey", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -169,7 +172,7 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
log.Error(err, message)
|
||||
s.recorder.Event(csr, corev1.EventTypeWarning, "ErrorKeyMatch", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorKeyMatch", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -178,12 +181,12 @@ func (s *SelfSigned) Sign(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
message := fmt.Sprintf("Error signing certificate: %s", err)
|
||||
s.recorder.Event(csr, corev1.EventTypeWarning, "ErrorSigning", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorSigning", message)
|
||||
_, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, certificatesv1.CertificateFailed, s.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
csr.Status.Certificate = certPEM
|
||||
csr, err = s.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
csr, err = util.UpdateOrApplyStatus(ctx, s.certClient, csr, "", s.fieldManager)
|
||||
if err != nil {
|
||||
message := "Error updating certificate"
|
||||
s.recorder.Eventf(csr, corev1.EventTypeWarning, "ErrorUpdate", "%s: %s", message, err)
|
||||
|
||||
@ -119,11 +119,8 @@ func (c *Controller) Sync(ctx context.Context, csr *certificatesv1.CertificateSi
|
||||
message := fmt.Sprintf("Requester may not reference Namespaced Issuer %s/%s", ref.Namespace, ref.Name)
|
||||
c.recorder.Event(csr, corev1.EventTypeWarning, "DeniedReference", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "DeniedReference", message)
|
||||
if _, err := c.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
_, err := util.UpdateOrApplyStatus(ctx, c.certClient, csr, certificatesv1.CertificateFailed, c.fieldManager)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,25 +3,37 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"apply.go",
|
||||
"conditions.go",
|
||||
"signername.go",
|
||||
],
|
||||
importpath = "github.com/cert-manager/cert-manager/pkg/controller/certificatesigningrequests/util",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//internal/controller/feature:go_default_library",
|
||||
"//pkg/apis/certmanager/v1:go_default_library",
|
||||
"//pkg/logs:go_default_library",
|
||||
"//pkg/util/feature:go_default_library",
|
||||
"@io_k8s_api//certificates/v1:go_default_library",
|
||||
"@io_k8s_api//core/v1:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
|
||||
"@io_k8s_client_go//applyconfigurations/certificates/v1:go_default_library",
|
||||
"@io_k8s_client_go//kubernetes/typed/certificates/v1:go_default_library",
|
||||
"@io_k8s_utils//clock:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["signername_test.go"],
|
||||
srcs = [
|
||||
"conditions_test.go",
|
||||
"signername_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"@com_github_stretchr_testify//assert:go_default_library",
|
||||
"@io_k8s_api//certificates/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
||||
64
pkg/controller/certificatesigningrequests/util/apply.go
Normal file
64
pkg/controller/certificatesigningrequests/util/apply.go
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
certificatesv1 "k8s.io/api/certificates/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
certificatesapply "k8s.io/client-go/applyconfigurations/certificates/v1"
|
||||
certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1"
|
||||
|
||||
"github.com/cert-manager/cert-manager/internal/controller/feature"
|
||||
utilfeature "github.com/cert-manager/cert-manager/pkg/util/feature"
|
||||
)
|
||||
|
||||
// UpdateOrApplyStatus will update a CertificateSigningRequest's status, or
|
||||
// Apply if the ServerSideApply feature gate is enabled.
|
||||
// When the ServerSideApply feature is enabled; condType is optional, and will
|
||||
// only be applied if non-empty and the condition with that type exists on the
|
||||
// CertificateSigningRequest.
|
||||
func UpdateOrApplyStatus(ctx context.Context,
|
||||
cl certificatesclient.CertificateSigningRequestInterface,
|
||||
csr *certificatesv1.CertificateSigningRequest,
|
||||
condType certificatesv1.RequestConditionType,
|
||||
fieldManager string,
|
||||
) (*certificatesv1.CertificateSigningRequest, error) {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(feature.ServerSideApply) {
|
||||
status := certificatesapply.CertificateSigningRequestStatus().
|
||||
WithCertificate(csr.Status.Certificate...)
|
||||
|
||||
if len(condType) > 0 {
|
||||
cond := certificateSigningRequestGetCondition(csr, condType)
|
||||
if cond != nil {
|
||||
status = status.WithConditions(
|
||||
&certificatesapply.CertificateSigningRequestConditionApplyConfiguration{
|
||||
Type: &cond.Type, Status: &cond.Status, Reason: &cond.Reason, Message: &cond.Message,
|
||||
LastTransitionTime: &cond.LastTransitionTime, LastUpdateTime: &cond.LastUpdateTime,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return cl.ApplyStatus(ctx, certificatesapply.CertificateSigningRequest(csr.Name).WithStatus(status),
|
||||
metav1.ApplyOptions{Force: true, FieldManager: fieldManager},
|
||||
)
|
||||
} else {
|
||||
return cl.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
}
|
||||
}
|
||||
@ -72,3 +72,12 @@ func CertificateSigningRequestSetFailed(csr *certificatesv1.CertificateSigningRe
|
||||
logf.V(logf.InfoLevel).Infof("Setting lastTransitionTime for CertificateSigningRequest %s/%s condition Failed to %v",
|
||||
csr.Namespace, csr.Name, nowTime.Time)
|
||||
}
|
||||
|
||||
func certificateSigningRequestGetCondition(csr *certificatesv1.CertificateSigningRequest, condType certificatesv1.RequestConditionType) *certificatesv1.CertificateSigningRequestCondition {
|
||||
for _, cond := range csr.Status.Conditions {
|
||||
if cond.Type == condType {
|
||||
return &cond
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
certificatesv1 "k8s.io/api/certificates/v1"
|
||||
)
|
||||
|
||||
func Test_certificateSigningRequestGetCondition(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
conditions []certificatesv1.CertificateSigningRequestCondition
|
||||
condType certificatesv1.RequestConditionType
|
||||
expCondition *certificatesv1.CertificateSigningRequestCondition
|
||||
}{
|
||||
"if no conditions exist, return nil": {
|
||||
conditions: []certificatesv1.CertificateSigningRequestCondition{},
|
||||
condType: certificatesv1.RequestConditionType("a"),
|
||||
expCondition: nil,
|
||||
},
|
||||
"if conditions exist but type doesn't match, return nil": {
|
||||
conditions: []certificatesv1.CertificateSigningRequestCondition{
|
||||
{Type: certificatesv1.RequestConditionType("a")},
|
||||
{Type: certificatesv1.RequestConditionType("b")},
|
||||
},
|
||||
condType: certificatesv1.RequestConditionType("c"),
|
||||
expCondition: nil,
|
||||
},
|
||||
"if conditions exist and type matches, return condition": {
|
||||
conditions: []certificatesv1.CertificateSigningRequestCondition{
|
||||
{Type: certificatesv1.RequestConditionType("a")},
|
||||
{Type: certificatesv1.RequestConditionType("b")},
|
||||
{Type: certificatesv1.RequestConditionType("c")},
|
||||
},
|
||||
condType: certificatesv1.RequestConditionType("c"),
|
||||
expCondition: &certificatesv1.CertificateSigningRequestCondition{Type: certificatesv1.RequestConditionType("c")},
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
gotCondition := certificateSigningRequestGetCondition(&certificatesv1.CertificateSigningRequest{
|
||||
Status: certificatesv1.CertificateSigningRequestStatus{
|
||||
Conditions: test.conditions,
|
||||
},
|
||||
}, test.condType)
|
||||
assert.Equal(t, test.expCondition, gotCondition)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,6 @@ go_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",
|
||||
|
||||
@ -25,7 +25,6 @@ import (
|
||||
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"
|
||||
@ -56,6 +55,9 @@ type Vault struct {
|
||||
|
||||
certClient certificatesclient.CertificateSigningRequestInterface
|
||||
clientBuilder internalvault.ClientBuilder
|
||||
|
||||
// fieldManager is the manager name used for the Apply operations.
|
||||
fieldManager string
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -73,6 +75,7 @@ func NewVault(ctx *controllerpkg.Context) certificatesigningrequests.Signer {
|
||||
recorder: ctx.Recorder,
|
||||
certClient: ctx.Client.CertificatesV1().CertificateSigningRequests(),
|
||||
clientBuilder: internalvault.New,
|
||||
fieldManager: ctx.FieldManager,
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +95,7 @@ func (v *Vault) Sign(ctx context.Context, csr *certificatesv1.CertificateSigning
|
||||
log.Error(err, message)
|
||||
v.recorder.Event(csr, corev1.EventTypeWarning, "SecretNotFound", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "SecretNotFound", message)
|
||||
_, err := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -109,7 +112,7 @@ func (v *Vault) Sign(ctx context.Context, csr *certificatesv1.CertificateSigning
|
||||
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{})
|
||||
_, err := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -119,14 +122,14 @@ func (v *Vault) Sign(ctx context.Context, csr *certificatesv1.CertificateSigning
|
||||
log.Error(err, message)
|
||||
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorSigning", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorSigning", message)
|
||||
_, err := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, err := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return err
|
||||
}
|
||||
|
||||
log.V(logf.DebugLevel).Info("certificate issued")
|
||||
|
||||
csr.Status.Certificate = certPEM
|
||||
csr, err = v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
csr, err = util.UpdateOrApplyStatus(ctx, v.certClient, csr, "", v.fieldManager)
|
||||
if err != nil {
|
||||
message := "Error updating certificate"
|
||||
v.recorder.Eventf(csr, corev1.EventTypeWarning, "ErrorUpdate", "%s: %s", message, err)
|
||||
|
||||
@ -57,6 +57,9 @@ type Venafi struct {
|
||||
recorder record.EventRecorder
|
||||
|
||||
clientBuilder venaficlient.VenafiClientBuilder
|
||||
|
||||
// fieldManager is the manager name used for the Apply operations.
|
||||
fieldManager string
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -74,6 +77,7 @@ func NewVenafi(ctx *controllerpkg.Context) certificatesigningrequests.Signer {
|
||||
certClient: ctx.Client.CertificatesV1().CertificateSigningRequests(),
|
||||
recorder: ctx.Recorder,
|
||||
clientBuilder: venaficlient.New,
|
||||
fieldManager: ctx.FieldManager,
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +117,7 @@ func (v *Venafi) Sign(ctx context.Context, csr *certificatesv1.CertificateSignin
|
||||
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)
|
||||
_, userr := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, userr := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return userr
|
||||
}
|
||||
}
|
||||
@ -124,7 +128,7 @@ func (v *Venafi) Sign(ctx context.Context, csr *certificatesv1.CertificateSignin
|
||||
log.Error(err, message)
|
||||
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorParseDuration", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorParseDuration", message)
|
||||
_, userr := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, userr := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return userr
|
||||
}
|
||||
|
||||
@ -144,7 +148,7 @@ func (v *Venafi) Sign(ctx context.Context, csr *certificatesv1.CertificateSignin
|
||||
log.Error(err, "")
|
||||
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorCustomFields", err.Error())
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorCustomFields", err.Error())
|
||||
_, userr := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, userr := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return userr
|
||||
|
||||
default:
|
||||
@ -152,7 +156,7 @@ func (v *Venafi) Sign(ctx context.Context, csr *certificatesv1.CertificateSignin
|
||||
log.Error(err, message)
|
||||
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorRequest", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorRequest", message)
|
||||
_, userr := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, userr := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return userr
|
||||
}
|
||||
}
|
||||
@ -194,12 +198,12 @@ func (v *Venafi) Sign(ctx context.Context, csr *certificatesv1.CertificateSignin
|
||||
log.Error(err, message)
|
||||
v.recorder.Event(csr, corev1.EventTypeWarning, "ErrorParse", message)
|
||||
util.CertificateSigningRequestSetFailed(csr, "ErrorParse", message)
|
||||
_, userr := v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
_, userr := util.UpdateOrApplyStatus(ctx, v.certClient, csr, certificatesv1.CertificateFailed, v.fieldManager)
|
||||
return userr
|
||||
}
|
||||
|
||||
csr.Status.Certificate = bundle.ChainPEM
|
||||
csr, err = v.certClient.UpdateStatus(ctx, csr, metav1.UpdateOptions{})
|
||||
csr, err = util.UpdateOrApplyStatus(ctx, v.certClient, csr, "", v.fieldManager)
|
||||
if err != nil {
|
||||
message := "Error updating certificate"
|
||||
v.recorder.Eventf(csr, corev1.EventTypeWarning, "SigningError", "%s: %s", message, err)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user