mirror of https://github.com/k3s-io/k3s
Merge pull request #30166 from mikedanese/csr-print
Automatic merge from submit-queue add a certificate signing request resource printer in kubectl #30163pull/6/head
commit
431e7ce1ab
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue