From cd341c16977bcea24c0946dbcf03fd1114162be3 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Thu, 4 Jun 2020 12:05:51 -0400 Subject: [PATCH] Add v1 CSR support to kubectl describe Kubernetes-commit: 92a665e83f223425608e38286fdf147acb85112d --- pkg/describe/describe.go | 75 ++++++++++++++++++++--------- pkg/util/certificate/certificate.go | 6 +-- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/pkg/describe/describe.go b/pkg/describe/describe.go index 2e8692dce..bbca655d3 100644 --- a/pkg/describe/describe.go +++ b/pkg/describe/describe.go @@ -3252,26 +3252,57 @@ type CertificateSigningRequestDescriber struct { } func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) { - csr, err := p.client.CertificatesV1beta1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{}) - if err != nil { + + var ( + crBytes []byte + metadata metav1.ObjectMeta + status string + signerName string + username string + events *corev1.EventList + ) + + if csr, err := p.client.CertificatesV1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{}); err == nil { + crBytes = csr.Spec.Request + metadata = csr.ObjectMeta + conditionTypes := []string{} + for _, c := range csr.Status.Conditions { + conditionTypes = append(conditionTypes, string(c.Type)) + } + status = extractCSRStatus(conditionTypes, csr.Status.Certificate) + signerName = csr.Spec.SignerName + username = csr.Spec.Username + if describerSettings.ShowEvents { + events, _ = p.client.CoreV1().Events(namespace).Search(scheme.Scheme, csr) + } + } else if csr, err := p.client.CertificatesV1beta1().CertificateSigningRequests().Get(context.TODO(), name, metav1.GetOptions{}); err == nil { + crBytes = csr.Spec.Request + metadata = csr.ObjectMeta + conditionTypes := []string{} + for _, c := range csr.Status.Conditions { + conditionTypes = append(conditionTypes, string(c.Type)) + } + status = extractCSRStatus(conditionTypes, csr.Status.Certificate) + if csr.Spec.SignerName != nil { + signerName = *csr.Spec.SignerName + } + username = csr.Spec.Username + if describerSettings.ShowEvents { + events, _ = p.client.CoreV1().Events(namespace).Search(scheme.Scheme, csr) + } + } else { return "", err } - cr, err := certificate.ParseCSR(csr) + cr, err := certificate.ParseCSR(crBytes) if err != nil { return "", fmt.Errorf("Error parsing CSR: %v", err) } - status := extractCSRStatus(csr) - var events *corev1.EventList - if describerSettings.ShowEvents { - events, _ = p.client.CoreV1().Events(namespace).Search(scheme.Scheme, csr) - } - - return describeCertificateSigningRequest(csr, cr, status, events) + return describeCertificateSigningRequest(metadata, signerName, username, cr, status, events) } -func describeCertificateSigningRequest(csr *certificatesv1beta1.CertificateSigningRequest, cr *x509.CertificateRequest, status string, events *corev1.EventList) (string, error) { +func describeCertificateSigningRequest(csr metav1.ObjectMeta, signerName string, username string, cr *x509.CertificateRequest, status string, events *corev1.EventList) (string, error) { printListHelper := func(w PrefixWriter, prefix, name string, values []string) { if len(values) == 0 { return @@ -3287,9 +3318,9 @@ func describeCertificateSigningRequest(csr *certificatesv1beta1.CertificateSigni w.Write(LEVEL_0, "Labels:\t%s\n", labels.FormatLabels(csr.Labels)) w.Write(LEVEL_0, "Annotations:\t%s\n", labels.FormatLabels(csr.Annotations)) w.Write(LEVEL_0, "CreationTimestamp:\t%s\n", csr.CreationTimestamp.Time.Format(time.RFC1123Z)) - w.Write(LEVEL_0, "Requesting User:\t%s\n", csr.Spec.Username) - if csr.Spec.SignerName != nil { - w.Write(LEVEL_0, "Signer:\t%s\n", *csr.Spec.SignerName) + w.Write(LEVEL_0, "Requesting User:\t%s\n", username) + if len(signerName) > 0 { + w.Write(LEVEL_0, "Signer:\t%s\n", signerName) } w.Write(LEVEL_0, "Status:\t%s\n", status) @@ -4835,20 +4866,20 @@ func formatEndpoints(endpoints *corev1.Endpoints, ports sets.String) string { return ret } -func extractCSRStatus(csr *certificatesv1beta1.CertificateSigningRequest) string { +func extractCSRStatus(conditions []string, certificateBytes []byte) string { var approved, denied, failed bool - for _, c := range csr.Status.Conditions { - switch c.Type { - case certificatesv1beta1.CertificateApproved: + for _, c := range conditions { + switch c { + case string(certificatesv1beta1.CertificateApproved): approved = true - case certificatesv1beta1.CertificateDenied: + case string(certificatesv1beta1.CertificateDenied): denied = true - case certificatesv1beta1.CertificateFailed: + case string(certificatesv1beta1.CertificateFailed): failed = true } } var status string - // must be in order of presidence + // must be in order of precedence if denied { status += "Denied" } else if approved { @@ -4859,7 +4890,7 @@ func extractCSRStatus(csr *certificatesv1beta1.CertificateSigningRequest) string if failed { status += ",Failed" } - if len(csr.Status.Certificate) > 0 { + if len(certificateBytes) > 0 { status += ",Issued" } return status diff --git a/pkg/util/certificate/certificate.go b/pkg/util/certificate/certificate.go index 201958c6f..c55e5963f 100644 --- a/pkg/util/certificate/certificate.go +++ b/pkg/util/certificate/certificate.go @@ -20,16 +20,12 @@ import ( "crypto/x509" "encoding/pem" "errors" - - certificatesv1beta1 "k8s.io/api/certificates/v1beta1" ) // TODO(yue9944882): Remove this helper package once it's copied to k/api // ParseCSR extracts the CSR from the API object and decodes it. -func ParseCSR(obj *certificatesv1beta1.CertificateSigningRequest) (*x509.CertificateRequest, error) { - // extract PEM from request object - pemBytes := obj.Spec.Request +func ParseCSR(pemBytes []byte) (*x509.CertificateRequest, error) { block, _ := pem.Decode(pemBytes) if block == nil || block.Type != "CERTIFICATE REQUEST" { return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")