func TestController_AutoApproval(t *testing.T) {
	validKubeAPIServerClientKubeletUsername := "system:node:abc"
	validKubeAPIServerClientKubeletCSR := pemWithTemplate(&x509.CertificateRequest{
		Subject: pkix.Name{
			CommonName:   validKubeAPIServerClientKubeletUsername,
			Organization: []string{"system:nodes"},
		},
	})
	validKubeAPIServerClientKubeletUsages := []certv1beta1.KeyUsage{
		certv1beta1.UsageDigitalSignature,
		certv1beta1.UsageKeyEncipherment,
		certv1beta1.UsageClientAuth,
	}
	tests := map[string]struct {
		signerName          string
		request             []byte
		usages              []certv1beta1.KeyUsage
		username            string
		autoApproved        bool
		grantNodeClient     bool
		grantSelfNodeClient bool
	}{
		"should auto-approve CSR that has kube-apiserver-client-kubelet signerName and matches requirements": {
			signerName:          certv1beta1.KubeAPIServerClientKubeletSignerName,
			request:             validKubeAPIServerClientKubeletCSR,
			usages:              validKubeAPIServerClientKubeletUsages,
			username:            validKubeAPIServerClientKubeletUsername,
			grantSelfNodeClient: true,
			autoApproved:        true,
		},
		"should auto-approve CSR that has kube-apiserver-client-kubelet signerName and matches requirements despite missing username if nodeclient permissions are granted": {
			signerName:      certv1beta1.KubeAPIServerClientKubeletSignerName,
			request:         validKubeAPIServerClientKubeletCSR,
			usages:          validKubeAPIServerClientKubeletUsages,
			username:        "does-not-match-cn",
			grantNodeClient: true,
			autoApproved:    true,
		},
		"should not auto-approve CSR that has kube-apiserver-client-kubelet signerName that does not match requirements": {
			signerName:   certv1beta1.KubeAPIServerClientKubeletSignerName,
			request:      pemWithGroup("system:notnodes"),
			autoApproved: false,
		},
		"should not auto-approve CSR that has kube-apiserver-client signerName that DOES match kubelet CSR requirements": {
			signerName:   certv1beta1.KubeAPIServerClientSignerName,
			request:      validKubeAPIServerClientKubeletCSR,
			usages:       validKubeAPIServerClientKubeletUsages,
			username:     validKubeAPIServerClientKubeletUsername,
			autoApproved: false,
		},
	}
	for name, test := range tests {
		t.Run(name, func(t *testing.T) {
			// Run an apiserver with the default configuration options.
			s := kubeapiservertesting.StartTestServerOrDie(t, kubeapiservertesting.NewDefaultTestServerOptions(), []string{""}, framework.SharedEtcd())
			defer s.TearDownFn()
			client := clientset.NewForConfigOrDie(s.ClientConfig)
			informers := informers.NewSharedInformerFactory(clientset.NewForConfigOrDie(restclient.AddUserAgent(s.ClientConfig, "certificatesigningrequest-informers")), time.Second)

			// Register the controller
			c := approver.NewCSRApprovingController(client, informers.Certificates().V1().CertificateSigningRequests())
			// Start the controller & informers
			stopCh := make(chan struct{})
			defer close(stopCh)
			informers.Start(stopCh)
			go c.Run(1, stopCh)

			// Configure appropriate permissions
			if test.grantNodeClient {
				grantUserNodeClientPermissions(t, client, test.username, false)
			}
			if test.grantSelfNodeClient {
				grantUserNodeClientPermissions(t, client, test.username, true)
			}

			// Use a client that impersonates the test case 'username' to ensure the `spec.username`
			// field on the CSR is set correctly.
			impersonationConfig := restclient.CopyConfig(s.ClientConfig)
			impersonationConfig.Impersonate.UserName = test.username
			impersonationClient, err := clientset.NewForConfig(impersonationConfig)
			if err != nil {
				t.Fatalf("Error in create clientset: %v", err)
			}
			csr := &certv1beta1.CertificateSigningRequest{
				ObjectMeta: metav1.ObjectMeta{
					Name: "csr",
				},
				Spec: certv1beta1.CertificateSigningRequestSpec{
					Request:    test.request,
					Usages:     test.usages,
					SignerName: &test.signerName,
				},
			}
			_, err = impersonationClient.CertificatesV1beta1().CertificateSigningRequests().Create(context.TODO(), csr, metav1.CreateOptions{})
			if err != nil {
				t.Fatalf("failed to create testing CSR: %v", err)
			}

			if test.autoApproved {
				if err := waitForCertificateRequestApproved(client, csr.Name); err != nil {
					t.Errorf("failed to wait for CSR to be auto-approved: %v", err)
				}
			} else {
				if err := ensureCertificateRequestNotApproved(client, csr.Name); err != nil {
					t.Errorf("failed to ensure that CSR was not auto-approved: %v", err)
				}
			}
		})
	}
}
// Integration tests that verify the behaviour of the CSR auto-approving controller.
Integration tests that verify the behaviour of the CSR auto-approving controller.
// Integration tests that verify the behaviour of the CSR auto - approving controller .
func TestController_AutoApproval(t *testing.T) {
	validKubeAPIServerClientKubeletUsername := "system:node:abc"
	validKubeAPIServerClientKubeletCSR := pemWithTemplate(&x509.CertificateRequest{
		Subject: pkix.Name{
			CommonName:   validKubeAPIServerClientKubeletUsername,
			Organization: []string{"system:nodes"},
		},
	})
	validKubeAPIServerClientKubeletUsages := []certv1beta1.KeyUsage{
		certv1beta1.UsageDigitalSignature,
		certv1beta1.UsageKeyEncipherment,
		certv1beta1.UsageClientAuth,
	}
	tests := map[string]struct {
		signerName          string
		request             []byte
		usages              []certv1beta1.KeyUsage
		username            string
		autoApproved        bool
		grantNodeClient     bool
		grantSelfNodeClient bool
	}{
		"should auto-approve CSR that has kube-apiserver-client-kubelet signerName and matches requirements": {
			signerName:          certv1beta1.KubeAPIServerClientKubeletSignerName,
			request:             validKubeAPIServerClientKubeletCSR,
			usages:              validKubeAPIServerClientKubeletUsages,
			username:            validKubeAPIServerClientKubeletUsername,
			grantSelfNodeClient: true,
			autoApproved:        true,
		},
		"should auto-approve CSR that has kube-apiserver-client-kubelet signerName and matches requirements despite missing username if nodeclient permissions are granted": {
			signerName:      certv1beta1.KubeAPIServerClientKubeletSignerName,
			request:         validKubeAPIServerClientKubeletCSR,
			usages:          validKubeAPIServerClientKubeletUsages,
			username:        "does-not-match-cn",
			grantNodeClient: true,
			autoApproved:    true,
		},
		"should not auto-approve CSR that has kube-apiserver-client-kubelet signerName that does not match requirements": {
			signerName:   certv1beta1.KubeAPIServerClientKubeletSignerName,
			request:      pemWithGroup("system:notnodes"),
			autoApproved: false,
		},
		"should not auto-approve CSR that has kube-apiserver-client signerName that DOES match kubelet CSR requirements": {
			signerName:   certv1beta1.KubeAPIServerClientSignerName,
			request:      validKubeAPIServerClientKubeletCSR,
			usages:       validKubeAPIServerClientKubeletUsages,
			username:     validKubeAPIServerClientKubeletUsername,
			autoApproved: false,
		},
	}
	for name, test := range tests {
		t.Run(name, func(t *testing.T) {
			s := kubeapiservertesting.StartTestServerOrDie(t, kubeapiservertesting.NewDefaultTestServerOptions(), []string{""}, framework.SharedEtcd())
			defer s.TearDownFn()
			client := clientset.NewForConfigOrDie(s.ClientConfig)
			informers := informers.NewSharedInformerFactory(clientset.NewForConfigOrDie(restclient.AddUserAgent(s.ClientConfig, "certificatesigningrequest-informers")), time.Second)
			c := approver.NewCSRApprovingController(client, informers.Certificates().V1().CertificateSigningRequests())
			stopCh := make(chan struct{})
			defer close(stopCh)
			informers.Start(stopCh)
			go c.Run(1, stopCh)
			if test.grantNodeClient {
				grantUserNodeClientPermissions(t, client, test.username, false)
			}
			if test.grantSelfNodeClient {
				grantUserNodeClientPermissions(t, client, test.username, true)
			}
			impersonationConfig := restclient.CopyConfig(s.ClientConfig)
			impersonationConfig.Impersonate.UserName = test.username
			impersonationClient, err := clientset.NewForConfig(impersonationConfig)
			if err != nil {
				t.Fatalf("Error in create clientset: %v", err)
			}
			csr := &certv1beta1.CertificateSigningRequest{
				ObjectMeta: metav1.ObjectMeta{
					Name: "csr",
				},
				Spec: certv1beta1.CertificateSigningRequestSpec{
					Request:    test.request,
					Usages:     test.usages,
					SignerName: &test.signerName,
				},
			}
			_, err = impersonationClient.CertificatesV1beta1().CertificateSigningRequests().Create(context.TODO(), csr, metav1.CreateOptions{})
			if err != nil {
				t.Fatalf("failed to create testing CSR: %v", err)
			}
			if test.autoApproved {
				if err := waitForCertificateRequestApproved(client, csr.Name); err != nil {
					t.Errorf("failed to wait for CSR to be auto-approved: %v", err)
				}
			} else {
				if err := ensureCertificateRequestNotApproved(client, csr.Name); err != nil {
					t.Errorf("failed to ensure that CSR was not auto-approved: %v", err)
				}
			}
		})
	}
}
func TestController_AutoApproval ( t * testing . T ) { validKubeAPIServerClientKubeletUsername := " " validKubeAPIServerClientKubeletCSR := pemWithTemplate ( & x509 . CertificateRequest { Subject : pkix . Name { CommonName : validKubeAPIServerClientKubeletUsername , Organization : [ ] string { " " } , } , } ) validKubeAPIServerClientKubeletUsages := [ ] certv1beta1 . KeyUsage { certv1beta1 . UsageDigitalSignature , certv1beta1 . UsageKeyEncipherment , certv1beta1 . UsageClientAuth , } tests := map [ string ] struct { signerName string request [ ] byte usages [ ] certv1beta1 . KeyUsage username string autoApproved bool grantNodeClient bool grantSelfNodeClient bool } { " " : { signerName : certv1beta1 . KubeAPIServerClientKubeletSignerName , request : validKubeAPIServerClientKubeletCSR , usages : validKubeAPIServerClientKubeletUsages , username : validKubeAPIServerClientKubeletUsername , grantSelfNodeClient : true , autoApproved : true , } , " " : { signerName : certv1beta1 . KubeAPIServerClientKubeletSignerName , request : validKubeAPIServerClientKubeletCSR , usages : validKubeAPIServerClientKubeletUsages , username : " " , grantNodeClient : true , autoApproved : true , } , " " : { signerName : certv1beta1 . KubeAPIServerClientKubeletSignerName , request : pemWithGroup ( " " ) , autoApproved : false , } , " " : { signerName : certv1beta1 . KubeAPIServerClientSignerName , request : validKubeAPIServerClientKubeletCSR , usages : validKubeAPIServerClientKubeletUsages , username : validKubeAPIServerClientKubeletUsername , autoApproved : false , } , } for name , test := range tests { t . Run ( name , func ( t * testing . T ) { s := kubeapiservertesting . StartTestServerOrDie ( t , kubeapiservertesting . NewDefaultTestServerOptions ( ) , [ ] string { " " } , framework . SharedEtcd ( ) ) defer s . TearDownFn ( ) client := clientset . NewForConfigOrDie ( s . ClientConfig ) informers := informers . NewSharedInformerFactory ( clientset . NewForConfigOrDie ( restclient . AddUserAgent ( s . ClientConfig , " " ) ) , time . Second ) c := approver . NewCSRApprovingController ( client , informers . Certificates ( ) . V1 ( ) . CertificateSigningRequests ( ) ) stopCh := make ( chan struct { } ) defer close ( stopCh ) informers . Start ( stopCh ) go c . Run ( 1 , stopCh ) if test . grantNodeClient { grantUserNodeClientPermissions ( t , client , test . username , false ) } if test . grantSelfNodeClient { grantUserNodeClientPermissions ( t , client , test . username , true ) } impersonationConfig := restclient . CopyConfig ( s . ClientConfig ) impersonationConfig . Impersonate . UserName = test . username impersonationClient , err := clientset . NewForConfig ( impersonationConfig ) if err != nil { t . Fatalf ( " " , err ) } csr := & certv1beta1 . CertificateSigningRequest { ObjectMeta : metav1 . ObjectMeta { Name : " " , } , Spec : certv1beta1 . CertificateSigningRequestSpec { Request : test . request , Usages : test . usages , SignerName : & test . signerName , } , } _ , err = impersonationClient . CertificatesV1beta1 ( ) . CertificateSigningRequests ( ) . Create ( context . TODO ( ) , csr , metav1 . CreateOptions { } ) if err != nil { t . Fatalf ( " " , err ) } if test . autoApproved { if err := waitForCertificateRequestApproved ( client , csr . Name ) ; err != nil { t . Errorf ( " " , err ) } } else { if err := ensureCertificateRequestNotApproved ( client , csr . Name ) ; err != nil { t . Errorf ( " " , err ) } } } ) } }
Integration tests that verify the behaviour of the CSR auto-approving controller.
Integration tests that verify the behaviour of the CSR auto - approving controller .
// Run an apiserver with the default configuration options. // Register the controller // Start the controller & informers // Configure appropriate permissions // Use a client that impersonates the test case 'username' to ensure the `spec.username` // field on the CSR is set correctly.