Merge pull request #91713 from liggitt/csr-v1-manager

CSR v1 - switch controllers
This commit is contained in:
Kubernetes Prow Robot 2020-06-09 14:49:30 -07:00 committed by GitHub
commit 11fe6e815f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 213 additions and 190 deletions

View File

@ -89,7 +89,7 @@ func startCSRSigningController(ctx ControllerContext) (http.Handler, bool, error
} }
c := ctx.ClientBuilder.ClientOrDie("certificate-controller") c := ctx.ClientBuilder.ClientOrDie("certificate-controller")
csrInformer := ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests() csrInformer := ctx.InformerFactory.Certificates().V1().CertificateSigningRequests()
certTTL := ctx.ComponentConfig.CSRSigningController.ClusterSigningDuration.Duration certTTL := ctx.ComponentConfig.CSRSigningController.ClusterSigningDuration.Duration
caFile, caKeyFile := getKubeletServingSignerFiles(ctx.ComponentConfig.CSRSigningController) caFile, caKeyFile := getKubeletServingSignerFiles(ctx.ComponentConfig.CSRSigningController)
@ -137,7 +137,7 @@ func startCSRApprovingController(ctx ControllerContext) (http.Handler, bool, err
approver := approver.NewCSRApprovingController( approver := approver.NewCSRApprovingController(
ctx.ClientBuilder.ClientOrDie("certificate-controller"), ctx.ClientBuilder.ClientOrDie("certificate-controller"),
ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(), ctx.InformerFactory.Certificates().V1().CertificateSigningRequests(),
) )
go approver.Run(1, ctx.Stop) go approver.Run(1, ctx.Stop)
@ -146,8 +146,8 @@ func startCSRApprovingController(ctx ControllerContext) (http.Handler, bool, err
func startCSRCleanerController(ctx ControllerContext) (http.Handler, bool, error) { func startCSRCleanerController(ctx ControllerContext) (http.Handler, bool, error) {
cleaner := cleaner.NewCSRCleanerController( cleaner := cleaner.NewCSRCleanerController(
ctx.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1beta1().CertificateSigningRequests(), ctx.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1().CertificateSigningRequests(),
ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(), ctx.InformerFactory.Certificates().V1().CertificateSigningRequests(),
) )
go cleaner.Run(1, ctx.Stop) go cleaner.Run(1, ctx.Stop)
return nil, true, nil return nil, true, nil

View File

@ -20,6 +20,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
], ],
) )

View File

@ -20,12 +20,15 @@ import (
"crypto/x509" "crypto/x509"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt"
"reflect"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
) )
// ParseCSR extracts the CSR from the API object and decodes it. // ParseCSR extracts the CSR from the bytes and decodes it.
func ParseCSR(obj *CertificateSigningRequest) (*x509.CertificateRequest, error) { func ParseCSR(pemBytes []byte) (*x509.CertificateRequest, error) {
// extract PEM from request object
pemBytes := obj.Spec.Request
block, _ := pem.Decode(pemBytes) block, _ := pem.Decode(pemBytes)
if block == nil || block.Type != "CERTIFICATE REQUEST" { if block == nil || block.Type != "CERTIFICATE REQUEST" {
return nil, errors.New("PEM block type must be CERTIFICATE REQUEST") return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
@ -36,3 +39,88 @@ func ParseCSR(obj *CertificateSigningRequest) (*x509.CertificateRequest, error)
} }
return csr, nil return csr, nil
} }
var (
organizationNotSystemNodesErr = fmt.Errorf("subject organization is not system:nodes")
commonNameNotSystemNode = fmt.Errorf("subject common name does not begin with system:node:")
dnsOrIPSANRequiredErr = fmt.Errorf("DNS or IP subjectAltName is required")
dnsSANNotAllowedErr = fmt.Errorf("DNS subjectAltNames are not allowed")
emailSANNotAllowedErr = fmt.Errorf("Email subjectAltNames are not allowed")
ipSANNotAllowedErr = fmt.Errorf("IP subjectAltNames are not allowed")
uriSANNotAllowedErr = fmt.Errorf("URI subjectAltNames are not allowed")
)
var kubeletServingRequiredUsages = sets.NewString(
string(UsageDigitalSignature),
string(UsageKeyEncipherment),
string(UsageServerAuth),
)
func IsKubeletServingCSR(req *x509.CertificateRequest, usages sets.String) bool {
return ValidateKubeletServingCSR(req, usages) == nil
}
func ValidateKubeletServingCSR(req *x509.CertificateRequest, usages sets.String) error {
if !reflect.DeepEqual([]string{"system:nodes"}, req.Subject.Organization) {
return organizationNotSystemNodesErr
}
// at least one of dnsNames or ipAddresses must be specified
if len(req.DNSNames) == 0 && len(req.IPAddresses) == 0 {
return dnsOrIPSANRequiredErr
}
if len(req.EmailAddresses) > 0 {
return emailSANNotAllowedErr
}
if len(req.URIs) > 0 {
return uriSANNotAllowedErr
}
if !kubeletServingRequiredUsages.Equal(usages) {
return fmt.Errorf("usages did not match %v", kubeletServingRequiredUsages.List())
}
if !strings.HasPrefix(req.Subject.CommonName, "system:node:") {
return commonNameNotSystemNode
}
return nil
}
var kubeletClientRequiredUsages = sets.NewString(
string(UsageDigitalSignature),
string(UsageKeyEncipherment),
string(UsageClientAuth),
)
func IsKubeletClientCSR(req *x509.CertificateRequest, usages sets.String) bool {
return ValidateKubeletClientCSR(req, usages) == nil
}
func ValidateKubeletClientCSR(req *x509.CertificateRequest, usages sets.String) error {
if !reflect.DeepEqual([]string{"system:nodes"}, req.Subject.Organization) {
return organizationNotSystemNodesErr
}
if len(req.DNSNames) > 0 {
return dnsSANNotAllowedErr
}
if len(req.EmailAddresses) > 0 {
return emailSANNotAllowedErr
}
if len(req.IPAddresses) > 0 {
return ipSANNotAllowedErr
}
if len(req.URIs) > 0 {
return uriSANNotAllowedErr
}
if !strings.HasPrefix(req.Subject.CommonName, "system:node:") {
return commonNameNotSystemNode
}
if !kubeletClientRequiredUsages.Equal(usages) {
return fmt.Errorf("usages did not match %v", kubeletClientRequiredUsages.List())
}
return nil
}

View File

@ -18,14 +18,12 @@ package v1beta1
import ( import (
"crypto/x509" "crypto/x509"
"fmt"
"reflect"
"strings"
certificatesv1beta1 "k8s.io/api/certificates/v1beta1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
certificates "k8s.io/kubernetes/pkg/apis/certificates"
) )
func addDefaultingFuncs(scheme *runtime.Scheme) error { func addDefaultingFuncs(scheme *runtime.Scheme) error {
@ -67,99 +65,24 @@ func DefaultSignerNameFromSpec(obj *certificatesv1beta1.CertificateSigningReques
} }
} }
var (
organizationNotSystemNodesErr = fmt.Errorf("subject organization is not system:nodes")
commonNameNotSystemNode = fmt.Errorf("subject common name does not begin with system:node:")
dnsOrIPSANRequiredErr = fmt.Errorf("DNS or IP subjectAltName is required")
dnsSANNotAllowedErr = fmt.Errorf("DNS subjectAltNames are not allowed")
emailSANNotAllowedErr = fmt.Errorf("Email subjectAltNames are not allowed")
ipSANNotAllowedErr = fmt.Errorf("IP subjectAltNames are not allowed")
uriSANNotAllowedErr = fmt.Errorf("URI subjectAltNames are not allowed")
)
func IsKubeletServingCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) bool { func IsKubeletServingCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) bool {
return ValidateKubeletServingCSR(req, usages) == nil return certificates.IsKubeletServingCSR(req, usagesToSet(usages))
} }
func ValidateKubeletServingCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) error { func ValidateKubeletServingCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) error {
if !reflect.DeepEqual([]string{"system:nodes"}, req.Subject.Organization) { return certificates.ValidateKubeletServingCSR(req, usagesToSet(usages))
return organizationNotSystemNodesErr
}
// at least one of dnsNames or ipAddresses must be specified
if len(req.DNSNames) == 0 && len(req.IPAddresses) == 0 {
return dnsOrIPSANRequiredErr
}
if len(req.EmailAddresses) > 0 {
return emailSANNotAllowedErr
}
if len(req.URIs) > 0 {
return uriSANNotAllowedErr
}
requiredUsages := []certificatesv1beta1.KeyUsage{
certificatesv1beta1.UsageDigitalSignature,
certificatesv1beta1.UsageKeyEncipherment,
certificatesv1beta1.UsageServerAuth,
}
if !equalUnsorted(requiredUsages, usages) {
return fmt.Errorf("usages did not match %v", requiredUsages)
}
if !strings.HasPrefix(req.Subject.CommonName, "system:node:") {
return commonNameNotSystemNode
}
return nil
} }
func IsKubeletClientCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) bool { func IsKubeletClientCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) bool {
return ValidateKubeletClientCSR(req, usages) == nil return certificates.IsKubeletClientCSR(req, usagesToSet(usages))
} }
func ValidateKubeletClientCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) error { func ValidateKubeletClientCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) error {
if !reflect.DeepEqual([]string{"system:nodes"}, req.Subject.Organization) { return certificates.ValidateKubeletClientCSR(req, usagesToSet(usages))
return organizationNotSystemNodesErr
}
if len(req.DNSNames) > 0 {
return dnsSANNotAllowedErr
}
if len(req.EmailAddresses) > 0 {
return emailSANNotAllowedErr
}
if len(req.IPAddresses) > 0 {
return ipSANNotAllowedErr
}
if len(req.URIs) > 0 {
return uriSANNotAllowedErr
}
if !strings.HasPrefix(req.Subject.CommonName, "system:node:") {
return commonNameNotSystemNode
}
requiredUsages := []certificatesv1beta1.KeyUsage{
certificatesv1beta1.UsageDigitalSignature,
certificatesv1beta1.UsageKeyEncipherment,
certificatesv1beta1.UsageClientAuth,
}
if !equalUnsorted(requiredUsages, usages) {
return fmt.Errorf("usages did not match %v", requiredUsages)
}
return nil
} }
// equalUnsorted compares two []string for equality of contents regardless of func usagesToSet(usages []certificatesv1beta1.KeyUsage) sets.String {
// the order of the elements result := sets.NewString()
func equalUnsorted(left, right []certificatesv1beta1.KeyUsage) bool { for _, usage := range usages {
l := sets.NewString() result.Insert(string(usage))
for _, s := range left {
l.Insert(string(s))
} }
r := sets.NewString() return result
for _, s := range right {
r.Insert(string(s))
}
return l.Equal(r)
} }

View File

@ -84,7 +84,7 @@ type certificateValidationOptions struct {
// PEM-encoded PKCS#10 certificate signing request. If this is invalid, we must // PEM-encoded PKCS#10 certificate signing request. If this is invalid, we must
// not accept the CSR for further processing. // not accept the CSR for further processing.
func validateCSR(obj *certificates.CertificateSigningRequest) error { func validateCSR(obj *certificates.CertificateSigningRequest) error {
csr, err := certificates.ParseCSR(obj) csr, err := certificates.ParseCSR(obj.Spec.Request)
if err != nil { if err != nil {
return err return err
} }

View File

@ -13,17 +13,16 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/controller/certificates", importpath = "k8s.io/kubernetes/pkg/controller/certificates",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/apis/certificates/v1beta1:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/client-go/informers/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/informers/certificates/v1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/listers/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/listers/certificates/v1:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library", "//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
@ -64,7 +63,7 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library",

View File

@ -11,9 +11,9 @@ go_test(
srcs = ["sarapprove_test.go"], srcs = ["sarapprove_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/certificates/v1beta1:go_default_library", "//pkg/apis/certificates/v1:go_default_library",
"//staging/src/k8s.io/api/authorization/v1:go_default_library", "//staging/src/k8s.io/api/authorization/v1:go_default_library",
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
@ -26,12 +26,14 @@ go_library(
srcs = ["sarapprove.go"], srcs = ["sarapprove.go"],
importpath = "k8s.io/kubernetes/pkg/controller/certificates/approver", importpath = "k8s.io/kubernetes/pkg/controller/certificates/approver",
deps = [ deps = [
"//pkg/apis/certificates/v1beta1:go_default_library", "//pkg/apis/certificates:go_default_library",
"//pkg/controller/certificates:go_default_library", "//pkg/controller/certificates:go_default_library",
"//staging/src/k8s.io/api/authorization/v1:go_default_library", "//staging/src/k8s.io/api/authorization/v1:go_default_library",
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/client-go/informers/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/client-go/informers/certificates/v1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
], ],
) )

View File

@ -23,12 +23,14 @@ import (
"fmt" "fmt"
authorization "k8s.io/api/authorization/v1" authorization "k8s.io/api/authorization/v1"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1" "k8s.io/apimachinery/pkg/util/sets"
certificatesinformers "k8s.io/client-go/informers/certificates/v1"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" capihelper "k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/controller/certificates" "k8s.io/kubernetes/pkg/controller/certificates"
) )
@ -100,7 +102,7 @@ func (a *sarApprover) handle(csr *capi.CertificateSigningRequest) error {
} }
if approved { if approved {
appendApprovalCondition(csr, r.successMessage) appendApprovalCondition(csr, r.successMessage)
_, err = a.client.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(context.Background(), csr, metav1.UpdateOptions{}) _, err = a.client.CertificatesV1().CertificateSigningRequests().UpdateApproval(context.Background(), csr.Name, csr, metav1.UpdateOptions{})
if err != nil { if err != nil {
return fmt.Errorf("error updating approval for csr: %v", err) return fmt.Errorf("error updating approval for csr: %v", err)
} }
@ -140,25 +142,30 @@ func (a *sarApprover) authorize(csr *capi.CertificateSigningRequest, rattrs auth
func appendApprovalCondition(csr *capi.CertificateSigningRequest, message string) { func appendApprovalCondition(csr *capi.CertificateSigningRequest, message string) {
csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{ csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{
Type: capi.CertificateApproved, Type: capi.CertificateApproved,
Status: corev1.ConditionTrue,
Reason: "AutoApproved", Reason: "AutoApproved",
Message: message, Message: message,
}) })
} }
func isNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool { func isNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool {
isClientCSR := capihelper.IsKubeletClientCSR(x509cr, csr.Spec.Usages) if csr.Spec.SignerName != capi.KubeAPIServerClientKubeletSignerName {
if !isClientCSR {
return false return false
} }
return *csr.Spec.SignerName == capi.KubeAPIServerClientKubeletSignerName return capihelper.IsKubeletClientCSR(x509cr, usagesToSet(csr.Spec.Usages))
} }
func isSelfNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool { func isSelfNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool {
if !isNodeClientCert(csr, x509cr) {
return false
}
if csr.Spec.Username != x509cr.Subject.CommonName { if csr.Spec.Username != x509cr.Subject.CommonName {
return false return false
} }
return true return isNodeClientCert(csr, x509cr)
}
func usagesToSet(usages []capi.KeyUsage) sets.String {
result := sets.NewString()
for _, usage := range usages {
result.Insert(string(usage))
}
return result
} }

View File

@ -28,12 +28,12 @@ import (
"testing" "testing"
authorization "k8s.io/api/authorization/v1" authorization "k8s.io/api/authorization/v1"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
testclient "k8s.io/client-go/testing" testclient "k8s.io/client-go/testing"
k8s_certificates_v1beta1 "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" k8s_certificates_v1 "k8s.io/kubernetes/pkg/apis/certificates/v1"
) )
func TestHandle(t *testing.T) { func TestHandle(t *testing.T) {
@ -86,7 +86,7 @@ func TestHandle(t *testing.T) {
if got, expected := a.Verb, "update"; got != expected { if got, expected := a.Verb, "update"; got != expected {
t.Errorf("got: %v, expected: %v", got, expected) t.Errorf("got: %v, expected: %v", got, expected)
} }
if got, expected := a.Resource, (schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "certificatesigningrequests"}); got != expected { if got, expected := a.Resource, (schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1", Resource: "certificatesigningrequests"}); got != expected {
t.Errorf("got: %v, expected: %v", got, expected) t.Errorf("got: %v, expected: %v", got, expected)
} }
if got, expected := a.Subresource, "approval"; got != expected { if got, expected := a.Subresource, "approval"; got != expected {
@ -201,7 +201,7 @@ func testRecognizer(t *testing.T, cases []func(b *csrBuilder), recognizeFunc fun
c(&b) c(&b)
t.Run(fmt.Sprintf("csr:%#v", b), func(t *testing.T) { t.Run(fmt.Sprintf("csr:%#v", b), func(t *testing.T) {
csr := makeFancyTestCsr(b) csr := makeFancyTestCsr(b)
x509cr, err := k8s_certificates_v1beta1.ParseCSR(csr.Spec.Request) x509cr, err := k8s_certificates_v1.ParseCSR(csr.Spec.Request)
if err != nil { if err != nil {
t.Errorf("unexpected err: %v", err) t.Errorf("unexpected err: %v", err)
} }
@ -252,7 +252,7 @@ func makeFancyTestCsr(b csrBuilder) *capi.CertificateSigningRequest {
Spec: capi.CertificateSigningRequestSpec{ Spec: capi.CertificateSigningRequestSpec{
Username: b.requestor, Username: b.requestor,
Usages: b.usages, Usages: b.usages,
SignerName: &b.signerName, SignerName: b.signerName,
Request: pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrb}), Request: pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrb}),
}, },
} }

View File

@ -14,7 +14,7 @@ go_library(
"//cmd/kubelet/app:__pkg__", "//cmd/kubelet/app:__pkg__",
"//pkg/controller/certificates:__subpackages__", "//pkg/controller/certificates:__subpackages__",
], ],
deps = ["//staging/src/k8s.io/api/certificates/v1beta1:go_default_library"], deps = ["//staging/src/k8s.io/api/certificates/v1:go_default_library"],
) )
filegroup( filegroup(
@ -39,7 +39,7 @@ go_test(
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/github.com/google/go-cmp/cmp:go_default_library", "//vendor/github.com/google/go-cmp/cmp:go_default_library",
"//vendor/github.com/google/go-cmp/cmp/cmpopts:go_default_library", "//vendor/github.com/google/go-cmp/cmp/cmpopts:go_default_library",

View File

@ -30,7 +30,7 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts" "github.com/google/go-cmp/cmp/cmpopts"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
) )

View File

@ -22,7 +22,7 @@ import (
"sort" "sort"
"time" "time"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
) )
// SigningPolicy validates a CertificateRequest before it's signed by the // SigningPolicy validates a CertificateRequest before it's signed by the

View File

@ -22,7 +22,7 @@ import (
"reflect" "reflect"
"testing" "testing"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
) )
func TestKeyUsagesFromStrings(t *testing.T) { func TestKeyUsagesFromStrings(t *testing.T) {

View File

@ -24,19 +24,18 @@ import (
"golang.org/x/time/rate" "golang.org/x/time/rate"
certificates "k8s.io/api/certificates/v1beta1" certificates "k8s.io/api/certificates/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1" certificatesinformers "k8s.io/client-go/informers/certificates/v1"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
v1core "k8s.io/client-go/kubernetes/typed/core/v1" v1core "k8s.io/client-go/kubernetes/typed/core/v1"
certificateslisters "k8s.io/client-go/listers/certificates/v1beta1" certificateslisters "k8s.io/client-go/listers/certificates/v1"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/klog/v2" "k8s.io/klog/v2"
capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
) )
@ -193,15 +192,6 @@ func (cc *CertificateController) syncFunc(key string) error {
// need to operate on a copy so we don't mutate the csr in the shared cache // need to operate on a copy so we don't mutate the csr in the shared cache
csr = csr.DeepCopy() csr = csr.DeepCopy()
// If the `signerName` field is not set, we are talking to a pre-1.18 apiserver.
// As per the KEP document for the certificates API, this will be defaulted here
// in the controller to maintain backwards compatibility.
// This should be removed after a deprecation window has passed.
// Default here to allow handlers to assume the field is set.
if csr.Spec.SignerName == nil {
signerName := capihelper.DefaultSignerNameFromSpec(&csr.Spec)
csr.Spec.SignerName = &signerName
}
return cc.handler(csr) return cc.handler(csr)
} }

View File

@ -21,7 +21,7 @@ import (
"testing" "testing"
"time" "time"
certificates "k8s.io/api/certificates/v1beta1" certificates "k8s.io/api/certificates/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
@ -48,7 +48,7 @@ func TestCertificateController(t *testing.T) {
Reason: "test reason", Reason: "test reason",
Message: "test message", Message: "test message",
}) })
_, err := client.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{}) _, err := client.CertificatesV1().CertificateSigningRequests().UpdateApproval(context.TODO(), csr.Name, csr, metav1.UpdateOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -58,7 +58,7 @@ func TestCertificateController(t *testing.T) {
controller := NewCertificateController( controller := NewCertificateController(
"test", "test",
client, client,
informerFactory.Certificates().V1beta1().CertificateSigningRequests(), informerFactory.Certificates().V1().CertificateSigningRequests(),
handler, handler,
) )
controller.csrsSynced = func() bool { return true } controller.csrsSynced = func() bool { return true }

View File

@ -17,7 +17,7 @@ limitations under the License.
package certificates package certificates
import ( import (
certificates "k8s.io/api/certificates/v1beta1" certificates "k8s.io/api/certificates/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
) )

View File

@ -21,14 +21,14 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/certificates/v1beta1" certificatesapi "k8s.io/api/certificates/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func TestIsCertificateRequestApproved(t *testing.T) { func TestIsCertificateRequestApproved(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
conditions []v1beta1.CertificateSigningRequestCondition conditions []certificatesapi.CertificateSigningRequestCondition
expectedIsApproved bool expectedIsApproved bool
}{ }{
{ {
@ -37,28 +37,28 @@ func TestIsCertificateRequestApproved(t *testing.T) {
false, false,
}, { }, {
"Approved not exist and Denied exist", "Approved not exist and Denied exist",
[]v1beta1.CertificateSigningRequestCondition{ []certificatesapi.CertificateSigningRequestCondition{
{ {
Type: v1beta1.CertificateDenied, Type: certificatesapi.CertificateDenied,
}, },
}, },
false, false,
}, { }, {
"Approved exist and Denied not exist", "Approved exist and Denied not exist",
[]v1beta1.CertificateSigningRequestCondition{ []certificatesapi.CertificateSigningRequestCondition{
{ {
Type: v1beta1.CertificateApproved, Type: certificatesapi.CertificateApproved,
}, },
}, },
true, true,
}, { }, {
"Both of Approved and Denied exist", "Both of Approved and Denied exist",
[]v1beta1.CertificateSigningRequestCondition{ []certificatesapi.CertificateSigningRequestCondition{
{ {
Type: v1beta1.CertificateApproved, Type: certificatesapi.CertificateApproved,
}, },
{ {
Type: v1beta1.CertificateDenied, Type: certificatesapi.CertificateDenied,
}, },
}, },
false, false,
@ -66,11 +66,11 @@ func TestIsCertificateRequestApproved(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
csr := &v1beta1.CertificateSigningRequest{ csr := &certificatesapi.CertificateSigningRequest{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: "fake-csr", Name: "fake-csr",
}, },
Status: v1beta1.CertificateSigningRequestStatus{ Status: certificatesapi.CertificateSigningRequestStatus{
Conditions: tc.conditions, Conditions: tc.conditions,
}, },
} }

View File

@ -6,14 +6,14 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/controller/certificates/cleaner", importpath = "k8s.io/kubernetes/pkg/controller/certificates/cleaner",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/client-go/informers/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/informers/certificates/v1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/certificates/v1:go_default_library",
"//staging/src/k8s.io/client-go/listers/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/listers/certificates/v1:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
], ],
) )
@ -37,7 +37,7 @@ go_test(
srcs = ["cleaner_test.go"], srcs = ["cleaner_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
], ],

View File

@ -29,14 +29,14 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1" certificatesinformers "k8s.io/client-go/informers/certificates/v1"
csrclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" csrclient "k8s.io/client-go/kubernetes/typed/certificates/v1"
certificateslisters "k8s.io/client-go/listers/certificates/v1beta1" certificateslisters "k8s.io/client-go/listers/certificates/v1"
) )
const ( const (

View File

@ -20,7 +20,7 @@ import (
"testing" "testing"
"time" "time"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
) )
@ -211,7 +211,7 @@ func TestCleanerWithApprovedExpiredCSR(t *testing.T) {
client := fake.NewSimpleClientset(csr) client := fake.NewSimpleClientset(csr)
s := &CSRCleanerController{ s := &CSRCleanerController{
csrClient: client.CertificatesV1beta1().CertificateSigningRequests(), csrClient: client.CertificatesV1().CertificateSigningRequests(),
} }
err := s.handle(csr) err := s.handle(csr)

View File

@ -16,9 +16,9 @@ go_test(
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/certificates/v1beta1:go_default_library", "//pkg/apis/certificates/v1:go_default_library",
"//pkg/controller/certificates:go_default_library", "//pkg/controller/certificates:go_default_library",
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
@ -36,14 +36,16 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/pkg/controller/certificates/signer", importpath = "k8s.io/kubernetes/pkg/controller/certificates/signer",
deps = [ deps = [
"//pkg/apis/certificates/v1beta1:go_default_library", "//pkg/apis/certificates:go_default_library",
"//pkg/controller/certificates:go_default_library", "//pkg/controller/certificates:go_default_library",
"//pkg/controller/certificates/authority:go_default_library", "//pkg/controller/certificates/authority:go_default_library",
"//staging/src/k8s.io/api/certificates/v1:go_default_library",
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library",
"//staging/src/k8s.io/client-go/informers/certificates/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/informers/certificates/v1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/util/cert:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library",
"//staging/src/k8s.io/client-go/util/keyutil:go_default_library", "//staging/src/k8s.io/client-go/util/keyutil:go_default_library",

View File

@ -24,13 +24,15 @@ import (
"fmt" "fmt"
"time" "time"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
capiv1beta1 "k8s.io/api/certificates/v1beta1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/server/dynamiccertificates" "k8s.io/apiserver/pkg/server/dynamiccertificates"
certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1" certificatesinformers "k8s.io/client-go/informers/certificates/v1"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" capihelper "k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/controller/certificates" "k8s.io/kubernetes/pkg/controller/certificates"
"k8s.io/kubernetes/pkg/controller/certificates/authority" "k8s.io/kubernetes/pkg/controller/certificates/authority"
) )
@ -73,7 +75,7 @@ func NewLegacyUnknownCSRSigningController(
caFile, caKeyFile string, caFile, caKeyFile string,
certTTL time.Duration, certTTL time.Duration,
) (*CSRSigningController, error) { ) (*CSRSigningController, error) {
return NewCSRSigningController("csrsigning-legacy-unknown", capi.LegacyUnknownSignerName, client, csrInformer, caFile, caKeyFile, certTTL) return NewCSRSigningController("csrsigning-legacy-unknown", capiv1beta1.LegacyUnknownSignerName, client, csrInformer, caFile, caKeyFile, certTTL)
} }
func NewCSRSigningController( func NewCSRSigningController(
@ -146,7 +148,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
} }
// Fast-path to avoid any additional processing if the CSRs signerName does not match // Fast-path to avoid any additional processing if the CSRs signerName does not match
if *csr.Spec.SignerName != s.signerName { if csr.Spec.SignerName != s.signerName {
return nil return nil
} }
@ -154,7 +156,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
if err != nil { if err != nil {
return fmt.Errorf("unable to parse csr %q: %v", csr.Name, err) return fmt.Errorf("unable to parse csr %q: %v", csr.Name, err)
} }
if recognized, err := s.isRequestForSignerFn(x509cr, csr.Spec.Usages, *csr.Spec.SignerName); err != nil { if recognized, err := s.isRequestForSignerFn(x509cr, csr.Spec.Usages, csr.Spec.SignerName); err != nil {
csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{ csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{
Type: capi.CertificateFailed, Type: capi.CertificateFailed,
Status: v1.ConditionTrue, Status: v1.ConditionTrue,
@ -162,7 +164,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
Message: err.Error(), Message: err.Error(),
LastUpdateTime: metav1.Now(), LastUpdateTime: metav1.Now(),
}) })
_, err = s.client.CertificatesV1beta1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{}) _, err = s.client.CertificatesV1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{})
if err != nil { if err != nil {
return fmt.Errorf("error adding failure condition for csr: %v", err) return fmt.Errorf("error adding failure condition for csr: %v", err)
} }
@ -176,7 +178,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
return fmt.Errorf("error auto signing csr: %v", err) return fmt.Errorf("error auto signing csr: %v", err)
} }
csr.Status.Certificate = cert csr.Status.Certificate = cert
_, err = s.client.CertificatesV1beta1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{}) _, err = s.client.CertificatesV1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{})
if err != nil { if err != nil {
return fmt.Errorf("error updating signature for csr: %v", err) return fmt.Errorf("error updating signature for csr: %v", err)
} }
@ -208,7 +210,7 @@ func getCSRVerificationFuncForSignerName(signerName string) (isRequestForSignerF
return isKubeletClient, nil return isKubeletClient, nil
case capi.KubeAPIServerClientSignerName: case capi.KubeAPIServerClientSignerName:
return isKubeAPIServerClient, nil return isKubeAPIServerClient, nil
case capi.LegacyUnknownSignerName: case capiv1beta1.LegacyUnknownSignerName:
return isLegacyUnknown, nil return isLegacyUnknown, nil
default: default:
// TODO type this error so that a different reporting loop (one without a signing cert), can mark // TODO type this error so that a different reporting loop (one without a signing cert), can mark
@ -222,14 +224,14 @@ func isKubeletServing(req *x509.CertificateRequest, usages []capi.KeyUsage, sign
if signerName != capi.KubeletServingSignerName { if signerName != capi.KubeletServingSignerName {
return false, nil return false, nil
} }
return true, capihelper.ValidateKubeletServingCSR(req, usages) return true, capihelper.ValidateKubeletServingCSR(req, usagesToSet(usages))
} }
func isKubeletClient(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) { func isKubeletClient(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) {
if signerName != capi.KubeAPIServerClientKubeletSignerName { if signerName != capi.KubeAPIServerClientKubeletSignerName {
return false, nil return false, nil
} }
return true, capihelper.ValidateKubeletClientCSR(req, usages) return true, capihelper.ValidateKubeletClientCSR(req, usagesToSet(usages))
} }
func isKubeAPIServerClient(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) { func isKubeAPIServerClient(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) {
@ -240,11 +242,11 @@ func isKubeAPIServerClient(req *x509.CertificateRequest, usages []capi.KeyUsage,
} }
func isLegacyUnknown(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) { func isLegacyUnknown(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) {
if signerName != capi.LegacyUnknownSignerName { if signerName != capiv1beta1.LegacyUnknownSignerName {
return false, nil return false, nil
} }
// No restrictions are applied to the legacy-unknown signerName to // No restrictions are applied to the legacy-unknown signerName to
// maintain backward compatibility in v1beta1. // maintain backward compatibility in v1.
return true, nil return true, nil
} }
@ -265,3 +267,11 @@ func validAPIServerClientUsages(usages []capi.KeyUsage) error {
} }
return nil return nil
} }
func usagesToSet(usages []capi.KeyUsage) sets.String {
result := sets.NewString()
for _, usage := range usages {
result.Insert(string(usage))
}
return result
}

View File

@ -29,7 +29,7 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
capi "k8s.io/api/certificates/v1beta1" capi "k8s.io/api/certificates/v1"
"k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/clock"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
@ -37,13 +37,13 @@ import (
"k8s.io/client-go/util/cert" "k8s.io/client-go/util/cert"
"k8s.io/kubernetes/pkg/controller/certificates" "k8s.io/kubernetes/pkg/controller/certificates"
capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1"
) )
func TestSigner(t *testing.T) { func TestSigner(t *testing.T) {
clock := clock.FakeClock{} clock := clock.FakeClock{}
s, err := newSigner(capi.LegacyUnknownSignerName, "./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour) s, err := newSigner("kubernetes.io/legacy-unknown", "./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour)
if err != nil { if err != nil {
t.Fatalf("failed to create signer: %v", err) t.Fatalf("failed to create signer: %v", err)
} }
@ -337,7 +337,7 @@ func makeTestCSR(b csrBuilder) *capi.CertificateSigningRequest {
}, },
} }
if b.signerName != "" { if b.signerName != "" {
csr.Spec.SignerName = &b.signerName csr.Spec.SignerName = b.signerName
} }
if b.approved { if b.approved {
csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{ csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{

View File

@ -75,7 +75,7 @@ func (p *Plugin) Validate(_ context.Context, a admission.Attributes, _ admission
return nil return nil
} }
csrParsed, err := certificatesapi.ParseCSR(csr) csrParsed, err := certificatesapi.ParseCSR(csr.Spec.Request)
if err != nil { if err != nil {
return admission.NewForbidden(a, fmt.Errorf("failed to parse CSR: %v", err)) return admission.NewForbidden(a, fmt.Errorf("failed to parse CSR: %v", err))
} }

View File

@ -10,6 +10,7 @@ rules:
- k8s.io/kubernetes/pkg/apis/apps/validation - k8s.io/kubernetes/pkg/apis/apps/validation
- k8s.io/kubernetes/pkg/apis/autoscaling - k8s.io/kubernetes/pkg/apis/autoscaling
- k8s.io/kubernetes/pkg/apis/batch - k8s.io/kubernetes/pkg/apis/batch
- k8s.io/kubernetes/pkg/apis/certificates
- k8s.io/kubernetes/pkg/apis/core - k8s.io/kubernetes/pkg/apis/core
- k8s.io/kubernetes/pkg/apis/core/helper - k8s.io/kubernetes/pkg/apis/core/helper
- k8s.io/kubernetes/pkg/apis/core/install - k8s.io/kubernetes/pkg/apis/core/install

View File

@ -101,7 +101,7 @@ func TestController_AutoApproval(t *testing.T) {
informers := informers.NewSharedInformerFactory(clientset.NewForConfigOrDie(restclient.AddUserAgent(s.ClientConfig, "certificatesigningrequest-informers")), time.Second) informers := informers.NewSharedInformerFactory(clientset.NewForConfigOrDie(restclient.AddUserAgent(s.ClientConfig, "certificatesigningrequest-informers")), time.Second)
// Register the controller // Register the controller
c := approver.NewCSRApprovingController(client, informers.Certificates().V1beta1().CertificateSigningRequests()) c := approver.NewCSRApprovingController(client, informers.Certificates().V1().CertificateSigningRequests())
// Start the controller & informers // Start the controller & informers
stopCh := make(chan struct{}) stopCh := make(chan struct{})
defer close(stopCh) defer close(stopCh)
@ -159,7 +159,7 @@ const (
func waitForCertificateRequestApproved(client kubernetes.Interface, name string) error { func waitForCertificateRequestApproved(client kubernetes.Interface, name string) error {
if err := wait.Poll(interval, timeout, func() (bool, error) { if err := wait.Poll(interval, timeout, func() (bool, error) {
csr, err := client.CertificatesV1beta1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{}) csr, err := client.CertificatesV1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil { if err != nil {
return false, err return false, err
} }