func extractRouteInfo(route *routeapi.Route) (requested bool, other []string, errors []string) { reasons := sets.NewString() for _, ingress := range route.Status.Ingress { exact := route.Spec.Host == ingress.Host switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status { case kapi.ConditionFalse: reasons.Insert(condition.Reason) default: if exact { requested = true } else { other = append(other, ingress.Host) } } } return requested, other, reasons.List() }
// FindRouteAdmissionFailures creates markers for any routes that were rejected by their routers func FindRouteAdmissionFailures(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker { markers := []osgraph.Marker{} for _, uncastRouteNode := range g.NodesByKind(routegraph.RouteNodeKind) { routeNode := uncastRouteNode.(*routegraph.RouteNode) Route: for _, ingress := range routeNode.Status.Ingress { switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status { case kapi.ConditionFalse: markers = append(markers, osgraph.Marker{ Node: routeNode, Severity: osgraph.ErrorSeverity, Key: RouteNotAdmittedTypeErr, Message: fmt.Sprintf("%s was not accepted by router %q: %s (%s)", f.ResourceName(routeNode), ingress.RouterName, condition.Message, condition.Reason), }) break Route } } } return markers }
func printRoute(route *routeapi.Route, w io.Writer, opts kctl.PrintOptions) error { tlsTerm := "" insecurePolicy := "" if route.Spec.TLS != nil { tlsTerm = string(route.Spec.TLS.Termination) insecurePolicy = string(route.Spec.TLS.InsecureEdgeTerminationPolicy) } if opts.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", route.Namespace); err != nil { return err } } var ( matchedHost bool reason string host = route.Spec.Host admitted, errors = 0, 0 ) for _, ingress := range route.Status.Ingress { switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status { case kapi.ConditionTrue: admitted++ if !matchedHost { matchedHost = ingress.Host == route.Spec.Host host = ingress.Host } case kapi.ConditionFalse: reason = condition.Reason errors++ } } switch { case route.Status.Ingress == nil: // this is the legacy case, we should continue to show the host when talking to servers // that have not set status ingress, since we can't distinguish this condition from there // being no routers. case admitted == 0 && errors > 0: host = reason case errors > 0: host = fmt.Sprintf("%s ... %d rejected", host, errors) case admitted == 0: host = "Pending" case admitted > 1: host = fmt.Sprintf("%s ... %d more", host, admitted-1) } var policy string switch { case len(tlsTerm) != 0 && len(insecurePolicy) != 0: policy = fmt.Sprintf("%s/%s", tlsTerm, insecurePolicy) case len(tlsTerm) != 0: policy = tlsTerm case len(insecurePolicy) != 0: policy = fmt.Sprintf("default/%s", insecurePolicy) default: policy = "" } svc := route.Spec.To.Name if route.Spec.Port != nil { svc = fmt.Sprintf("%s:%s", svc, route.Spec.Port.TargetPort.String()) } if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", route.Name, host, route.Spec.Path, svc, policy, labels.Set(route.Labels)); err != nil { return err } return nil }
// Describe returns the description of a route func (d *RouteDescriber) Describe(namespace, name string, settings kctl.DescriberSettings) (string, error) { c := d.Routes(namespace) route, err := c.Get(name) if err != nil { return "", err } endpoints, endsErr := d.kubeClient.Endpoints(namespace).Get(route.Spec.To.Name) return tabbedString(func(out *tabwriter.Writer) error { formatMeta(out, route.ObjectMeta) if len(route.Spec.Host) > 0 { formatString(out, "Requested Host", route.Spec.Host) for _, ingress := range route.Status.Ingress { if route.Spec.Host != ingress.Host { continue } switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status { case kapi.ConditionTrue: fmt.Fprintf(out, "\t exposed on router %s %s ago\n", ingress.RouterName, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time))) case kapi.ConditionFalse: fmt.Fprintf(out, "\t rejected by router %s: %s (%s ago)\n", ingress.RouterName, condition.Reason, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time))) if len(condition.Message) > 0 { fmt.Fprintf(out, "\t %s\n", condition.Message) } } } } else { formatString(out, "Requested Host", "<auto>") } for _, ingress := range route.Status.Ingress { if route.Spec.Host == ingress.Host { continue } switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status { case kapi.ConditionTrue: fmt.Fprintf(out, "\t%s exposed on router %s %s ago\n", ingress.Host, ingress.RouterName, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time))) case kapi.ConditionFalse: fmt.Fprintf(out, "\trejected by router %s: %s (%s ago)\n", ingress.RouterName, condition.Reason, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time))) if len(condition.Message) > 0 { fmt.Fprintf(out, "\t %s\n", condition.Message) } } } formatString(out, "Path", route.Spec.Path) tlsTerm := "" insecurePolicy := "" if route.Spec.TLS != nil { tlsTerm = string(route.Spec.TLS.Termination) insecurePolicy = string(route.Spec.TLS.InsecureEdgeTerminationPolicy) } formatString(out, "TLS Termination", tlsTerm) formatString(out, "Insecure Policy", insecurePolicy) formatString(out, "Service", route.Spec.To.Name) if route.Spec.Port != nil { formatString(out, "Endpoint Port", route.Spec.Port.TargetPort.String()) } else { formatString(out, "Endpoint Port", "<all endpoint ports>") } ends := "<none>" if endsErr != nil { ends = fmt.Sprintf("Unable to get endpoints: %v", endsErr) } else if len(endpoints.Subsets) > 0 { list := []string{} max := 3 count := 0 for i := range endpoints.Subsets { ss := &endpoints.Subsets[i] for p := range ss.Ports { for a := range ss.Addresses { if len(list) < max { list = append(list, fmt.Sprintf("%s:%d", ss.Addresses[a].IP, ss.Ports[p].Port)) } count++ } } } ends = strings.Join(list, ", ") if count > max { ends += fmt.Sprintf(" + %d more...", count-max) } } formatString(out, "Endpoints", ends) return nil }) }
func printRoute(route *routeapi.Route, w io.Writer, opts kctl.PrintOptions) error { tlsTerm := "" insecurePolicy := "" if route.Spec.TLS != nil { tlsTerm = string(route.Spec.TLS.Termination) insecurePolicy = string(route.Spec.TLS.InsecureEdgeTerminationPolicy) } name := formatResourceName(opts.Kind, route.Name, opts.WithKind) if opts.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", route.Namespace); err != nil { return err } } var ( matchedHost bool reason string host = route.Spec.Host admitted, errors = 0, 0 ) for _, ingress := range route.Status.Ingress { switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status { case kapi.ConditionTrue: admitted++ if !matchedHost { matchedHost = ingress.Host == route.Spec.Host host = ingress.Host } case kapi.ConditionFalse: reason = condition.Reason errors++ } } switch { case route.Status.Ingress == nil: // this is the legacy case, we should continue to show the host when talking to servers // that have not set status ingress, since we can't distinguish this condition from there // being no routers. case admitted == 0 && errors > 0: host = reason case errors > 0: host = fmt.Sprintf("%s ... %d rejected", host, errors) case admitted == 0: host = "Pending" case admitted > 1: host = fmt.Sprintf("%s ... %d more", host, admitted-1) } var policy string switch { case len(tlsTerm) != 0 && len(insecurePolicy) != 0: policy = fmt.Sprintf("%s/%s", tlsTerm, insecurePolicy) case len(tlsTerm) != 0: policy = tlsTerm case len(insecurePolicy) != 0: policy = fmt.Sprintf("default/%s", insecurePolicy) default: policy = "" } backends := append([]routeapi.RouteTargetReference{route.Spec.To}, route.Spec.AlternateBackends...) totalWeight := int32(0) for _, backend := range backends { if backend.Weight != nil { totalWeight += *backend.Weight } } var backendInfo []string for _, backend := range backends { switch { case backend.Weight == nil, len(backends) == 1 && totalWeight != 0: backendInfo = append(backendInfo, backend.Name) case totalWeight == 0: backendInfo = append(backendInfo, fmt.Sprintf("%s(0%%)", backend.Name)) default: backendInfo = append(backendInfo, fmt.Sprintf("%s(%d%%)", backend.Name, *backend.Weight*100/totalWeight)) } } var port string if route.Spec.Port != nil { port = route.Spec.Port.TargetPort.String() } else { port = "<all>" } _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", name, host, route.Spec.Path, strings.Join(backendInfo, ","), port, policy) return err }