mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Switch CSR approver/signer/cleaner controllers to v1
This commit is contained in:
		@@ -89,7 +89,7 @@ func startCSRSigningController(ctx ControllerContext) (http.Handler, bool, error
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c := ctx.ClientBuilder.ClientOrDie("certificate-controller")
 | 
			
		||||
	csrInformer := ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests()
 | 
			
		||||
	csrInformer := ctx.InformerFactory.Certificates().V1().CertificateSigningRequests()
 | 
			
		||||
	certTTL := ctx.ComponentConfig.CSRSigningController.ClusterSigningDuration.Duration
 | 
			
		||||
	caFile, caKeyFile := getKubeletServingSignerFiles(ctx.ComponentConfig.CSRSigningController)
 | 
			
		||||
 | 
			
		||||
@@ -137,7 +137,7 @@ func startCSRApprovingController(ctx ControllerContext) (http.Handler, bool, err
 | 
			
		||||
 | 
			
		||||
	approver := approver.NewCSRApprovingController(
 | 
			
		||||
		ctx.ClientBuilder.ClientOrDie("certificate-controller"),
 | 
			
		||||
		ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(),
 | 
			
		||||
		ctx.InformerFactory.Certificates().V1().CertificateSigningRequests(),
 | 
			
		||||
	)
 | 
			
		||||
	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) {
 | 
			
		||||
	cleaner := cleaner.NewCSRCleanerController(
 | 
			
		||||
		ctx.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1beta1().CertificateSigningRequests(),
 | 
			
		||||
		ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(),
 | 
			
		||||
		ctx.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1().CertificateSigningRequests(),
 | 
			
		||||
		ctx.InformerFactory.Certificates().V1().CertificateSigningRequests(),
 | 
			
		||||
	)
 | 
			
		||||
	go cleaner.Run(1, ctx.Stop)
 | 
			
		||||
	return nil, true, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ go_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/schema:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,12 +20,15 @@ import (
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"encoding/pem"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ParseCSR extracts the CSR from the API object and decodes it.
 | 
			
		||||
func ParseCSR(obj *CertificateSigningRequest) (*x509.CertificateRequest, error) {
 | 
			
		||||
	// extract PEM from request object
 | 
			
		||||
	pemBytes := obj.Spec.Request
 | 
			
		||||
// ParseCSR extracts the CSR from the bytes and decodes it.
 | 
			
		||||
func ParseCSR(pemBytes []byte) (*x509.CertificateRequest, error) {
 | 
			
		||||
	block, _ := pem.Decode(pemBytes)
 | 
			
		||||
	if block == nil || block.Type != "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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,14 +18,12 @@ package v1beta1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	v1 "k8s.io/api/core/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
	certificates "k8s.io/kubernetes/pkg/apis/certificates"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	return ValidateKubeletServingCSR(req, usages) == nil
 | 
			
		||||
	return certificates.IsKubeletServingCSR(req, usagesToSet(usages))
 | 
			
		||||
}
 | 
			
		||||
func ValidateKubeletServingCSR(req *x509.CertificateRequest, usages []certificatesv1beta1.KeyUsage) 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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	return certificates.ValidateKubeletServingCSR(req, usagesToSet(usages))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	if !reflect.DeepEqual([]string{"system:nodes"}, req.Subject.Organization) {
 | 
			
		||||
		return organizationNotSystemNodesErr
 | 
			
		||||
	return certificates.ValidateKubeletClientCSR(req, usagesToSet(usages))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	if len(req.DNSNames) > 0 {
 | 
			
		||||
		return dnsSANNotAllowedErr
 | 
			
		||||
func usagesToSet(usages []certificatesv1beta1.KeyUsage) sets.String {
 | 
			
		||||
	result := sets.NewString()
 | 
			
		||||
	for _, usage := range usages {
 | 
			
		||||
		result.Insert(string(usage))
 | 
			
		||||
	}
 | 
			
		||||
	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
 | 
			
		||||
// the order of the elements
 | 
			
		||||
func equalUnsorted(left, right []certificatesv1beta1.KeyUsage) bool {
 | 
			
		||||
	l := sets.NewString()
 | 
			
		||||
	for _, s := range left {
 | 
			
		||||
		l.Insert(string(s))
 | 
			
		||||
	}
 | 
			
		||||
	r := sets.NewString()
 | 
			
		||||
	for _, s := range right {
 | 
			
		||||
		r.Insert(string(s))
 | 
			
		||||
	}
 | 
			
		||||
	return l.Equal(r)
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,7 @@ type certificateValidationOptions struct {
 | 
			
		||||
// PEM-encoded PKCS#10 certificate signing request. If this is invalid, we must
 | 
			
		||||
// not accept the CSR for further processing.
 | 
			
		||||
func validateCSR(obj *certificates.CertificateSigningRequest) error {
 | 
			
		||||
	csr, err := certificates.ParseCSR(obj)
 | 
			
		||||
	csr, err := certificates.ParseCSR(obj.Spec.Request)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,17 +13,16 @@ go_library(
 | 
			
		||||
    importpath = "k8s.io/kubernetes/pkg/controller/certificates",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//pkg/apis/certificates/v1beta1: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/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/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/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/record:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
 | 
			
		||||
@@ -64,7 +63,7 @@ go_test(
 | 
			
		||||
    embed = [":go_default_library"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//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/util/wait:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/informers:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,9 @@ go_test(
 | 
			
		||||
    srcs = ["sarapprove_test.go"],
 | 
			
		||||
    embed = [":go_default_library"],
 | 
			
		||||
    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/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/schema:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
 | 
			
		||||
@@ -26,12 +26,14 @@ go_library(
 | 
			
		||||
    srcs = ["sarapprove.go"],
 | 
			
		||||
    importpath = "k8s.io/kubernetes/pkg/controller/certificates/approver",
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//pkg/apis/certificates/v1beta1:go_default_library",
 | 
			
		||||
        "//pkg/apis/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/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/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",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -23,12 +23,14 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	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"
 | 
			
		||||
	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"
 | 
			
		||||
 | 
			
		||||
	capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1"
 | 
			
		||||
	capihelper "k8s.io/kubernetes/pkg/apis/certificates"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/certificates"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -100,7 +102,7 @@ func (a *sarApprover) handle(csr *capi.CertificateSigningRequest) error {
 | 
			
		||||
		}
 | 
			
		||||
		if approved {
 | 
			
		||||
			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 {
 | 
			
		||||
				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) {
 | 
			
		||||
	csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{
 | 
			
		||||
		Type:    capi.CertificateApproved,
 | 
			
		||||
		Status:  corev1.ConditionTrue,
 | 
			
		||||
		Reason:  "AutoApproved",
 | 
			
		||||
		Message: message,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool {
 | 
			
		||||
	isClientCSR := capihelper.IsKubeletClientCSR(x509cr, csr.Spec.Usages)
 | 
			
		||||
	if !isClientCSR {
 | 
			
		||||
	if csr.Spec.SignerName != capi.KubeAPIServerClientKubeletSignerName {
 | 
			
		||||
		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 {
 | 
			
		||||
	if !isNodeClientCert(csr, x509cr) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if csr.Spec.Username != x509cr.Subject.CommonName {
 | 
			
		||||
		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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,12 +28,12 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	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/schema"
 | 
			
		||||
	"k8s.io/client-go/kubernetes/fake"
 | 
			
		||||
	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) {
 | 
			
		||||
@@ -86,7 +86,7 @@ func TestHandle(t *testing.T) {
 | 
			
		||||
				if got, expected := a.Verb, "update"; 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)
 | 
			
		||||
				}
 | 
			
		||||
				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)
 | 
			
		||||
		t.Run(fmt.Sprintf("csr:%#v", b), func(t *testing.T) {
 | 
			
		||||
			csr := makeFancyTestCsr(b)
 | 
			
		||||
			x509cr, err := k8s_certificates_v1beta1.ParseCSR(csr.Spec.Request)
 | 
			
		||||
			x509cr, err := k8s_certificates_v1.ParseCSR(csr.Spec.Request)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Errorf("unexpected err: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
@@ -252,7 +252,7 @@ func makeFancyTestCsr(b csrBuilder) *capi.CertificateSigningRequest {
 | 
			
		||||
		Spec: capi.CertificateSigningRequestSpec{
 | 
			
		||||
			Username:   b.requestor,
 | 
			
		||||
			Usages:     b.usages,
 | 
			
		||||
			SignerName: &b.signerName,
 | 
			
		||||
			SignerName: b.signerName,
 | 
			
		||||
			Request:    pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrb}),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ go_library(
 | 
			
		||||
        "//cmd/kubelet/app:__pkg__",
 | 
			
		||||
        "//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(
 | 
			
		||||
@@ -39,7 +39,7 @@ go_test(
 | 
			
		||||
    ],
 | 
			
		||||
    embed = [":go_default_library"],
 | 
			
		||||
    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",
 | 
			
		||||
        "//vendor/github.com/google/go-cmp/cmp:go_default_library",
 | 
			
		||||
        "//vendor/github.com/google/go-cmp/cmp/cmpopts:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ import (
 | 
			
		||||
	"github.com/google/go-cmp/cmp"
 | 
			
		||||
	"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"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	capi "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	capi "k8s.io/api/certificates/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SigningPolicy validates a CertificateRequest before it's signed by the
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	capi "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	capi "k8s.io/api/certificates/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestKeyUsagesFromStrings(t *testing.T) {
 | 
			
		||||
 
 | 
			
		||||
@@ -24,19 +24,18 @@ import (
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/time/rate"
 | 
			
		||||
 | 
			
		||||
	certificates "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	certificates "k8s.io/api/certificates/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/api/errors"
 | 
			
		||||
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
			
		||||
	"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"
 | 
			
		||||
	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/record"
 | 
			
		||||
	"k8s.io/client-go/util/workqueue"
 | 
			
		||||
	"k8s.io/klog/v2"
 | 
			
		||||
	capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1"
 | 
			
		||||
	"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
 | 
			
		||||
	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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	certificates "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	certificates "k8s.io/api/certificates/v1"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
			
		||||
	"k8s.io/client-go/informers"
 | 
			
		||||
@@ -48,7 +48,7 @@ func TestCertificateController(t *testing.T) {
 | 
			
		||||
			Reason:  "test reason",
 | 
			
		||||
			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 {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
@@ -58,7 +58,7 @@ func TestCertificateController(t *testing.T) {
 | 
			
		||||
	controller := NewCertificateController(
 | 
			
		||||
		"test",
 | 
			
		||||
		client,
 | 
			
		||||
		informerFactory.Certificates().V1beta1().CertificateSigningRequests(),
 | 
			
		||||
		informerFactory.Certificates().V1().CertificateSigningRequests(),
 | 
			
		||||
		handler,
 | 
			
		||||
	)
 | 
			
		||||
	controller.csrsSynced = func() bool { return true }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ limitations under the License.
 | 
			
		||||
package certificates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	certificates "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	certificates "k8s.io/api/certificates/v1"
 | 
			
		||||
	v1 "k8s.io/api/core/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,14 +21,14 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	certificatesapi "k8s.io/api/certificates/v1"
 | 
			
		||||
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestIsCertificateRequestApproved(t *testing.T) {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name               string
 | 
			
		||||
		conditions         []v1beta1.CertificateSigningRequestCondition
 | 
			
		||||
		conditions         []certificatesapi.CertificateSigningRequestCondition
 | 
			
		||||
		expectedIsApproved bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
@@ -37,28 +37,28 @@ func TestIsCertificateRequestApproved(t *testing.T) {
 | 
			
		||||
			false,
 | 
			
		||||
		}, {
 | 
			
		||||
			"Approved not exist and Denied exist",
 | 
			
		||||
			[]v1beta1.CertificateSigningRequestCondition{
 | 
			
		||||
			[]certificatesapi.CertificateSigningRequestCondition{
 | 
			
		||||
				{
 | 
			
		||||
					Type: v1beta1.CertificateDenied,
 | 
			
		||||
					Type: certificatesapi.CertificateDenied,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		}, {
 | 
			
		||||
			"Approved exist and Denied not exist",
 | 
			
		||||
			[]v1beta1.CertificateSigningRequestCondition{
 | 
			
		||||
			[]certificatesapi.CertificateSigningRequestCondition{
 | 
			
		||||
				{
 | 
			
		||||
					Type: v1beta1.CertificateApproved,
 | 
			
		||||
					Type: certificatesapi.CertificateApproved,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			true,
 | 
			
		||||
		}, {
 | 
			
		||||
			"Both of Approved and Denied exist",
 | 
			
		||||
			[]v1beta1.CertificateSigningRequestCondition{
 | 
			
		||||
			[]certificatesapi.CertificateSigningRequestCondition{
 | 
			
		||||
				{
 | 
			
		||||
					Type: v1beta1.CertificateApproved,
 | 
			
		||||
					Type: certificatesapi.CertificateApproved,
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Type: v1beta1.CertificateDenied,
 | 
			
		||||
					Type: certificatesapi.CertificateDenied,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
@@ -66,11 +66,11 @@ func TestIsCertificateRequestApproved(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		csr := &v1beta1.CertificateSigningRequest{
 | 
			
		||||
		csr := &certificatesapi.CertificateSigningRequest{
 | 
			
		||||
			ObjectMeta: v1.ObjectMeta{
 | 
			
		||||
				Name: "fake-csr",
 | 
			
		||||
			},
 | 
			
		||||
			Status: v1beta1.CertificateSigningRequestStatus{
 | 
			
		||||
			Status: certificatesapi.CertificateSigningRequestStatus{
 | 
			
		||||
				Conditions: tc.conditions,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,14 +6,14 @@ go_library(
 | 
			
		||||
    importpath = "k8s.io/kubernetes/pkg/controller/certificates/cleaner",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    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/labels: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/client-go/informers/certificates/v1beta1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/kubernetes/typed/certificates/v1beta1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/listers/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/v1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/listers/certificates/v1:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/klog/v2:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
@@ -37,7 +37,7 @@ go_test(
 | 
			
		||||
    srcs = ["cleaner_test.go"],
 | 
			
		||||
    embed = [":go_default_library"],
 | 
			
		||||
    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/client-go/kubernetes/fake:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -29,14 +29,14 @@ import (
 | 
			
		||||
 | 
			
		||||
	"k8s.io/klog/v2"
 | 
			
		||||
 | 
			
		||||
	capi "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	capi "k8s.io/api/certificates/v1"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/labels"
 | 
			
		||||
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
			
		||||
	certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1"
 | 
			
		||||
	csrclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
 | 
			
		||||
	certificateslisters "k8s.io/client-go/listers/certificates/v1beta1"
 | 
			
		||||
	certificatesinformers "k8s.io/client-go/informers/certificates/v1"
 | 
			
		||||
	csrclient "k8s.io/client-go/kubernetes/typed/certificates/v1"
 | 
			
		||||
	certificateslisters "k8s.io/client-go/listers/certificates/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	capi "k8s.io/api/certificates/v1beta1"
 | 
			
		||||
	capi "k8s.io/api/certificates/v1"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/client-go/kubernetes/fake"
 | 
			
		||||
)
 | 
			
		||||
@@ -211,7 +211,7 @@ func TestCleanerWithApprovedExpiredCSR(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
			client := fake.NewSimpleClientset(csr)
 | 
			
		||||
			s := &CSRCleanerController{
 | 
			
		||||
				csrClient: client.CertificatesV1beta1().CertificateSigningRequests(),
 | 
			
		||||
				csrClient: client.CertificatesV1().CertificateSigningRequests(),
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			err := s.handle(csr)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,9 @@ go_test(
 | 
			
		||||
    ],
 | 
			
		||||
    embed = [":go_default_library"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//pkg/apis/certificates/v1beta1:go_default_library",
 | 
			
		||||
        "//pkg/apis/certificates/v1: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/diff: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",
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//pkg/apis/certificates/v1beta1:go_default_library",
 | 
			
		||||
        "//pkg/apis/certificates:go_default_library",
 | 
			
		||||
        "//pkg/controller/certificates: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/core/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/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/util/cert:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/util/keyutil:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -24,13 +24,15 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"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"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
	"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"
 | 
			
		||||
	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/authority"
 | 
			
		||||
)
 | 
			
		||||
@@ -73,7 +75,7 @@ func NewLegacyUnknownCSRSigningController(
 | 
			
		||||
	caFile, caKeyFile string,
 | 
			
		||||
	certTTL time.Duration,
 | 
			
		||||
) (*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(
 | 
			
		||||
@@ -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
 | 
			
		||||
	if *csr.Spec.SignerName != s.signerName {
 | 
			
		||||
	if csr.Spec.SignerName != s.signerName {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -154,7 +156,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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{
 | 
			
		||||
			Type:           capi.CertificateFailed,
 | 
			
		||||
			Status:         v1.ConditionTrue,
 | 
			
		||||
@@ -162,7 +164,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
 | 
			
		||||
			Message:        err.Error(),
 | 
			
		||||
			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 {
 | 
			
		||||
			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)
 | 
			
		||||
	}
 | 
			
		||||
	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 {
 | 
			
		||||
		return fmt.Errorf("error updating signature for csr: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -208,7 +210,7 @@ func getCSRVerificationFuncForSignerName(signerName string) (isRequestForSignerF
 | 
			
		||||
		return isKubeletClient, nil
 | 
			
		||||
	case capi.KubeAPIServerClientSignerName:
 | 
			
		||||
		return isKubeAPIServerClient, nil
 | 
			
		||||
	case capi.LegacyUnknownSignerName:
 | 
			
		||||
	case capiv1beta1.LegacyUnknownSignerName:
 | 
			
		||||
		return isLegacyUnknown, nil
 | 
			
		||||
	default:
 | 
			
		||||
		// 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 {
 | 
			
		||||
		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) {
 | 
			
		||||
	if signerName != capi.KubeAPIServerClientKubeletSignerName {
 | 
			
		||||
		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) {
 | 
			
		||||
@@ -240,11 +242,11 @@ func isKubeAPIServerClient(req *x509.CertificateRequest, usages []capi.KeyUsage,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isLegacyUnknown(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) {
 | 
			
		||||
	if signerName != capi.LegacyUnknownSignerName {
 | 
			
		||||
	if signerName != capiv1beta1.LegacyUnknownSignerName {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
	// No restrictions are applied to the legacy-unknown signerName to
 | 
			
		||||
	// maintain backward compatibility in v1beta1.
 | 
			
		||||
	// maintain backward compatibility in v1.
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -265,3 +267,11 @@ func validAPIServerClientUsages(usages []capi.KeyUsage) error {
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func usagesToSet(usages []capi.KeyUsage) sets.String {
 | 
			
		||||
	result := sets.NewString()
 | 
			
		||||
	for _, usage := range usages {
 | 
			
		||||
		result.Insert(string(usage))
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"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/diff"
 | 
			
		||||
	"k8s.io/client-go/kubernetes/fake"
 | 
			
		||||
@@ -37,13 +37,13 @@ import (
 | 
			
		||||
	"k8s.io/client-go/util/cert"
 | 
			
		||||
	"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) {
 | 
			
		||||
	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 {
 | 
			
		||||
		t.Fatalf("failed to create signer: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -337,7 +337,7 @@ func makeTestCSR(b csrBuilder) *capi.CertificateSigningRequest {
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	if b.signerName != "" {
 | 
			
		||||
		csr.Spec.SignerName = &b.signerName
 | 
			
		||||
		csr.Spec.SignerName = b.signerName
 | 
			
		||||
	}
 | 
			
		||||
	if b.approved {
 | 
			
		||||
		csr.Status.Conditions = append(csr.Status.Conditions, capi.CertificateSigningRequestCondition{
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ func (p *Plugin) Validate(_ context.Context, a admission.Attributes, _ admission
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	csrParsed, err := certificatesapi.ParseCSR(csr)
 | 
			
		||||
	csrParsed, err := certificatesapi.ParseCSR(csr.Spec.Request)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return admission.NewForbidden(a, fmt.Errorf("failed to parse CSR: %v", err))
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ rules:
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/apps/validation
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/autoscaling
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/batch
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/certificates
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/core
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/core/helper
 | 
			
		||||
      - k8s.io/kubernetes/pkg/apis/core/install
 | 
			
		||||
 
 | 
			
		||||
@@ -101,7 +101,7 @@ func TestController_AutoApproval(t *testing.T) {
 | 
			
		||||
			informers := informers.NewSharedInformerFactory(clientset.NewForConfigOrDie(restclient.AddUserAgent(s.ClientConfig, "certificatesigningrequest-informers")), time.Second)
 | 
			
		||||
 | 
			
		||||
			// Register the controller
 | 
			
		||||
			c := approver.NewCSRApprovingController(client, informers.Certificates().V1beta1().CertificateSigningRequests())
 | 
			
		||||
			c := approver.NewCSRApprovingController(client, informers.Certificates().V1().CertificateSigningRequests())
 | 
			
		||||
			// Start the controller & informers
 | 
			
		||||
			stopCh := make(chan struct{})
 | 
			
		||||
			defer close(stopCh)
 | 
			
		||||
@@ -159,7 +159,7 @@ const (
 | 
			
		||||
 | 
			
		||||
func waitForCertificateRequestApproved(client kubernetes.Interface, name string) 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 {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user