@@ -17,7 +17,7 @@ func discoverConnections(resources []common.Resource, links []common.Service) ([
17
17
connections := []common.Connections {}
18
18
for destResIdx := range resources {
19
19
destRes := & resources [destResIdx ]
20
- deploymentServices := findServices (destRes . Resource . Selectors , links )
20
+ deploymentServices := findServices (destRes , links )
21
21
for svcIdx := range deploymentServices {
22
22
svc := & deploymentServices [svcIdx ]
23
23
srcRes := findSource (resources , svc )
@@ -35,9 +35,10 @@ func discoverConnections(resources []common.Resource, links []common.Service) ([
35
35
}
36
36
37
37
// areSelectorsContained returns true if selectors2 is contained in selectors1
38
- func areSelectorsContained (selectors1 , selectors2 []string ) bool {
38
+ func areSelectorsContained (selectors1 map [ string ] string , selectors2 []string ) bool {
39
39
elementMap := make (map [string ]string )
40
- for _ , s := range selectors1 {
40
+ for k , v := range selectors1 {
41
+ s := fmt .Sprintf ("%s:%s" , k , v )
41
42
elementMap [s ] = ""
42
43
}
43
44
for _ , val := range selectors2 {
@@ -49,14 +50,16 @@ func areSelectorsContained(selectors1, selectors2 []string) bool {
49
50
return true
50
51
}
51
52
52
- // findServices returns a list of services that may be in front of a given deployment (represented by its selectors)
53
- func findServices (selectors [] string , links []common.Service ) []common.Service {
53
+ // findServices returns a list of services that may be in front of a given workload resource
54
+ func findServices (resource * common. Resource , links []common.Service ) []common.Service {
54
55
var matchedSvc []common.Service
55
- //TODO: refer to namespaces - the matching services and input deployment should be in the same namespace
56
56
for linkIdx := range links {
57
57
link := & links [linkIdx ]
58
+ if link .Resource .Namespace != resource .Resource .Namespace {
59
+ continue
60
+ }
58
61
// all service selector values should be contained in the input selectors of the deployment
59
- res := areSelectorsContained (selectors , link .Resource .Selectors )
62
+ res := areSelectorsContained (resource . Resource . Labels , link .Resource .Selectors )
60
63
if res {
61
64
matchedSvc = append (matchedSvc , * link )
62
65
}
@@ -72,22 +75,58 @@ func findServices(selectors []string, links []common.Service) []common.Service {
72
75
func findSource (resources []common.Resource , service * common.Service ) []* common.Resource {
73
76
tRes := []* common.Resource {}
74
77
for resIdx := range resources {
75
- res := & resources [resIdx ]
76
- for _ , envVal := range res .Resource .Envs {
77
- envVal = strings .TrimPrefix (envVal , "http://" )
78
- if service .Resource .Name == envVal { // A match without port name
79
- tRes = append (tRes , res )
80
- }
81
- for _ , p := range service .Resource .Network {
82
- serviceWithPort := fmt .Sprintf ("%s:%d" , service .Resource .Name , p .Port )
83
- if serviceWithPort == envVal {
84
- foundSrc := * res
85
- // specify the used ports for target by the found src
86
- foundSrc .Resource .UsedPorts = []int {p .Port }
87
- tRes = append (tRes , & foundSrc )
78
+ resource := & resources [resIdx ]
79
+ serviceAddresses := getPossibleServiceAddresses (service , resource )
80
+ foundSrc := * resource // We copy the resource so we can specify the ports used by the source found
81
+ matched := false
82
+ for _ , envVal := range resource .Resource .Envs {
83
+ match , port := envValueMatchesService (envVal , service , serviceAddresses )
84
+ if match {
85
+ matched = true
86
+ if port .Port > 0 {
87
+ foundSrc .Resource .UsedPorts = append (foundSrc .Resource .UsedPorts , port )
88
88
}
89
89
}
90
90
}
91
+ if matched {
92
+ tRes = append (tRes , & foundSrc )
93
+ }
91
94
}
92
95
return tRes
93
96
}
97
+
98
+ func getPossibleServiceAddresses (service * common.Service , resource * common.Resource ) []string {
99
+ svcAddresses := []string {}
100
+ if service .Resource .Namespace != "" {
101
+ serviceDotNamespace := fmt .Sprintf ("%s.%s" , service .Resource .Name , service .Resource .Namespace )
102
+ svcAddresses = append (svcAddresses , serviceDotNamespace , serviceDotNamespace + ".svc.cluster.local" )
103
+ }
104
+ if service .Resource .Namespace == resource .Resource .Namespace { // both service and resource live in the same namespace
105
+ svcAddresses = append (svcAddresses , service .Resource .Name )
106
+ }
107
+
108
+ return svcAddresses
109
+ }
110
+
111
+ func envValueMatchesService (envVal string , service * common.Service , serviceAddresses []string ) (bool , common.SvcNetworkAttr ) {
112
+ envVal = strings .TrimPrefix (envVal , "http://" )
113
+ envVal = strings .TrimPrefix (envVal , "https://" )
114
+
115
+ // first look for matches without specified port
116
+ for _ , svcAddress := range serviceAddresses {
117
+ if svcAddress == envVal {
118
+ return true , common.SvcNetworkAttr {} // this means no specified port
119
+ }
120
+ }
121
+
122
+ // Now look for matches that have port specified
123
+ for _ , p := range service .Resource .Network {
124
+ for _ , svcAddress := range serviceAddresses {
125
+ serviceWithPort := fmt .Sprintf ("%s:%d" , svcAddress , p .Port )
126
+ if envVal == serviceWithPort {
127
+ return true , p
128
+ }
129
+ }
130
+ }
131
+ return false , common.SvcNetworkAttr {}
132
+ }
0 commit comments