Skip to content

Commit 31520cc

Browse files
author
Christopher M. Luciano
committed
ingress: Add v1 describers for Ingress and IngressClass
Ingressv1 Get is attempted for Ingresses and IngressClasses and falls back to Ingressv1beta1 if there is a failure. Signed-off-by: Christopher M. Luciano <[email protected]>
1 parent 868efab commit 31520cc

File tree

2 files changed

+512
-54
lines changed

2 files changed

+512
-54
lines changed

staging/src/k8s.io/kubectl/pkg/describe/describe.go

Lines changed: 187 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ func describerMap(clientConfig *rest.Config) (map[schema.GroupKind]ResourceDescr
187187
{Group: extensionsv1beta1.GroupName, Kind: "Ingress"}: &IngressDescriber{c},
188188
{Group: networkingv1beta1.GroupName, Kind: "Ingress"}: &IngressDescriber{c},
189189
{Group: networkingv1beta1.GroupName, Kind: "IngressClass"}: &IngressClassDescriber{c},
190+
{Group: networkingv1.GroupName, Kind: "Ingress"}: &IngressDescriber{c},
191+
{Group: networkingv1.GroupName, Kind: "IngressClass"}: &IngressClassDescriber{c},
190192
{Group: batchv1.GroupName, Kind: "Job"}: &JobDescriber{c},
191193
{Group: batchv1.GroupName, Kind: "CronJob"}: &CronJobDescriber{c},
192194
{Group: appsv1.GroupName, Kind: "StatefulSet"}: &StatefulSetDescriber{c},
@@ -2343,24 +2345,36 @@ func describeSecret(secret *corev1.Secret) (string, error) {
23432345
}
23442346

23452347
type IngressDescriber struct {
2346-
clientset.Interface
2348+
client clientset.Interface
23472349
}
23482350

23492351
func (i *IngressDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
2350-
c := i.NetworkingV1beta1().Ingresses(namespace)
2351-
ing, err := c.Get(context.TODO(), name, metav1.GetOptions{})
2352-
if err != nil {
2353-
return "", err
2352+
var events *corev1.EventList
2353+
2354+
// try ingress/v1 first (v1.19) and fallback to ingress/v1beta if an err occurs
2355+
netV1, err := i.client.NetworkingV1().Ingresses(namespace).Get(context.TODO(), name, metav1.GetOptions{})
2356+
if err == nil {
2357+
if describerSettings.ShowEvents {
2358+
events, _ = i.client.CoreV1().Events(namespace).Search(scheme.Scheme, netV1)
2359+
}
2360+
return i.describeIngressV1(netV1, events)
23542361
}
2355-
return i.describeIngress(ing, describerSettings)
2362+
netV1beta1, err := i.client.NetworkingV1beta1().Ingresses(namespace).Get(context.TODO(), name, metav1.GetOptions{})
2363+
if err == nil {
2364+
if describerSettings.ShowEvents {
2365+
events, _ = i.client.CoreV1().Events(namespace).Search(scheme.Scheme, netV1beta1)
2366+
}
2367+
return i.describeIngressV1beta1(netV1beta1, events)
2368+
}
2369+
return "", err
23562370
}
23572371

2358-
func (i *IngressDescriber) describeBackend(ns string, backend *networkingv1beta1.IngressBackend) string {
2359-
endpoints, err := i.CoreV1().Endpoints(ns).Get(context.TODO(), backend.ServiceName, metav1.GetOptions{})
2372+
func (i *IngressDescriber) describeBackendV1beta1(ns string, backend *networkingv1beta1.IngressBackend) string {
2373+
endpoints, err := i.client.CoreV1().Endpoints(ns).Get(context.TODO(), backend.ServiceName, metav1.GetOptions{})
23602374
if err != nil {
23612375
return fmt.Sprintf("<error: %v>", err)
23622376
}
2363-
service, err := i.CoreV1().Services(ns).Get(context.TODO(), backend.ServiceName, metav1.GetOptions{})
2377+
service, err := i.client.CoreV1().Services(ns).Get(context.TODO(), backend.ServiceName, metav1.GetOptions{})
23642378
if err != nil {
23652379
return fmt.Sprintf("<error: %v>", err)
23662380
}
@@ -2381,7 +2395,93 @@ func (i *IngressDescriber) describeBackend(ns string, backend *networkingv1beta1
23812395
return formatEndpoints(endpoints, sets.NewString(spName))
23822396
}
23832397

2384-
func (i *IngressDescriber) describeIngress(ing *networkingv1beta1.Ingress, describerSettings DescriberSettings) (string, error) {
2398+
func (i *IngressDescriber) describeBackendV1(ns string, backend *networkingv1.IngressBackend) string {
2399+
2400+
if backend.Service != nil {
2401+
sb := serviceBackendStringer(backend.Service)
2402+
endpoints, err := i.client.CoreV1().Endpoints(ns).Get(context.TODO(), backend.Service.Name, metav1.GetOptions{})
2403+
if err != nil {
2404+
return fmt.Sprintf("%v (<error: %v>)", sb, err)
2405+
}
2406+
service, err := i.client.CoreV1().Services(ns).Get(context.TODO(), backend.Service.Name, metav1.GetOptions{})
2407+
if err != nil {
2408+
return fmt.Sprintf("%v(<error: %v>)", sb, err)
2409+
}
2410+
spName := ""
2411+
for i := range service.Spec.Ports {
2412+
sp := &service.Spec.Ports[i]
2413+
if backend.Service.Port.Number != 0 && backend.Service.Port.Number == sp.Port {
2414+
spName = sp.Name
2415+
} else if len(backend.Service.Port.Name) > 0 && backend.Service.Port.Name == sp.Name {
2416+
spName = sp.Name
2417+
}
2418+
}
2419+
ep := formatEndpoints(endpoints, sets.NewString(spName))
2420+
return fmt.Sprintf("%s\t %s)", sb, ep)
2421+
}
2422+
if backend.Resource != nil {
2423+
ic := backend.Resource
2424+
return fmt.Sprintf("APIGroup: %v, Kind: %v, Name: %v", *ic.APIGroup, ic.Kind, ic.Name)
2425+
}
2426+
return ""
2427+
}
2428+
2429+
func (i *IngressDescriber) describeIngressV1(ing *networkingv1.Ingress, events *corev1.EventList) (string, error) {
2430+
return tabbedString(func(out io.Writer) error {
2431+
w := NewPrefixWriter(out)
2432+
w.Write(LEVEL_0, "Name:\t%v\n", ing.Name)
2433+
w.Write(LEVEL_0, "Namespace:\t%v\n", ing.Namespace)
2434+
w.Write(LEVEL_0, "Address:\t%v\n", loadBalancerStatusStringer(ing.Status.LoadBalancer, true))
2435+
def := ing.Spec.DefaultBackend
2436+
ns := ing.Namespace
2437+
if def == nil {
2438+
// Ingresses that don't specify a default backend inherit the
2439+
// default backend in the kube-system namespace.
2440+
def = &networkingv1.IngressBackend{
2441+
Service: &networkingv1.IngressServiceBackend{
2442+
Name: "default-http-backend",
2443+
Port: networkingv1.ServiceBackendPort{
2444+
Number: 80,
2445+
},
2446+
},
2447+
}
2448+
ns = metav1.NamespaceSystem
2449+
}
2450+
w.Write(LEVEL_0, "Default backend:\t%s\n", i.describeBackendV1(ns, def))
2451+
if len(ing.Spec.TLS) != 0 {
2452+
describeIngressTLSV1(w, ing.Spec.TLS)
2453+
}
2454+
w.Write(LEVEL_0, "Rules:\n Host\tPath\tBackends\n")
2455+
w.Write(LEVEL_1, "----\t----\t--------\n")
2456+
count := 0
2457+
for _, rules := range ing.Spec.Rules {
2458+
2459+
if rules.HTTP == nil {
2460+
continue
2461+
}
2462+
count++
2463+
host := rules.Host
2464+
if len(host) == 0 {
2465+
host = "*"
2466+
}
2467+
w.Write(LEVEL_1, "%s\t\n", host)
2468+
for _, path := range rules.HTTP.Paths {
2469+
w.Write(LEVEL_2, "\t%s \t%s\n", path.Path, i.describeBackendV1(ing.Namespace, &path.Backend))
2470+
}
2471+
}
2472+
if count == 0 {
2473+
w.Write(LEVEL_1, "\t%s %s\n", "*", "*", i.describeBackendV1(ns, def))
2474+
}
2475+
printAnnotationsMultiline(w, "Annotations", ing.Annotations)
2476+
2477+
if events != nil {
2478+
DescribeEvents(events, w)
2479+
}
2480+
return nil
2481+
})
2482+
}
2483+
2484+
func (i *IngressDescriber) describeIngressV1beta1(ing *networkingv1beta1.Ingress, events *corev1.EventList) (string, error) {
23852485
return tabbedString(func(out io.Writer) error {
23862486
w := NewPrefixWriter(out)
23872487
w.Write(LEVEL_0, "Name:\t%v\n", ing.Name)
@@ -2398,14 +2498,15 @@ func (i *IngressDescriber) describeIngress(ing *networkingv1beta1.Ingress, descr
23982498
}
23992499
ns = metav1.NamespaceSystem
24002500
}
2401-
w.Write(LEVEL_0, "Default backend:\t%s (%s)\n", backendStringer(def), i.describeBackend(ns, def))
2501+
w.Write(LEVEL_0, "Default backend:\t%s (%s)\n", backendStringer(def), i.describeBackendV1beta1(ns, def))
24022502
if len(ing.Spec.TLS) != 0 {
2403-
describeIngressTLS(w, ing.Spec.TLS)
2503+
describeIngressTLSV1beta1(w, ing.Spec.TLS)
24042504
}
24052505
w.Write(LEVEL_0, "Rules:\n Host\tPath\tBackends\n")
24062506
w.Write(LEVEL_1, "----\t----\t--------\n")
24072507
count := 0
24082508
for _, rules := range ing.Spec.Rules {
2509+
24092510
if rules.HTTP == nil {
24102511
continue
24112512
}
@@ -2416,25 +2517,33 @@ func (i *IngressDescriber) describeIngress(ing *networkingv1beta1.Ingress, descr
24162517
}
24172518
w.Write(LEVEL_1, "%s\t\n", host)
24182519
for _, path := range rules.HTTP.Paths {
2419-
w.Write(LEVEL_2, "\t%s \t%s (%s)\n", path.Path, backendStringer(&path.Backend), i.describeBackend(ing.Namespace, &path.Backend))
2520+
w.Write(LEVEL_2, "\t%s \t%s (%s)\n", path.Path, backendStringer(&path.Backend), i.describeBackendV1beta1(ing.Namespace, &path.Backend))
24202521
}
24212522
}
24222523
if count == 0 {
2423-
w.Write(LEVEL_1, "%s\t%s \t%s (%s)\n", "*", "*", backendStringer(def), i.describeBackend(ns, def))
2524+
w.Write(LEVEL_1, "%s\t%s \t%s (%s)\n", "*", "*", backendStringer(def), i.describeBackendV1beta1(ns, def))
24242525
}
24252526
printAnnotationsMultiline(w, "Annotations", ing.Annotations)
24262527

2427-
if describerSettings.ShowEvents {
2428-
events, _ := i.CoreV1().Events(ing.Namespace).Search(scheme.Scheme, ing)
2429-
if events != nil {
2430-
DescribeEvents(events, w)
2431-
}
2528+
if events != nil {
2529+
DescribeEvents(events, w)
24322530
}
24332531
return nil
24342532
})
24352533
}
24362534

2437-
func describeIngressTLS(w PrefixWriter, ingTLS []networkingv1beta1.IngressTLS) {
2535+
func describeIngressTLSV1beta1(w PrefixWriter, ingTLS []networkingv1beta1.IngressTLS) {
2536+
w.Write(LEVEL_0, "TLS:\n")
2537+
for _, t := range ingTLS {
2538+
if t.SecretName == "" {
2539+
w.Write(LEVEL_1, "SNI routes %v\n", strings.Join(t.Hosts, ","))
2540+
} else {
2541+
w.Write(LEVEL_1, "%v terminates %v\n", t.SecretName, strings.Join(t.Hosts, ","))
2542+
}
2543+
}
2544+
}
2545+
2546+
func describeIngressTLSV1(w PrefixWriter, ingTLS []networkingv1.IngressTLS) {
24382547
w.Write(LEVEL_0, "TLS:\n")
24392548
for _, t := range ingTLS {
24402549
if t.SecretName == "" {
@@ -2446,19 +2555,30 @@ func describeIngressTLS(w PrefixWriter, ingTLS []networkingv1beta1.IngressTLS) {
24462555
}
24472556

24482557
type IngressClassDescriber struct {
2449-
clientset.Interface
2558+
client clientset.Interface
24502559
}
24512560

24522561
func (i *IngressClassDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
2453-
c := i.NetworkingV1beta1().IngressClasses()
2454-
ic, err := c.Get(context.TODO(), name, metav1.GetOptions{})
2455-
if err != nil {
2456-
return "", err
2562+
var events *corev1.EventList
2563+
// try IngressClass/v1 first (v1.19) and fallback to IngressClass/v1beta if an err occurs
2564+
netV1, err := i.client.NetworkingV1().IngressClasses().Get(context.TODO(), name, metav1.GetOptions{})
2565+
if err == nil {
2566+
if describerSettings.ShowEvents {
2567+
events, _ = i.client.CoreV1().Events(namespace).Search(scheme.Scheme, netV1)
2568+
}
2569+
return i.describeIngressClassV1(netV1, events)
2570+
}
2571+
netV1beta1, err := i.client.NetworkingV1beta1().IngressClasses().Get(context.TODO(), name, metav1.GetOptions{})
2572+
if err == nil {
2573+
if describerSettings.ShowEvents {
2574+
events, _ = i.client.CoreV1().Events(namespace).Search(scheme.Scheme, netV1beta1)
2575+
}
2576+
return i.describeIngressClassV1beta1(netV1beta1, events)
24572577
}
2458-
return i.describeIngressClass(ic, describerSettings)
2578+
return "", err
24592579
}
24602580

2461-
func (i *IngressClassDescriber) describeIngressClass(ic *networkingv1beta1.IngressClass, describerSettings DescriberSettings) (string, error) {
2581+
func (i *IngressClassDescriber) describeIngressClassV1beta1(ic *networkingv1beta1.IngressClass, events *corev1.EventList) (string, error) {
24622582
return tabbedString(func(out io.Writer) error {
24632583
w := NewPrefixWriter(out)
24642584
w.Write(LEVEL_0, "Name:\t%s\n", ic.Name)
@@ -2474,7 +2594,32 @@ func (i *IngressClassDescriber) describeIngressClass(ic *networkingv1beta1.Ingre
24742594
w.Write(LEVEL_1, "Kind:\t%v\n", ic.Spec.Parameters.Kind)
24752595
w.Write(LEVEL_1, "Name:\t%v\n", ic.Spec.Parameters.Name)
24762596
}
2597+
if events != nil {
2598+
DescribeEvents(events, w)
2599+
}
2600+
return nil
2601+
})
2602+
}
24772603

2604+
func (i *IngressClassDescriber) describeIngressClassV1(ic *networkingv1.IngressClass, events *corev1.EventList) (string, error) {
2605+
return tabbedString(func(out io.Writer) error {
2606+
w := NewPrefixWriter(out)
2607+
w.Write(LEVEL_0, "Name:\t%s\n", ic.Name)
2608+
printLabelsMultiline(w, "Labels", ic.Labels)
2609+
printAnnotationsMultiline(w, "Annotations", ic.Annotations)
2610+
w.Write(LEVEL_0, "Controller:\t%v\n", ic.Spec.Controller)
2611+
2612+
if ic.Spec.Parameters != nil {
2613+
w.Write(LEVEL_0, "Parameters:\n")
2614+
if ic.Spec.Parameters.APIGroup != nil {
2615+
w.Write(LEVEL_1, "APIGroup:\t%v\n", *ic.Spec.Parameters.APIGroup)
2616+
}
2617+
w.Write(LEVEL_1, "Kind:\t%v\n", ic.Spec.Parameters.Kind)
2618+
w.Write(LEVEL_1, "Name:\t%v\n", ic.Spec.Parameters.Name)
2619+
}
2620+
if events != nil {
2621+
DescribeEvents(events, w)
2622+
}
24782623
return nil
24792624
})
24802625
}
@@ -4896,6 +5041,21 @@ func extractCSRStatus(conditions []string, certificateBytes []byte) string {
48965041
return status
48975042
}
48985043

5044+
// backendStringer behaves just like a string interface and converts the given backend to a string.
5045+
func serviceBackendStringer(backend *networkingv1.IngressServiceBackend) string {
5046+
if backend == nil {
5047+
return ""
5048+
}
5049+
var bPort string
5050+
if backend.Port.Number != 0 {
5051+
sNum := int64(backend.Port.Number)
5052+
bPort = strconv.FormatInt(sNum, 10)
5053+
} else {
5054+
bPort = backend.Port.Name
5055+
}
5056+
return fmt.Sprintf("%v:%v", backend.Name, bPort)
5057+
}
5058+
48995059
// backendStringer behaves just like a string interface and converts the given backend to a string.
49005060
func backendStringer(backend *networkingv1beta1.IngressBackend) string {
49015061
if backend == nil {

0 commit comments

Comments
 (0)