mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #91713 from liggitt/csr-v1-manager
CSR v1 - switch controllers
This commit is contained in:
commit
11fe6e815f
@ -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
|
||||||
|
@ -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",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 }
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
],
|
],
|
||||||
|
@ -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 (
|
||||||
|
@ -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)
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user