forked from LaconicNetwork/kompose
Upgrade OpenShift and its dependencies.
OpenShift version 1.4.0-alpha.0
This commit is contained in:
+228
@@ -0,0 +1,228 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gonum/graph"
|
||||
|
||||
kapi "k8s.io/kubernetes/pkg/api"
|
||||
|
||||
osgraph "github.com/openshift/origin/pkg/api/graph"
|
||||
kubegraph "github.com/openshift/origin/pkg/api/kubegraph/nodes"
|
||||
routeapi "github.com/openshift/origin/pkg/route/api"
|
||||
routeedges "github.com/openshift/origin/pkg/route/graph"
|
||||
routegraph "github.com/openshift/origin/pkg/route/graph/nodes"
|
||||
)
|
||||
|
||||
const (
|
||||
// MissingRoutePortWarning is returned when a route has no route port specified
|
||||
// and the service it routes to has multiple ports.
|
||||
MissingRoutePortWarning = "MissingRoutePort"
|
||||
// WrongRoutePortWarning is returned when a route has a route port specified
|
||||
// but the service it points to has no such port (either as a named port or as
|
||||
// a target port).
|
||||
WrongRoutePortWarning = "WrongRoutePort"
|
||||
// MissingServiceWarning is returned when there is no service for the specific route.
|
||||
MissingServiceWarning = "MissingService"
|
||||
// MissingTLSTerminationTypeErr is returned when a route with a tls config doesn't
|
||||
// specify a tls termination type.
|
||||
MissingTLSTerminationTypeErr = "MissingTLSTermination"
|
||||
// PathBasedPassthroughErr is returned when a path based route is passthrough
|
||||
// terminated.
|
||||
PathBasedPassthroughErr = "PathBasedPassthrough"
|
||||
// MissingTLSTerminationTypeErr is returned when a route with a tls config doesn't
|
||||
// specify a tls termination type.
|
||||
RouteNotAdmittedTypeErr = "RouteNotAdmitted"
|
||||
// MissingRequiredRouterErr is returned when no router has been setup.
|
||||
MissingRequiredRouterErr = "MissingRequiredRouter"
|
||||
)
|
||||
|
||||
// FindPortMappingIssues checks all routes and reports any issues related to their ports.
|
||||
// Also non-existent services for routes are reported here.
|
||||
func FindPortMappingIssues(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker {
|
||||
markers := []osgraph.Marker{}
|
||||
|
||||
for _, uncastRouteNode := range g.NodesByKind(routegraph.RouteNodeKind) {
|
||||
routeNode := uncastRouteNode.(*routegraph.RouteNode)
|
||||
marker := routePortMarker(g, f, routeNode)
|
||||
if marker != nil {
|
||||
markers = append(markers, *marker)
|
||||
}
|
||||
}
|
||||
|
||||
return markers
|
||||
}
|
||||
|
||||
func routePortMarker(g osgraph.Graph, f osgraph.Namer, routeNode *routegraph.RouteNode) *osgraph.Marker {
|
||||
for _, uncastServiceNode := range g.SuccessorNodesByEdgeKind(routeNode, routeedges.ExposedThroughRouteEdgeKind) {
|
||||
svcNode := uncastServiceNode.(*kubegraph.ServiceNode)
|
||||
|
||||
if !svcNode.Found() {
|
||||
return &osgraph.Marker{
|
||||
Node: routeNode,
|
||||
RelatedNodes: []graph.Node{svcNode},
|
||||
|
||||
Severity: osgraph.WarningSeverity,
|
||||
Key: MissingServiceWarning,
|
||||
Message: fmt.Sprintf("%s is supposed to route traffic to %s but %s doesn't exist.",
|
||||
f.ResourceName(routeNode), f.ResourceName(svcNode), f.ResourceName(svcNode)),
|
||||
// TODO: Suggest 'oc create service' once that's a thing.
|
||||
// See https://github.com/kubernetes/kubernetes/pull/19509
|
||||
}
|
||||
}
|
||||
|
||||
if len(svcNode.Spec.Ports) > 1 && (routeNode.Spec.Port == nil || len(routeNode.Spec.Port.TargetPort.String()) == 0) {
|
||||
return &osgraph.Marker{
|
||||
Node: routeNode,
|
||||
RelatedNodes: []graph.Node{svcNode},
|
||||
|
||||
Severity: osgraph.WarningSeverity,
|
||||
Key: MissingRoutePortWarning,
|
||||
Message: fmt.Sprintf("%s doesn't have a port specified and is routing traffic to %s which uses multiple ports.",
|
||||
f.ResourceName(routeNode), f.ResourceName(svcNode)),
|
||||
}
|
||||
}
|
||||
|
||||
if routeNode.Spec.Port == nil {
|
||||
// If no port is specified, we don't need to analyze any further.
|
||||
return nil
|
||||
}
|
||||
|
||||
routePortString := routeNode.Spec.Port.TargetPort.String()
|
||||
if routePort, err := strconv.Atoi(routePortString); err == nil {
|
||||
for _, port := range svcNode.Spec.Ports {
|
||||
if port.TargetPort.IntValue() == routePort {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// route has a numeric port, service has no port with that number as a targetPort.
|
||||
marker := &osgraph.Marker{
|
||||
Node: routeNode,
|
||||
RelatedNodes: []graph.Node{svcNode},
|
||||
|
||||
Severity: osgraph.WarningSeverity,
|
||||
Key: WrongRoutePortWarning,
|
||||
Message: fmt.Sprintf("%s has a port specified (%d) but %s has no such targetPort.",
|
||||
f.ResourceName(routeNode), routePort, f.ResourceName(svcNode)),
|
||||
}
|
||||
if len(svcNode.Spec.Ports) == 1 {
|
||||
marker.Suggestion = osgraph.Suggestion(fmt.Sprintf("oc patch %s -p '{\"spec\":{\"port\":{\"targetPort\": %d}}}'", f.ResourceName(routeNode), svcNode.Spec.Ports[0].TargetPort.IntValue()))
|
||||
}
|
||||
|
||||
return marker
|
||||
}
|
||||
|
||||
for _, port := range svcNode.Spec.Ports {
|
||||
if port.Name == routePortString {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// route has a named port, service has no port with that name.
|
||||
marker := &osgraph.Marker{
|
||||
Node: routeNode,
|
||||
RelatedNodes: []graph.Node{svcNode},
|
||||
|
||||
Severity: osgraph.WarningSeverity,
|
||||
Key: WrongRoutePortWarning,
|
||||
Message: fmt.Sprintf("%s has a named port specified (%q) but %s has no such named port.",
|
||||
f.ResourceName(routeNode), routePortString, f.ResourceName(svcNode)),
|
||||
}
|
||||
if len(svcNode.Spec.Ports) == 1 {
|
||||
marker.Suggestion = osgraph.Suggestion(fmt.Sprintf("oc patch %s -p '{\"spec\":{\"port\":{\"targetPort\": %d}}}'", f.ResourceName(routeNode), svcNode.Spec.Ports[0].TargetPort.IntValue()))
|
||||
}
|
||||
|
||||
return marker
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindMissingTLSTerminationType(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker {
|
||||
markers := []osgraph.Marker{}
|
||||
|
||||
for _, uncastRouteNode := range g.NodesByKind(routegraph.RouteNodeKind) {
|
||||
routeNode := uncastRouteNode.(*routegraph.RouteNode)
|
||||
|
||||
if routeNode.Spec.TLS != nil && len(routeNode.Spec.TLS.Termination) == 0 {
|
||||
markers = append(markers, osgraph.Marker{
|
||||
Node: routeNode,
|
||||
|
||||
Severity: osgraph.ErrorSeverity,
|
||||
Key: MissingTLSTerminationTypeErr,
|
||||
Message: fmt.Sprintf("%s has a TLS configuration but no termination type specified.", f.ResourceName(routeNode)),
|
||||
Suggestion: osgraph.Suggestion(fmt.Sprintf("oc patch %s -p '{\"spec\":{\"tls\":{\"termination\":\"<type>\"}}}' (replace <type> with a valid termination type: edge, passthrough, reencrypt)", f.ResourceName(routeNode)))})
|
||||
}
|
||||
}
|
||||
|
||||
return markers
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// FindMissingRouter creates markers for all routes in case there is no running router.
|
||||
func FindMissingRouter(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker {
|
||||
markers := []osgraph.Marker{}
|
||||
|
||||
for _, uncastRouteNode := range g.NodesByKind(routegraph.RouteNodeKind) {
|
||||
routeNode := uncastRouteNode.(*routegraph.RouteNode)
|
||||
|
||||
if len(routeNode.Route.Status.Ingress) == 0 {
|
||||
markers = append(markers, osgraph.Marker{
|
||||
Node: routeNode,
|
||||
|
||||
Severity: osgraph.ErrorSeverity,
|
||||
Key: MissingRequiredRouterErr,
|
||||
Message: fmt.Sprintf("%s is routing traffic to svc/%s, but either the administrator has not installed a router or the router is not selecting this route.", f.ResourceName(routeNode), routeNode.Spec.To.Name),
|
||||
Suggestion: osgraph.Suggestion("oc adm router -h"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return markers
|
||||
}
|
||||
|
||||
func FindPathBasedPassthroughRoutes(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker {
|
||||
markers := []osgraph.Marker{}
|
||||
|
||||
for _, uncastRouteNode := range g.NodesByKind(routegraph.RouteNodeKind) {
|
||||
routeNode := uncastRouteNode.(*routegraph.RouteNode)
|
||||
|
||||
if len(routeNode.Spec.Path) > 0 && routeNode.Spec.TLS != nil && routeNode.Spec.TLS.Termination == routeapi.TLSTerminationPassthrough {
|
||||
markers = append(markers, osgraph.Marker{
|
||||
Node: routeNode,
|
||||
|
||||
Severity: osgraph.ErrorSeverity,
|
||||
Key: PathBasedPassthroughErr,
|
||||
Message: fmt.Sprintf("%s is path-based and uses passthrough termination, which is an invalid combination.", f.ResourceName(routeNode)),
|
||||
Suggestion: osgraph.Suggestion(fmt.Sprintf("1. use spec.tls.termination=edge or 2. use spec.tls.termination=reencrypt and specify spec.tls.destinationCACertificate or 3. remove spec.path")),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return markers
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
// Package analysis provides functions that analyse routes and setup markers
|
||||
// that will be reported by oc status
|
||||
package analysis
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
// Package graph contains graph utilities for routes
|
||||
package graph
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package graph
|
||||
|
||||
import (
|
||||
"github.com/gonum/graph"
|
||||
|
||||
kapi "k8s.io/kubernetes/pkg/api"
|
||||
|
||||
osgraph "github.com/openshift/origin/pkg/api/graph"
|
||||
kubegraph "github.com/openshift/origin/pkg/api/kubegraph/nodes"
|
||||
routegraph "github.com/openshift/origin/pkg/route/graph/nodes"
|
||||
)
|
||||
|
||||
const (
|
||||
// ExposedThroughRouteEdgeKind is an edge from a route to any object that
|
||||
// is exposed through routes
|
||||
ExposedThroughRouteEdgeKind = "ExposedThroughRoute"
|
||||
)
|
||||
|
||||
// AddRouteEdges adds an edge that connect a service to a route in the given graph
|
||||
func AddRouteEdges(g osgraph.MutableUniqueGraph, node *routegraph.RouteNode) {
|
||||
syntheticService := &kapi.Service{}
|
||||
syntheticService.Namespace = node.Namespace
|
||||
syntheticService.Name = node.Spec.To.Name
|
||||
|
||||
serviceNode := kubegraph.FindOrCreateSyntheticServiceNode(g, syntheticService)
|
||||
g.AddEdge(node, serviceNode, ExposedThroughRouteEdgeKind)
|
||||
|
||||
for _, svc := range node.Spec.AlternateBackends {
|
||||
syntheticService := &kapi.Service{}
|
||||
syntheticService.Namespace = node.Namespace
|
||||
syntheticService.Name = svc.Name
|
||||
|
||||
serviceNode := kubegraph.FindOrCreateSyntheticServiceNode(g, syntheticService)
|
||||
g.AddEdge(node, serviceNode, ExposedThroughRouteEdgeKind)
|
||||
}
|
||||
}
|
||||
|
||||
// AddAllRouteEdges adds service edges to all route nodes in the given graph
|
||||
func AddAllRouteEdges(g osgraph.MutableUniqueGraph) {
|
||||
for _, node := range g.(graph.Graph).Nodes() {
|
||||
if routeNode, ok := node.(*routegraph.RouteNode); ok {
|
||||
AddRouteEdges(g, routeNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
// Package nodes contains graph functions and types for routes
|
||||
package nodes
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"github.com/gonum/graph"
|
||||
|
||||
osgraph "github.com/openshift/origin/pkg/api/graph"
|
||||
routeapi "github.com/openshift/origin/pkg/route/api"
|
||||
)
|
||||
|
||||
// EnsureRouteNode adds a graph node for the specific route if it does not exist
|
||||
func EnsureRouteNode(g osgraph.MutableUniqueGraph, route *routeapi.Route) *RouteNode {
|
||||
return osgraph.EnsureUnique(
|
||||
g,
|
||||
RouteNodeName(route),
|
||||
func(node osgraph.Node) graph.Node {
|
||||
return &RouteNode{
|
||||
Node: node,
|
||||
Route: route,
|
||||
}
|
||||
},
|
||||
).(*RouteNode)
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
osgraph "github.com/openshift/origin/pkg/api/graph"
|
||||
routeapi "github.com/openshift/origin/pkg/route/api"
|
||||
)
|
||||
|
||||
var (
|
||||
RouteNodeKind = reflect.TypeOf(routeapi.Route{}).Name()
|
||||
)
|
||||
|
||||
func RouteNodeName(o *routeapi.Route) osgraph.UniqueName {
|
||||
return osgraph.GetUniqueRuntimeObjectNodeName(RouteNodeKind, o)
|
||||
}
|
||||
|
||||
type RouteNode struct {
|
||||
osgraph.Node
|
||||
*routeapi.Route
|
||||
}
|
||||
|
||||
func (n RouteNode) Object() interface{} {
|
||||
return n.Route
|
||||
}
|
||||
|
||||
func (n RouteNode) String() string {
|
||||
return string(RouteNodeName(n.Route))
|
||||
}
|
||||
|
||||
func (*RouteNode) Kind() string {
|
||||
return RouteNodeKind
|
||||
}
|
||||
Reference in New Issue
Block a user