mirror of
https://github.com/kubernetes/client-go.git
synced 2025-09-20 18:48:02 +00:00
Switch cert manager to v1 CSR API by default, falling back to v1beta1
Kubernetes-commit: a298c14f18d4973a9ceaf21f1e0dc4e39b4c5bfb
This commit is contained in:
committed by
Kubernetes Publisher
parent
0adb702ae4
commit
3ab7d09ea9
@@ -18,7 +18,6 @@ package certificate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
@@ -28,12 +27,19 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
certificates "k8s.io/api/certificates/v1beta1"
|
||||
certificatesv1 "k8s.io/api/certificates/v1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
var storeCertData = newCertificateData(`-----BEGIN CERTIFICATE-----
|
||||
@@ -219,7 +225,7 @@ func TestNewManagerNoRotation(t *testing.T) {
|
||||
}
|
||||
if _, err := NewManager(&Config{
|
||||
Template: &x509.CertificateRequest{},
|
||||
Usages: []certificates.KeyUsage{},
|
||||
Usages: []certificatesv1.KeyUsage{},
|
||||
CertificateStore: store,
|
||||
}); err != nil {
|
||||
t.Fatalf("Failed to initialize the certificate manager: %v", err)
|
||||
@@ -271,7 +277,7 @@ func TestSetRotationDeadline(t *testing.T) {
|
||||
},
|
||||
},
|
||||
getTemplate: func() *x509.CertificateRequest { return &x509.CertificateRequest{} },
|
||||
usages: []certificates.KeyUsage{},
|
||||
usages: []certificatesv1.KeyUsage{},
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
jitteryDuration = func(float64) time.Duration { return time.Duration(float64(tc.notAfter.Sub(tc.notBefore)) * 0.7) }
|
||||
@@ -465,9 +471,9 @@ func TestRotateCertCreateCSRError(t *testing.T) {
|
||||
},
|
||||
},
|
||||
getTemplate: func() *x509.CertificateRequest { return &x509.CertificateRequest{} },
|
||||
usages: []certificates.KeyUsage{},
|
||||
clientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return fakeClient{failureType: createError}, nil
|
||||
usages: []certificatesv1.KeyUsage{},
|
||||
clientsetFn: func(_ *tls.Certificate) (clientset.Interface, error) {
|
||||
return newClientset(fakeClient{failureType: createError}), nil
|
||||
},
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
@@ -489,9 +495,9 @@ func TestRotateCertWaitingForResultError(t *testing.T) {
|
||||
},
|
||||
},
|
||||
getTemplate: func() *x509.CertificateRequest { return &x509.CertificateRequest{} },
|
||||
usages: []certificates.KeyUsage{},
|
||||
clientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return fakeClient{failureType: watchError}, nil
|
||||
usages: []certificatesv1.KeyUsage{},
|
||||
clientsetFn: func(_ *tls.Certificate) (clientset.Interface, error) {
|
||||
return newClientset(fakeClient{failureType: watchError}), nil
|
||||
},
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
@@ -511,7 +517,7 @@ func TestNewManagerBootstrap(t *testing.T) {
|
||||
var cm Manager
|
||||
cm, err := NewManager(&Config{
|
||||
Template: &x509.CertificateRequest{},
|
||||
Usages: []certificates.KeyUsage{},
|
||||
Usages: []certificatesv1.KeyUsage{},
|
||||
CertificateStore: store,
|
||||
BootstrapCertificatePEM: bootstrapCertData.certificatePEM,
|
||||
BootstrapKeyPEM: bootstrapCertData.keyPEM,
|
||||
@@ -548,7 +554,7 @@ func TestNewManagerNoBootstrap(t *testing.T) {
|
||||
|
||||
cm, err := NewManager(&Config{
|
||||
Template: &x509.CertificateRequest{},
|
||||
Usages: []certificates.KeyUsage{},
|
||||
Usages: []certificatesv1.KeyUsage{},
|
||||
CertificateStore: store,
|
||||
BootstrapCertificatePEM: bootstrapCertData.certificatePEM,
|
||||
BootstrapKeyPEM: bootstrapCertData.keyPEM,
|
||||
@@ -644,6 +650,8 @@ func TestInitializeCertificateSigningRequestClient(t *testing.T) {
|
||||
storeCert *certificateData
|
||||
bootstrapCert *certificateData
|
||||
apiCert *certificateData
|
||||
noV1 bool
|
||||
noV1beta1 bool
|
||||
expectedCertBeforeStart *certificateData
|
||||
expectedCertAfterStart *certificateData
|
||||
}{
|
||||
@@ -655,6 +663,24 @@ func TestInitializeCertificateSigningRequestClient(t *testing.T) {
|
||||
expectedCertBeforeStart: nilCertificate,
|
||||
expectedCertAfterStart: apiServerCertData,
|
||||
},
|
||||
{
|
||||
description: "No current certificate, no bootstrap certificate, no v1 API",
|
||||
storeCert: nilCertificate,
|
||||
bootstrapCert: nilCertificate,
|
||||
apiCert: apiServerCertData,
|
||||
expectedCertBeforeStart: nilCertificate,
|
||||
expectedCertAfterStart: apiServerCertData,
|
||||
noV1: true,
|
||||
},
|
||||
{
|
||||
description: "No current certificate, no bootstrap certificate, no v1beta1 API",
|
||||
storeCert: nilCertificate,
|
||||
bootstrapCert: nilCertificate,
|
||||
apiCert: apiServerCertData,
|
||||
expectedCertBeforeStart: nilCertificate,
|
||||
expectedCertAfterStart: apiServerCertData,
|
||||
noV1beta1: true,
|
||||
},
|
||||
{
|
||||
description: "No current certificate, bootstrap certificate",
|
||||
storeCert: nilCertificate,
|
||||
@@ -702,18 +728,21 @@ func TestInitializeCertificateSigningRequestClient(t *testing.T) {
|
||||
CommonName: "system:node:fake-node-name",
|
||||
},
|
||||
},
|
||||
Usages: []certificates.KeyUsage{
|
||||
certificates.UsageDigitalSignature,
|
||||
certificates.UsageKeyEncipherment,
|
||||
certificates.UsageClientAuth,
|
||||
SignerName: certificatesv1.KubeAPIServerClientSignerName,
|
||||
Usages: []certificatesv1.KeyUsage{
|
||||
certificatesv1.UsageDigitalSignature,
|
||||
certificatesv1.UsageKeyEncipherment,
|
||||
certificatesv1.UsageClientAuth,
|
||||
},
|
||||
CertificateStore: certificateStore,
|
||||
BootstrapCertificatePEM: tc.bootstrapCert.certificatePEM,
|
||||
BootstrapKeyPEM: tc.bootstrapCert.keyPEM,
|
||||
ClientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return &fakeClient{
|
||||
ClientsetFn: func(_ *tls.Certificate) (clientset.Interface, error) {
|
||||
return newClientset(fakeClient{
|
||||
noV1: tc.noV1,
|
||||
noV1beta1: tc.noV1beta1,
|
||||
certificatePEM: tc.apiCert.certificatePEM,
|
||||
}, nil
|
||||
}), nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -814,18 +843,18 @@ func TestInitializeOtherRESTClients(t *testing.T) {
|
||||
CommonName: "system:node:fake-node-name",
|
||||
},
|
||||
},
|
||||
Usages: []certificates.KeyUsage{
|
||||
certificates.UsageDigitalSignature,
|
||||
certificates.UsageKeyEncipherment,
|
||||
certificates.UsageClientAuth,
|
||||
Usages: []certificatesv1.KeyUsage{
|
||||
certificatesv1.UsageDigitalSignature,
|
||||
certificatesv1.UsageKeyEncipherment,
|
||||
certificatesv1.UsageClientAuth,
|
||||
},
|
||||
CertificateStore: certificateStore,
|
||||
BootstrapCertificatePEM: tc.bootstrapCert.certificatePEM,
|
||||
BootstrapKeyPEM: tc.bootstrapCert.keyPEM,
|
||||
ClientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return &fakeClient{
|
||||
ClientsetFn: func(_ *tls.Certificate) (clientset.Interface, error) {
|
||||
return newClientset(fakeClient{
|
||||
certificatePEM: tc.apiCert.certificatePEM,
|
||||
}, nil
|
||||
}), nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -959,20 +988,20 @@ func TestServerHealth(t *testing.T) {
|
||||
CommonName: "system:node:fake-node-name",
|
||||
},
|
||||
},
|
||||
Usages: []certificates.KeyUsage{
|
||||
certificates.UsageDigitalSignature,
|
||||
certificates.UsageKeyEncipherment,
|
||||
certificates.UsageClientAuth,
|
||||
Usages: []certificatesv1.KeyUsage{
|
||||
certificatesv1.UsageDigitalSignature,
|
||||
certificatesv1.UsageKeyEncipherment,
|
||||
certificatesv1.UsageClientAuth,
|
||||
},
|
||||
CertificateStore: certificateStore,
|
||||
BootstrapCertificatePEM: tc.bootstrapCert.certificatePEM,
|
||||
BootstrapKeyPEM: tc.bootstrapCert.keyPEM,
|
||||
ClientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return &fakeClient{
|
||||
ClientsetFn: func(_ *tls.Certificate) (clientset.Interface, error) {
|
||||
return newClientset(fakeClient{
|
||||
certificatePEM: tc.apiCert.certificatePEM,
|
||||
failureType: tc.failureType,
|
||||
err: tc.clientErr,
|
||||
}, nil
|
||||
}), nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -1022,10 +1051,10 @@ func TestRotationLogsDuration(t *testing.T) {
|
||||
},
|
||||
certStore: &fakeStore{cert: expiredStoreCertData.certificate},
|
||||
getTemplate: func() *x509.CertificateRequest { return &x509.CertificateRequest{} },
|
||||
clientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return &fakeClient{
|
||||
clientsetFn: func(_ *tls.Certificate) (clientset.Interface, error) {
|
||||
return newClientset(fakeClient{
|
||||
certificatePEM: apiServerCertData.certificatePEM,
|
||||
}, nil
|
||||
}), nil
|
||||
},
|
||||
certificateRotation: &h,
|
||||
now: func() time.Time { return now },
|
||||
@@ -1053,53 +1082,101 @@ const (
|
||||
)
|
||||
|
||||
type fakeClient struct {
|
||||
noV1 bool
|
||||
noV1beta1 bool
|
||||
certificatesclient.CertificateSigningRequestInterface
|
||||
failureType fakeClientFailureType
|
||||
certificatePEM []byte
|
||||
err error
|
||||
}
|
||||
|
||||
func (c fakeClient) List(_ context.Context, opts v1.ListOptions) (*certificates.CertificateSigningRequestList, error) {
|
||||
if c.failureType == watchError {
|
||||
if c.err != nil {
|
||||
return nil, c.err
|
||||
}
|
||||
return nil, fmt.Errorf("Watch error")
|
||||
}
|
||||
csrReply := certificates.CertificateSigningRequestList{
|
||||
Items: []certificates.CertificateSigningRequest{
|
||||
{ObjectMeta: v1.ObjectMeta{UID: "fake-uid"}},
|
||||
},
|
||||
}
|
||||
return &csrReply, nil
|
||||
}
|
||||
func newClientset(opts fakeClient) *fake.Clientset {
|
||||
f := fake.NewSimpleClientset()
|
||||
switch opts.failureType {
|
||||
case createError:
|
||||
f.PrependReactor("create", "certificatesigningrequests", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if opts.err != nil {
|
||||
return true, nil, opts.err
|
||||
}
|
||||
return true, nil, fmt.Errorf("create error")
|
||||
})
|
||||
case watchError:
|
||||
f.PrependReactor("list", "certificatesigningrequests", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if opts.err != nil {
|
||||
return true, nil, opts.err
|
||||
}
|
||||
return true, nil, fmt.Errorf("watch error")
|
||||
})
|
||||
f.PrependWatchReactor("certificatesigningrequests", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
|
||||
if opts.err != nil {
|
||||
return true, nil, opts.err
|
||||
}
|
||||
return true, nil, fmt.Errorf("watch error")
|
||||
})
|
||||
default:
|
||||
f.PrependReactor("create", "certificatesigningrequests", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
switch action.GetResource().Version {
|
||||
case "v1":
|
||||
if opts.noV1 {
|
||||
return true, nil, apierrors.NewNotFound(certificatesv1.Resource("certificatesigningrequests"), "")
|
||||
}
|
||||
return true, &certificatesv1.CertificateSigningRequest{ObjectMeta: metav1.ObjectMeta{UID: "fake-uid"}}, nil
|
||||
case "v1beta1":
|
||||
if opts.noV1beta1 {
|
||||
return true, nil, apierrors.NewNotFound(certificatesv1.Resource("certificatesigningrequests"), "")
|
||||
}
|
||||
return true, &certificatesv1beta1.CertificateSigningRequest{ObjectMeta: metav1.ObjectMeta{UID: "fake-uid"}}, nil
|
||||
default:
|
||||
return false, nil, nil
|
||||
}
|
||||
})
|
||||
f.PrependReactor("list", "certificatesigningrequests", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
switch action.GetResource().Version {
|
||||
case "v1":
|
||||
if opts.noV1 {
|
||||
return true, nil, apierrors.NewNotFound(certificatesv1.Resource("certificatesigningrequests"), "")
|
||||
}
|
||||
return true, &certificatesv1.CertificateSigningRequestList{Items: []certificatesv1.CertificateSigningRequest{{ObjectMeta: v1.ObjectMeta{UID: "fake-uid"}}}}, nil
|
||||
case "v1beta1":
|
||||
if opts.noV1beta1 {
|
||||
return true, nil, apierrors.NewNotFound(certificatesv1.Resource("certificatesigningrequests"), "")
|
||||
}
|
||||
return true, &certificatesv1beta1.CertificateSigningRequestList{Items: []certificatesv1beta1.CertificateSigningRequest{{ObjectMeta: v1.ObjectMeta{UID: "fake-uid"}}}}, nil
|
||||
default:
|
||||
return false, nil, nil
|
||||
}
|
||||
})
|
||||
f.PrependWatchReactor("certificatesigningrequests", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
|
||||
switch action.GetResource().Version {
|
||||
case "v1":
|
||||
if opts.noV1 {
|
||||
return true, nil, apierrors.NewNotFound(certificatesv1.Resource("certificatesigningrequests"), "")
|
||||
}
|
||||
return true, &fakeWatch{
|
||||
version: action.GetResource().Version,
|
||||
failureType: opts.failureType,
|
||||
certificatePEM: opts.certificatePEM,
|
||||
}, nil
|
||||
|
||||
func (c fakeClient) Create(context.Context, *certificates.CertificateSigningRequest, v1.CreateOptions) (*certificates.CertificateSigningRequest, error) {
|
||||
if c.failureType == createError {
|
||||
if c.err != nil {
|
||||
return nil, c.err
|
||||
}
|
||||
return nil, fmt.Errorf("create error")
|
||||
case "v1beta1":
|
||||
if opts.noV1beta1 {
|
||||
return true, nil, apierrors.NewNotFound(certificatesv1.Resource("certificatesigningrequests"), "")
|
||||
}
|
||||
return true, &fakeWatch{
|
||||
version: action.GetResource().Version,
|
||||
failureType: opts.failureType,
|
||||
certificatePEM: opts.certificatePEM,
|
||||
}, nil
|
||||
default:
|
||||
return false, nil, nil
|
||||
}
|
||||
})
|
||||
}
|
||||
csrReply := certificates.CertificateSigningRequest{}
|
||||
csrReply.UID = "fake-uid"
|
||||
return &csrReply, nil
|
||||
}
|
||||
|
||||
func (c fakeClient) Watch(_ context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
if c.failureType == watchError {
|
||||
if c.err != nil {
|
||||
return nil, c.err
|
||||
}
|
||||
return nil, fmt.Errorf("watch error")
|
||||
}
|
||||
return &fakeWatch{
|
||||
failureType: c.failureType,
|
||||
certificatePEM: c.certificatePEM,
|
||||
}, nil
|
||||
return f
|
||||
}
|
||||
|
||||
type fakeWatch struct {
|
||||
version string
|
||||
failureType fakeClientFailureType
|
||||
certificatePEM []byte
|
||||
}
|
||||
@@ -1108,31 +1185,58 @@ func (w *fakeWatch) Stop() {
|
||||
}
|
||||
|
||||
func (w *fakeWatch) ResultChan() <-chan watch.Event {
|
||||
var condition certificates.CertificateSigningRequestCondition
|
||||
if w.failureType == certificateSigningRequestDenied {
|
||||
condition = certificates.CertificateSigningRequestCondition{
|
||||
Type: certificates.CertificateDenied,
|
||||
}
|
||||
} else {
|
||||
condition = certificates.CertificateSigningRequestCondition{
|
||||
Type: certificates.CertificateApproved,
|
||||
}
|
||||
}
|
||||
var csr runtime.Object
|
||||
|
||||
csr := certificates.CertificateSigningRequest{
|
||||
Status: certificates.CertificateSigningRequestStatus{
|
||||
Conditions: []certificates.CertificateSigningRequestCondition{
|
||||
condition,
|
||||
switch w.version {
|
||||
case "v1":
|
||||
var condition certificatesv1.CertificateSigningRequestCondition
|
||||
if w.failureType == certificateSigningRequestDenied {
|
||||
condition = certificatesv1.CertificateSigningRequestCondition{
|
||||
Type: certificatesv1.CertificateDenied,
|
||||
}
|
||||
} else {
|
||||
condition = certificatesv1.CertificateSigningRequestCondition{
|
||||
Type: certificatesv1.CertificateApproved,
|
||||
}
|
||||
}
|
||||
|
||||
csr = &certificatesv1.CertificateSigningRequest{
|
||||
ObjectMeta: metav1.ObjectMeta{UID: "fake-uid"},
|
||||
Status: certificatesv1.CertificateSigningRequestStatus{
|
||||
Conditions: []certificatesv1.CertificateSigningRequestCondition{
|
||||
condition,
|
||||
},
|
||||
Certificate: []byte(w.certificatePEM),
|
||||
},
|
||||
Certificate: []byte(w.certificatePEM),
|
||||
},
|
||||
}
|
||||
|
||||
case "v1beta1":
|
||||
var condition certificatesv1beta1.CertificateSigningRequestCondition
|
||||
if w.failureType == certificateSigningRequestDenied {
|
||||
condition = certificatesv1beta1.CertificateSigningRequestCondition{
|
||||
Type: certificatesv1beta1.CertificateDenied,
|
||||
}
|
||||
} else {
|
||||
condition = certificatesv1beta1.CertificateSigningRequestCondition{
|
||||
Type: certificatesv1beta1.CertificateApproved,
|
||||
}
|
||||
}
|
||||
|
||||
csr = &certificatesv1beta1.CertificateSigningRequest{
|
||||
ObjectMeta: metav1.ObjectMeta{UID: "fake-uid"},
|
||||
Status: certificatesv1beta1.CertificateSigningRequestStatus{
|
||||
Conditions: []certificatesv1beta1.CertificateSigningRequestCondition{
|
||||
condition,
|
||||
},
|
||||
Certificate: []byte(w.certificatePEM),
|
||||
},
|
||||
}
|
||||
}
|
||||
csr.UID = "fake-uid"
|
||||
|
||||
c := make(chan watch.Event, 1)
|
||||
c <- watch.Event{
|
||||
Type: watch.Added,
|
||||
Object: &csr,
|
||||
Object: csr,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
Reference in New Issue
Block a user