@@ -11,6 +11,7 @@ import (
11
11
kapierrors "k8s.io/apimachinery/pkg/api/errors"
12
12
"k8s.io/apimachinery/pkg/api/meta"
13
13
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14
+ "k8s.io/apimachinery/pkg/labels"
14
15
utilerrors "k8s.io/apimachinery/pkg/util/errors"
15
16
"k8s.io/apimachinery/pkg/util/sets"
16
17
kapps "k8s.io/kubernetes/pkg/apis/apps"
@@ -164,6 +165,22 @@ func (d *ProjectStatusDescriber) MakeGraph(namespace string) (osgraph.Graph, set
164
165
return g , forbiddenResources , nil
165
166
}
166
167
168
+ // createSelector receives a map of strings and
169
+ // converts it into a labels.Selector
170
+ func createSelector (values map [string ]string ) labels.Selector {
171
+ selector := labels .NewSelector ()
172
+ for k , v := range values {
173
+ req , err := labels .NewRequirement (k , "=" , []string {v })
174
+ if err != nil {
175
+ continue
176
+ }
177
+
178
+ selector = selector .Add (* req )
179
+ }
180
+
181
+ return selector
182
+ }
183
+
167
184
// Describe returns the description of a project
168
185
func (d * ProjectStatusDescriber ) Describe (namespace , name string ) (string , error ) {
169
186
var f formatter = namespacedFormatter {}
@@ -195,9 +212,25 @@ func (d *ProjectStatusDescriber) Describe(namespace, name string) (string, error
195
212
196
213
coveredNodes := graphview.IntSet {}
197
214
198
- services , coveredByServices := graphview .AllServiceGroups (g , coveredNodes )
215
+ allServices , coveredByServices := graphview .AllServiceGroups (g , coveredNodes )
199
216
coveredNodes .Insert (coveredByServices .List ()... )
200
217
218
+ // services grouped by selector
219
+ servicesBySelector := map [string ][]graphview.ServiceGroup {}
220
+ services := []graphview.ServiceGroup {}
221
+
222
+ // group services with identical selectors
223
+ for _ , svc := range allServices {
224
+ selector := createSelector (svc .Service .Spec .Selector )
225
+ if _ , seen := servicesBySelector [selector .String ()]; seen {
226
+ servicesBySelector [selector .String ()] = append (servicesBySelector [selector .String ()], svc )
227
+ continue
228
+ }
229
+
230
+ services = append (services , svc )
231
+ servicesBySelector [selector .String ()] = []graphview.ServiceGroup {}
232
+ }
233
+
201
234
standaloneDCs , coveredByDCs := graphview .AllDeploymentConfigPipelines (g , coveredNodes )
202
235
coveredNodes .Insert (coveredByDCs .List ()... )
203
236
@@ -243,6 +276,26 @@ func (d *ProjectStatusDescriber) Describe(namespace, name string) (string, error
243
276
sort .Sort (exposedRoutes (exposes ))
244
277
245
278
fmt .Fprintln (out )
279
+
280
+ // print services that should be grouped with this service based on matching selectors
281
+ selector := createSelector (service .Service .Spec .Selector )
282
+ groupedServices := servicesBySelector [selector .String ()]
283
+ for _ , groupedSvc := range groupedServices {
284
+ if ! groupedSvc .Service .Found () {
285
+ continue
286
+ }
287
+
288
+ grouppedLocal := namespacedFormatter {currentNamespace : service .Service .Namespace }
289
+
290
+ var grouppedExposes []string
291
+ for _ , routeNode := range groupedSvc .ExposingRoutes {
292
+ grouppedExposes = append (grouppedExposes , describeRouteInServiceGroup (grouppedLocal , routeNode )... )
293
+ }
294
+ sort .Sort (exposedRoutes (grouppedExposes ))
295
+
296
+ printLines (out , "" , 0 , describeServiceInServiceGroup (f , groupedSvc , grouppedExposes ... )... )
297
+ }
298
+
246
299
printLines (out , "" , 0 , describeServiceInServiceGroup (f , service , exposes ... )... )
247
300
248
301
for _ , dcPipeline := range service .DeploymentConfigPipelines {
0 commit comments