forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
service_group.go
134 lines (106 loc) · 4.67 KB
/
service_group.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package graphview
import (
"fmt"
"sort"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
osgraph "github.com/openshift/origin/pkg/api/graph"
kubeedges "github.com/openshift/origin/pkg/api/kubegraph"
kubegraph "github.com/openshift/origin/pkg/api/kubegraph/nodes"
deploygraph "github.com/openshift/origin/pkg/deploy/graph/nodes"
routeedges "github.com/openshift/origin/pkg/route/graph"
routegraph "github.com/openshift/origin/pkg/route/graph/nodes"
)
// ServiceGroup is a service, the DeploymentConfigPipelines it covers, and lists of the other nodes that fulfill it
type ServiceGroup struct {
Service *kubegraph.ServiceNode
DeploymentConfigPipelines []DeploymentConfigPipeline
ReplicationControllers []ReplicationController
StatefulSets []StatefulSet
// TODO: this has to stop
FulfillingStatefulSets []*kubegraph.StatefulSetNode
FulfillingDCs []*deploygraph.DeploymentConfigNode
FulfillingRCs []*kubegraph.ReplicationControllerNode
FulfillingPods []*kubegraph.PodNode
ExposingRoutes []*routegraph.RouteNode
}
// AllServiceGroups returns all the ServiceGroups that aren't in the excludes set and the set of covered NodeIDs
func AllServiceGroups(g osgraph.Graph, excludeNodeIDs IntSet) ([]ServiceGroup, IntSet) {
covered := IntSet{}
services := []ServiceGroup{}
for _, uncastNode := range g.NodesByKind(kubegraph.ServiceNodeKind) {
if excludeNodeIDs.Has(uncastNode.ID()) {
continue
}
service, covers := NewServiceGroup(g, uncastNode.(*kubegraph.ServiceNode))
covered.Insert(covers.List()...)
services = append(services, service)
}
sort.Sort(ServiceGroupByObjectMeta(services))
return services, covered
}
// NewServiceGroup returns the ServiceGroup and a set of all the NodeIDs covered by the service
func NewServiceGroup(g osgraph.Graph, serviceNode *kubegraph.ServiceNode) (ServiceGroup, IntSet) {
covered := IntSet{}
covered.Insert(serviceNode.ID())
service := ServiceGroup{}
service.Service = serviceNode
for _, uncastServiceFulfiller := range g.PredecessorNodesByEdgeKind(serviceNode, kubeedges.ExposedThroughServiceEdgeKind) {
container := osgraph.GetTopLevelContainerNode(g, uncastServiceFulfiller)
switch castContainer := container.(type) {
case *deploygraph.DeploymentConfigNode:
service.FulfillingDCs = append(service.FulfillingDCs, castContainer)
case *kubegraph.ReplicationControllerNode:
service.FulfillingRCs = append(service.FulfillingRCs, castContainer)
case *kubegraph.PodNode:
service.FulfillingPods = append(service.FulfillingPods, castContainer)
case *kubegraph.StatefulSetNode:
service.FulfillingStatefulSets = append(service.FulfillingStatefulSets, castContainer)
default:
utilruntime.HandleError(fmt.Errorf("unrecognized container: %v", castContainer))
}
}
for _, uncastServiceFulfiller := range g.PredecessorNodesByEdgeKind(serviceNode, routeedges.ExposedThroughRouteEdgeKind) {
container := osgraph.GetTopLevelContainerNode(g, uncastServiceFulfiller)
switch castContainer := container.(type) {
case *routegraph.RouteNode:
service.ExposingRoutes = append(service.ExposingRoutes, castContainer)
default:
utilruntime.HandleError(fmt.Errorf("unrecognized container: %v", castContainer))
}
}
// add the DCPipelines for all the DCs that fulfill the service
for _, fulfillingDC := range service.FulfillingDCs {
dcPipeline, dcCovers := NewDeploymentConfigPipeline(g, fulfillingDC)
covered.Insert(dcCovers.List()...)
service.DeploymentConfigPipelines = append(service.DeploymentConfigPipelines, dcPipeline)
}
for _, fulfillingRC := range service.FulfillingRCs {
rcView, rcCovers := NewReplicationController(g, fulfillingRC)
covered.Insert(rcCovers.List()...)
service.ReplicationControllers = append(service.ReplicationControllers, rcView)
}
for _, fulfillingStatefulSet := range service.FulfillingStatefulSets {
view, covers := NewStatefulSet(g, fulfillingStatefulSet)
covered.Insert(covers.List()...)
service.StatefulSets = append(service.StatefulSets, view)
}
for _, fulfillingPod := range service.FulfillingPods {
_, podCovers := NewPod(g, fulfillingPod)
covered.Insert(podCovers.List()...)
}
return service, covered
}
type ServiceGroupByObjectMeta []ServiceGroup
func (m ServiceGroupByObjectMeta) Len() int { return len(m) }
func (m ServiceGroupByObjectMeta) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (m ServiceGroupByObjectMeta) Less(i, j int) bool {
a, b := m[i], m[j]
return CompareObjectMeta(&a.Service.Service.ObjectMeta, &b.Service.Service.ObjectMeta)
}
func CompareObjectMeta(a, b *metav1.ObjectMeta) bool {
if a.Namespace == b.Namespace {
return a.Name < b.Name
}
return a.Namespace < b.Namespace
}