Merge pull request #30166 from mikedanese/csr-print

Automatic merge from submit-queue

add a certificate signing request resource printer in kubectl

#30163
pull/6/head
Kubernetes Submit Queue 2016-08-15 16:02:24 -07:00 committed by GitHub
commit 431e7ce1ab
2 changed files with 149 additions and 12 deletions

View File

@ -28,7 +28,6 @@ import (
"strings"
"time"
"github.com/golang/glog"
"k8s.io/kubernetes/federation/apis/federation"
fed_clientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
"k8s.io/kubernetes/pkg/api"
@ -38,6 +37,7 @@ import (
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/apis/extensions"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
client "k8s.io/kubernetes/pkg/client/unversioned"
@ -48,8 +48,11 @@ import (
"k8s.io/kubernetes/pkg/kubelet/qos"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/types"
utilcertificates "k8s.io/kubernetes/pkg/util/certificates"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/sets"
"github.com/golang/glog"
)
// Describer generates output for the named resource or an error
@ -101,17 +104,18 @@ func describerMap(c *client.Client) map[unversioned.GroupKind]Describer {
api.Kind("Endpoints"): &EndpointsDescriber{c},
api.Kind("ConfigMap"): &ConfigMapDescriber{c},
extensions.Kind("ReplicaSet"): &ReplicaSetDescriber{c},
extensions.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
extensions.Kind("NetworkPolicy"): &NetworkPolicyDescriber{c},
autoscaling.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
extensions.Kind("DaemonSet"): &DaemonSetDescriber{c},
extensions.Kind("Deployment"): &DeploymentDescriber{adapter.FromUnversionedClient(c)},
extensions.Kind("Job"): &JobDescriber{c},
batch.Kind("Job"): &JobDescriber{c},
batch.Kind("ScheduledJob"): &ScheduledJobDescriber{adapter.FromUnversionedClient(c)},
apps.Kind("PetSet"): &PetSetDescriber{c},
extensions.Kind("Ingress"): &IngressDescriber{c},
extensions.Kind("ReplicaSet"): &ReplicaSetDescriber{c},
extensions.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
extensions.Kind("NetworkPolicy"): &NetworkPolicyDescriber{c},
autoscaling.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
extensions.Kind("DaemonSet"): &DaemonSetDescriber{c},
extensions.Kind("Deployment"): &DeploymentDescriber{adapter.FromUnversionedClient(c)},
extensions.Kind("Job"): &JobDescriber{c},
extensions.Kind("Ingress"): &IngressDescriber{c},
batch.Kind("Job"): &JobDescriber{c},
batch.Kind("ScheduledJob"): &ScheduledJobDescriber{adapter.FromUnversionedClient(c)},
apps.Kind("PetSet"): &PetSetDescriber{c},
certificates.Kind("CertificateSigningRequest"): &CertificateSigningRequestDescriber{c},
}
return m
@ -1883,6 +1887,74 @@ func (p *PetSetDescriber) Describe(namespace, name string, describerSettings Des
})
}
type CertificateSigningRequestDescriber struct {
client *client.Client
}
func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
csr, err := p.client.Certificates().CertificateSigningRequests().Get(name)
if err != nil {
return "", err
}
cr, err := utilcertificates.ParseCertificateRequestObject(csr)
if err != nil {
return "", fmt.Errorf("Error parsing CSR: %v", err)
}
status, err := extractCSRStatus(csr)
if err != nil {
return "", err
}
printListHelper := func(out io.Writer, prefix, name string, values []string) {
if len(values) == 0 {
return
}
fmt.Fprintf(out, prefix+name+":\t")
fmt.Fprintf(out, strings.Join(values, "\n"+prefix+"\t"))
fmt.Fprintf(out, "\n")
}
return tabbedString(func(out io.Writer) error {
fmt.Fprintf(out, "Name:\t%s\n", csr.Name)
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(csr.Labels))
fmt.Fprintf(out, "Annotations:\t%s\n", labels.FormatLabels(csr.Annotations))
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", csr.CreationTimestamp.Time.Format(time.RFC1123Z))
fmt.Fprintf(out, "Requesting User:\t%s\n", csr.Spec.Username)
fmt.Fprintf(out, "Status:\t%s\n", status)
fmt.Fprintf(out, "Subject:\n")
fmt.Fprintf(out, "\tCommon Name:\t%s\n", cr.Subject.CommonName)
fmt.Fprintf(out, "\tSerial Number:\t%s\n", cr.Subject.SerialNumber)
printListHelper(out, "\t", "Organization", cr.Subject.Organization)
printListHelper(out, "\t", "Organizational Unit", cr.Subject.OrganizationalUnit)
printListHelper(out, "\t", "Country", cr.Subject.Country)
printListHelper(out, "\t", "Locality", cr.Subject.Locality)
printListHelper(out, "\t", "Province", cr.Subject.Province)
printListHelper(out, "\t", "StreetAddress", cr.Subject.StreetAddress)
printListHelper(out, "\t", "PostalCode", cr.Subject.PostalCode)
if len(cr.DNSNames)+len(cr.EmailAddresses)+len(cr.IPAddresses) > 0 {
fmt.Fprintf(out, "Subject Alternative Names:\n")
printListHelper(out, "\t", "DNS Names", cr.DNSNames)
printListHelper(out, "\t", "Email Addresses", cr.EmailAddresses)
var ipaddrs []string
for _, ipaddr := range cr.IPAddresses {
ipaddrs = append(ipaddrs, ipaddr.String())
}
printListHelper(out, "\t", "IP Addresses", ipaddrs)
}
if describerSettings.ShowEvents {
events, _ := p.client.Events(namespace).Search(csr)
if events != nil {
DescribeEvents(events, out)
}
}
return nil
})
}
// HorizontalPodAutoscalerDescriber generates information about a horizontal pod autoscaler.
type HorizontalPodAutoscalerDescriber struct {
client *client.Client

View File

@ -39,6 +39,7 @@ import (
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/labels"
@ -468,6 +469,7 @@ var configMapColumns = []string{"NAME", "DATA", "AGE"}
var podSecurityPolicyColumns = []string{"NAME", "PRIV", "CAPS", "VOLUMEPLUGINS", "SELINUX", "RUNASUSER"}
var clusterColumns = []string{"NAME", "STATUS", "VERSION", "AGE"}
var networkPolicyColumns = []string{"NAME", "POD-SELECTOR", "AGE"}
var certificateSigningRequestColumns = []string{"NAME", "AGE", "REQUESTOR", "CONDITION"}
// addDefaultHandlers adds print handlers for default Kubernetes types.
func (h *HumanReadablePrinter) addDefaultHandlers() {
@ -537,6 +539,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
h.Handler(clusterRoleColumns, printClusterRoleList)
h.Handler(clusterRoleBindingColumns, printClusterRoleBinding)
h.Handler(clusterRoleBindingColumns, printClusterRoleBindingList)
h.Handler(certificateSigningRequestColumns, printCertificateSigningRequest)
h.Handler(certificateSigningRequestColumns, printCertificateSigningRequestList)
}
func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error {
@ -1695,6 +1699,67 @@ func printClusterRoleBindingList(list *rbac.ClusterRoleBindingList, w io.Writer,
return nil
}
func printCertificateSigningRequest(csr *certificates.CertificateSigningRequest, w io.Writer, options PrintOptions) error {
name := formatResourceName(options.Kind, csr.Name, options.WithKind)
meta := csr.ObjectMeta
status, err := extractCSRStatus(csr)
if err != nil {
return err
}
if _, err := fmt.Fprintf(
w, "%s\t%s\t%s\t%s",
name,
translateTimestamp(meta.CreationTimestamp),
csr.Spec.Username,
status,
); err != nil {
return err
}
if _, err := fmt.Fprint(w, AppendLabels(meta.Labels, options.ColumnLabels)); err != nil {
return err
}
_, err = fmt.Fprint(w, AppendAllLabels(options.ShowLabels, meta.Labels))
return err
}
func extractCSRStatus(csr *certificates.CertificateSigningRequest) (string, error) {
var approved, denied bool
for _, c := range csr.Status.Conditions {
switch c.Type {
case certificates.CertificateApproved:
approved = true
case certificates.CertificateDenied:
denied = true
default:
return "", fmt.Errorf("unknown csr conditon %q", c)
}
}
var status string
// must be in order of presidence
if denied {
status += "Denied"
} else if approved {
status += "Approved"
} else {
status += "Pending"
}
if len(csr.Status.Certificate) > 0 {
status += ",Issued"
}
return status, nil
}
func printCertificateSigningRequestList(list *certificates.CertificateSigningRequestList, w io.Writer, options PrintOptions) error {
for i := range list.Items {
if err := printCertificateSigningRequest(&list.Items[i], w, options); err != nil {
return err
}
}
return nil
}
func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintOptions) error {
name := formatResourceName(options.Kind, item.Name, options.WithKind)