mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Add CertificateSigningRequest API coverage tests
This commit is contained in:
parent
56ad0cefbd
commit
0e2b13aed2
@ -20,13 +20,20 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
v1beta1client "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/util/cert"
|
"k8s.io/client-go/util/cert"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
"k8s.io/kubernetes/test/utils"
|
"k8s.io/kubernetes/test/utils"
|
||||||
@ -37,9 +44,18 @@ import (
|
|||||||
var _ = SIGDescribe("Certificates API", func() {
|
var _ = SIGDescribe("Certificates API", func() {
|
||||||
f := framework.NewDefaultFramework("certificates")
|
f := framework.NewDefaultFramework("certificates")
|
||||||
|
|
||||||
|
/*
|
||||||
|
Release: v1.19
|
||||||
|
Testname: CertificateSigningRequest API Client Certificate
|
||||||
|
Description:
|
||||||
|
- The certificatesigningrequests resource must accept a request for a certificate signed by kubernetes.io/kube-apiserver-client.
|
||||||
|
- The issued certificate must be valid as a client certificate used to authenticate to the kube-apiserver.
|
||||||
|
*/
|
||||||
ginkgo.It("should support building a client with a CSR", func() {
|
ginkgo.It("should support building a client with a CSR", func() {
|
||||||
const commonName = "tester-csr"
|
const commonName = "tester-csr"
|
||||||
|
|
||||||
|
csrClient := f.ClientSet.CertificatesV1beta1().CertificateSigningRequests()
|
||||||
|
|
||||||
pk, err := utils.NewPrivateKey()
|
pk, err := utils.NewPrivateKey()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
@ -49,29 +65,59 @@ var _ = SIGDescribe("Certificates API", func() {
|
|||||||
Bytes: pkder,
|
Bytes: pkder,
|
||||||
})
|
})
|
||||||
|
|
||||||
csrb, err := cert.MakeCSR(pk, &pkix.Name{CommonName: commonName, Organization: []string{"system:masters"}}, nil, nil)
|
csrb, err := cert.MakeCSR(pk, &pkix.Name{CommonName: commonName}, nil, nil)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
csr := &certificatesv1beta1.CertificateSigningRequest{
|
apiserverClientSigner := certificatesv1beta1.KubeAPIServerClientSignerName
|
||||||
|
csrTemplate := &certificatesv1beta1.CertificateSigningRequest{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
GenerateName: commonName + "-",
|
GenerateName: commonName + "-",
|
||||||
},
|
},
|
||||||
Spec: certificatesv1beta1.CertificateSigningRequestSpec{
|
Spec: certificatesv1beta1.CertificateSigningRequestSpec{
|
||||||
Request: csrb,
|
Request: csrb,
|
||||||
Usages: []certificatesv1beta1.KeyUsage{
|
Usages: []certificatesv1beta1.KeyUsage{
|
||||||
certificatesv1beta1.UsageSigning,
|
certificatesv1beta1.UsageDigitalSignature,
|
||||||
certificatesv1beta1.UsageKeyEncipherment,
|
certificatesv1beta1.UsageKeyEncipherment,
|
||||||
certificatesv1beta1.UsageClientAuth,
|
certificatesv1beta1.UsageClientAuth,
|
||||||
},
|
},
|
||||||
|
SignerName: &apiserverClientSigner,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
csrs := f.ClientSet.CertificatesV1beta1().CertificateSigningRequests()
|
|
||||||
|
// Grant permissions to the new user
|
||||||
|
clusterRole, err := f.ClientSet.RbacV1().ClusterRoles().Create(context.TODO(), &rbacv1.ClusterRole{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{GenerateName: commonName + "-"},
|
||||||
|
Rules: []rbacv1.PolicyRule{{Verbs: []string{"create"}, APIGroups: []string{"certificates.k8s.io"}, Resources: []string{"certificatesigningrequests"}}},
|
||||||
|
}, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
// Tolerate RBAC not being enabled
|
||||||
|
framework.Logf("error granting permissions to %s, create certificatesigningrequests permissions must be granted out of band: %v", commonName, err)
|
||||||
|
} else {
|
||||||
|
defer func() {
|
||||||
|
framework.ExpectNoError(f.ClientSet.RbacV1().ClusterRoles().Delete(context.TODO(), clusterRole.Name, metav1.DeleteOptions{}))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterRoleBinding, err := f.ClientSet.RbacV1().ClusterRoleBindings().Create(context.TODO(), &rbacv1.ClusterRoleBinding{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{GenerateName: commonName + "-"},
|
||||||
|
RoleRef: rbacv1.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: clusterRole.Name},
|
||||||
|
Subjects: []rbacv1.Subject{{APIGroup: "rbac.authorization.k8s.io", Kind: "User", Name: commonName}},
|
||||||
|
}, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
// Tolerate RBAC not being enabled
|
||||||
|
framework.Logf("error granting permissions to %s, create certificatesigningrequests permissions must be granted out of band: %v", commonName, err)
|
||||||
|
} else {
|
||||||
|
defer func() {
|
||||||
|
framework.ExpectNoError(f.ClientSet.RbacV1().ClusterRoleBindings().Delete(context.TODO(), clusterRoleBinding.Name, metav1.DeleteOptions{}))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
framework.Logf("creating CSR")
|
framework.Logf("creating CSR")
|
||||||
csr, err = csrs.Create(context.TODO(), csr, metav1.CreateOptions{})
|
csr, err := csrClient.Create(context.TODO(), csrTemplate, metav1.CreateOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
defer func() {
|
||||||
csrName := csr.Name
|
framework.ExpectNoError(csrClient.Delete(context.TODO(), csr.Name, metav1.DeleteOptions{}))
|
||||||
|
}()
|
||||||
|
|
||||||
framework.Logf("approving CSR")
|
framework.Logf("approving CSR")
|
||||||
framework.ExpectNoError(wait.Poll(5*time.Second, time.Minute, func() (bool, error) {
|
framework.ExpectNoError(wait.Poll(5*time.Second, time.Minute, func() (bool, error) {
|
||||||
@ -82,9 +128,9 @@ var _ = SIGDescribe("Certificates API", func() {
|
|||||||
Message: "Set from an e2e test",
|
Message: "Set from an e2e test",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
csr, err = csrs.UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{})
|
csr, err = csrClient.UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
csr, _ = csrs.Get(context.TODO(), csrName, metav1.GetOptions{})
|
csr, _ = csrClient.Get(context.TODO(), csr.Name, metav1.GetOptions{})
|
||||||
framework.Logf("err updating approval: %v", err)
|
framework.Logf("err updating approval: %v", err)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@ -93,7 +139,7 @@ var _ = SIGDescribe("Certificates API", func() {
|
|||||||
|
|
||||||
framework.Logf("waiting for CSR to be signed")
|
framework.Logf("waiting for CSR to be signed")
|
||||||
framework.ExpectNoError(wait.Poll(5*time.Second, time.Minute, func() (bool, error) {
|
framework.ExpectNoError(wait.Poll(5*time.Second, time.Minute, func() (bool, error) {
|
||||||
csr, err = csrs.Get(context.TODO(), csrName, metav1.GetOptions{})
|
csr, err = csrClient.Get(context.TODO(), csr.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Logf("error getting csr: %v", err)
|
framework.Logf("error getting csr: %v", err)
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -108,17 +154,247 @@ var _ = SIGDescribe("Certificates API", func() {
|
|||||||
framework.Logf("testing the client")
|
framework.Logf("testing the client")
|
||||||
rcfg, err := framework.LoadConfig()
|
rcfg, err := framework.LoadConfig()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
rcfg = rest.AnonymousClientConfig(rcfg)
|
||||||
rcfg.TLSClientConfig.CertData = csr.Status.Certificate
|
rcfg.TLSClientConfig.CertData = csr.Status.Certificate
|
||||||
rcfg.TLSClientConfig.KeyData = pkpem
|
rcfg.TLSClientConfig.KeyData = pkpem
|
||||||
rcfg.TLSClientConfig.CertFile = ""
|
|
||||||
rcfg.BearerToken = ""
|
|
||||||
rcfg.AuthProvider = nil
|
|
||||||
rcfg.Username = ""
|
|
||||||
rcfg.Password = ""
|
|
||||||
|
|
||||||
newClient, err := v1beta1client.NewForConfig(rcfg)
|
newClient, err := certificatesclient.NewForConfig(rcfg)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
framework.ExpectNoError(newClient.CertificateSigningRequests().Delete(context.TODO(), csrName, metav1.DeleteOptions{}))
|
|
||||||
|
framework.Logf("creating CSR as new client")
|
||||||
|
newCSR, err := newClient.CertificateSigningRequests().Create(context.TODO(), csrTemplate, metav1.CreateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
defer func() {
|
||||||
|
framework.ExpectNoError(csrClient.Delete(context.TODO(), newCSR.Name, metav1.DeleteOptions{}))
|
||||||
|
}()
|
||||||
|
framework.ExpectEqual(newCSR.Spec.Username, commonName)
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
Release: v1.19
|
||||||
|
Testname: CertificateSigningRequest API
|
||||||
|
Description:
|
||||||
|
- The certificates.k8s.io API group MUST exists in the /apis discovery document.
|
||||||
|
- The certificates.k8s.io/v1beta1 API group/version MUST exist in the /apis/certificates.k8s.io discovery document.
|
||||||
|
- The certificatesigningrequests, certificatesigningrequests/approval, and certificatesigningrequests/status
|
||||||
|
resources MUST exist in the /apis/certificates.k8s.io/v1beta1 discovery document.
|
||||||
|
- The certificatesigningrequests resource must support create, get, list, watch, update, patch, delete, and deletecollection.
|
||||||
|
- The certificatesigningrequests/approval resource must support get, update, patch.
|
||||||
|
- The certificatesigningrequests/status resource must support get, update, patch.
|
||||||
|
*/
|
||||||
|
ginkgo.It("should support CSR API operations [Privileged:ClusterAdmin]", func() {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
csrVersion := "v1beta1"
|
||||||
|
csrClient := f.ClientSet.CertificatesV1beta1().CertificateSigningRequests()
|
||||||
|
csrResource := certificatesv1beta1.SchemeGroupVersion.WithResource("certificatesigningrequests")
|
||||||
|
|
||||||
|
pk, err := utils.NewPrivateKey()
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
csrData, err := cert.MakeCSR(pk, &pkix.Name{CommonName: "e2e.example.com"}, []string{"e2e.example.com"}, nil)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
certificateData, _, err := cert.GenerateSelfSignedCertKey("e2e.example.com", nil, []string{"e2e.example.com"})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
certificateDataJSON, err := json.Marshal(certificateData)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
signerName := "example.com/e2e-" + f.UniqueName
|
||||||
|
csrTemplate := &certificatesv1beta1.CertificateSigningRequest{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{GenerateName: "e2e-example-csr-"},
|
||||||
|
Spec: certificatesv1beta1.CertificateSigningRequestSpec{
|
||||||
|
Request: csrData,
|
||||||
|
SignerName: &signerName,
|
||||||
|
Usages: []certificatesv1beta1.KeyUsage{certificatesv1beta1.UsageDigitalSignature, certificatesv1beta1.UsageKeyEncipherment, certificatesv1beta1.UsageServerAuth},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discovery
|
||||||
|
|
||||||
|
ginkgo.By("getting /apis")
|
||||||
|
{
|
||||||
|
discoveryGroups, err := f.ClientSet.Discovery().ServerGroups()
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
found := false
|
||||||
|
for _, group := range discoveryGroups.Groups {
|
||||||
|
if group.Name == certificatesv1beta1.GroupName {
|
||||||
|
for _, version := range group.Versions {
|
||||||
|
if version.Version == csrVersion {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
framework.ExpectEqual(found, true, fmt.Sprintf("expected certificates API group/version, got %#v", discoveryGroups.Groups))
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("getting /apis/certificates.k8s.io")
|
||||||
|
{
|
||||||
|
group := &metav1.APIGroup{}
|
||||||
|
err := f.ClientSet.Discovery().RESTClient().Get().AbsPath("/apis/certificates.k8s.io").Do(context.TODO()).Into(group)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
found := false
|
||||||
|
for _, version := range group.Versions {
|
||||||
|
if version.Version == csrVersion {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
framework.ExpectEqual(found, true, fmt.Sprintf("expected certificates API version, got %#v", group.Versions))
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("getting /apis/certificates.k8s.io/" + csrVersion)
|
||||||
|
{
|
||||||
|
resources, err := f.ClientSet.Discovery().ServerResourcesForGroupVersion(certificatesv1beta1.SchemeGroupVersion.String())
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
foundCSR, foundApproval, foundStatus := false, false, false
|
||||||
|
for _, resource := range resources.APIResources {
|
||||||
|
switch resource.Name {
|
||||||
|
case "certificatesigningrequests":
|
||||||
|
foundCSR = true
|
||||||
|
case "certificatesigningrequests/approval":
|
||||||
|
foundApproval = true
|
||||||
|
case "certificatesigningrequests/status":
|
||||||
|
foundStatus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
framework.ExpectEqual(foundCSR, true, fmt.Sprintf("expected certificatesigningrequests, got %#v", resources.APIResources))
|
||||||
|
framework.ExpectEqual(foundApproval, true, fmt.Sprintf("expected certificatesigningrequests/approval, got %#v", resources.APIResources))
|
||||||
|
framework.ExpectEqual(foundStatus, true, fmt.Sprintf("expected certificatesigningrequests/status, got %#v", resources.APIResources))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main resource create/read/update/watch operations
|
||||||
|
|
||||||
|
ginkgo.By("creating")
|
||||||
|
_, err = csrClient.Create(context.TODO(), csrTemplate, metav1.CreateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
_, err = csrClient.Create(context.TODO(), csrTemplate, metav1.CreateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
createdCSR, err := csrClient.Create(context.TODO(), csrTemplate, metav1.CreateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
ginkgo.By("getting")
|
||||||
|
gottenCSR, err := csrClient.Get(context.TODO(), createdCSR.Name, metav1.GetOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(gottenCSR.UID, createdCSR.UID)
|
||||||
|
|
||||||
|
ginkgo.By("listing")
|
||||||
|
csrs, err := csrClient.List(context.TODO(), metav1.ListOptions{FieldSelector: "spec.signerName=" + signerName})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(len(csrs.Items), 3, "filtered list should have 3 items")
|
||||||
|
|
||||||
|
ginkgo.By("watching")
|
||||||
|
framework.Logf("starting watch")
|
||||||
|
csrWatch, err := csrClient.Watch(context.TODO(), metav1.ListOptions{ResourceVersion: csrs.ResourceVersion, FieldSelector: "metadata.name=" + createdCSR.Name})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
ginkgo.By("patching")
|
||||||
|
patchedCSR, err := csrClient.Patch(context.TODO(), createdCSR.Name, types.MergePatchType, []byte(`{"metadata":{"annotations":{"patched":"true"}}}`), metav1.PatchOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(patchedCSR.Annotations["patched"], "true", "patched object should have the applied annotation")
|
||||||
|
|
||||||
|
ginkgo.By("updating")
|
||||||
|
csrToUpdate := patchedCSR.DeepCopy()
|
||||||
|
csrToUpdate.Annotations["updated"] = "true"
|
||||||
|
updatedCSR, err := csrClient.Update(context.TODO(), csrToUpdate, metav1.UpdateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(updatedCSR.Annotations["updated"], "true", "updated object should have the applied annotation")
|
||||||
|
|
||||||
|
framework.Logf("waiting for watch events with expected annotations")
|
||||||
|
for sawAnnotations := false; !sawAnnotations; {
|
||||||
|
select {
|
||||||
|
case evt, ok := <-csrWatch.ResultChan():
|
||||||
|
framework.ExpectEqual(ok, true, "watch channel should not close")
|
||||||
|
framework.ExpectEqual(evt.Type, watch.Modified)
|
||||||
|
watchedCSR, isCSR := evt.Object.(*certificatesv1beta1.CertificateSigningRequest)
|
||||||
|
framework.ExpectEqual(isCSR, true, fmt.Sprintf("expected CSR, got %T", evt.Object))
|
||||||
|
if watchedCSR.Annotations["patched"] == "true" {
|
||||||
|
framework.Logf("saw patched and updated annotations")
|
||||||
|
sawAnnotations = true
|
||||||
|
csrWatch.Stop()
|
||||||
|
} else {
|
||||||
|
framework.Logf("missing expected annotations, waiting: %#v", watchedCSR.Annotations)
|
||||||
|
}
|
||||||
|
case <-time.After(wait.ForeverTestTimeout):
|
||||||
|
framework.Fail("timed out waiting for watch event")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// /approval subresource operations
|
||||||
|
|
||||||
|
ginkgo.By("getting /approval")
|
||||||
|
gottenApproval, err := f.DynamicClient.Resource(csrResource).Get(context.TODO(), createdCSR.Name, metav1.GetOptions{}, "approval")
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(gottenApproval.GetObjectKind().GroupVersionKind(), certificatesv1beta1.SchemeGroupVersion.WithKind("CertificateSigningRequest"))
|
||||||
|
framework.ExpectEqual(gottenApproval.GetUID(), createdCSR.UID)
|
||||||
|
|
||||||
|
ginkgo.By("patching /approval")
|
||||||
|
patchedApproval, err := csrClient.Patch(context.TODO(), createdCSR.Name, types.MergePatchType,
|
||||||
|
[]byte(`{"metadata":{"annotations":{"patchedapproval":"true"}},"status":{"conditions":[{"type":"ApprovalPatch","status":"True","reason":"e2e"}]}}`),
|
||||||
|
metav1.PatchOptions{}, "approval")
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(len(patchedApproval.Status.Conditions), 1, fmt.Sprintf("patched object should have the applied condition, got %#v", patchedApproval.Status.Conditions))
|
||||||
|
framework.ExpectEqual(string(patchedApproval.Status.Conditions[0].Type), "ApprovalPatch", fmt.Sprintf("patched object should have the applied condition, got %#v", patchedApproval.Status.Conditions))
|
||||||
|
framework.ExpectEqual(patchedApproval.Annotations["patchedapproval"], "true", "patched object should have the applied annotation")
|
||||||
|
|
||||||
|
ginkgo.By("updating /approval")
|
||||||
|
approvalToUpdate := patchedApproval.DeepCopy()
|
||||||
|
approvalToUpdate.Status.Conditions = append(approvalToUpdate.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{
|
||||||
|
Type: certificatesv1beta1.CertificateApproved,
|
||||||
|
Reason: "E2E",
|
||||||
|
Message: "Set from an e2e test",
|
||||||
|
})
|
||||||
|
updatedApproval, err := csrClient.UpdateApproval(context.TODO(), approvalToUpdate, metav1.UpdateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(len(updatedApproval.Status.Conditions), 2, fmt.Sprintf("updated object should have the applied condition, got %#v", updatedApproval.Status.Conditions))
|
||||||
|
framework.ExpectEqual(updatedApproval.Status.Conditions[1].Type, certificatesv1beta1.CertificateApproved, fmt.Sprintf("updated object should have the approved condition, got %#v", updatedApproval.Status.Conditions))
|
||||||
|
|
||||||
|
// /status subresource operations
|
||||||
|
|
||||||
|
ginkgo.By("getting /status")
|
||||||
|
gottenStatus, err := f.DynamicClient.Resource(csrResource).Get(context.TODO(), createdCSR.Name, metav1.GetOptions{}, "status")
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(gottenStatus.GetObjectKind().GroupVersionKind(), certificatesv1beta1.SchemeGroupVersion.WithKind("CertificateSigningRequest"))
|
||||||
|
framework.ExpectEqual(gottenStatus.GetUID(), createdCSR.UID)
|
||||||
|
|
||||||
|
ginkgo.By("patching /status")
|
||||||
|
patchedStatus, err := csrClient.Patch(context.TODO(), createdCSR.Name, types.MergePatchType,
|
||||||
|
[]byte(`{"metadata":{"annotations":{"patchedstatus":"true"}},"status":{"certificate":`+string(certificateDataJSON)+`}}`),
|
||||||
|
metav1.PatchOptions{}, "status")
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(patchedStatus.Status.Certificate, certificateData, "patched object should have the applied certificate")
|
||||||
|
framework.ExpectEqual(patchedStatus.Annotations["patchedstatus"], "true", "patched object should have the applied annotation")
|
||||||
|
|
||||||
|
ginkgo.By("updating /status")
|
||||||
|
statusToUpdate := patchedStatus.DeepCopy()
|
||||||
|
statusToUpdate.Status.Conditions = append(statusToUpdate.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{
|
||||||
|
Type: "StatusUpdate",
|
||||||
|
Reason: "E2E",
|
||||||
|
Message: "Set from an e2e test",
|
||||||
|
})
|
||||||
|
updatedStatus, err := csrClient.UpdateStatus(context.TODO(), statusToUpdate, metav1.UpdateOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(len(updatedStatus.Status.Conditions), len(statusToUpdate.Status.Conditions), fmt.Sprintf("updated object should have the applied condition, got %#v", updatedStatus.Status.Conditions))
|
||||||
|
framework.ExpectEqual(string(updatedStatus.Status.Conditions[len(updatedStatus.Status.Conditions)-1].Type), "StatusUpdate", fmt.Sprintf("updated object should have the approved condition, got %#v", updatedStatus.Status.Conditions))
|
||||||
|
|
||||||
|
// main resource delete operations
|
||||||
|
|
||||||
|
ginkgo.By("deleting")
|
||||||
|
err = csrClient.Delete(context.TODO(), createdCSR.Name, metav1.DeleteOptions{})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
_, err = csrClient.Get(context.TODO(), createdCSR.Name, metav1.GetOptions{})
|
||||||
|
framework.ExpectEqual(apierrors.IsNotFound(err), true, fmt.Sprintf("expected 404, got %#v", err))
|
||||||
|
csrs, err = csrClient.List(context.TODO(), metav1.ListOptions{FieldSelector: "spec.signerName=" + signerName})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(len(csrs.Items), 2, "filtered list should have 2 items")
|
||||||
|
|
||||||
|
ginkgo.By("deleting a collection")
|
||||||
|
err = csrClient.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{FieldSelector: "spec.signerName=" + signerName})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
csrs, err = csrClient.List(context.TODO(), metav1.ListOptions{FieldSelector: "spec.signerName=" + signerName})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectEqual(len(csrs.Items), 0, "filtered list should have 0 items")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user