github.com/kiali/kiali@v1.84.0/graph/telemetry/istio/appender/workload_entry_test.go (about) 1 package appender_test 2 3 import ( 4 "sort" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1" 9 core_v1 "k8s.io/api/core/v1" 10 meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "k8s.io/apimachinery/pkg/runtime" 12 13 "github.com/kiali/kiali/business" 14 "github.com/kiali/kiali/config" 15 "github.com/kiali/kiali/graph" 16 "github.com/kiali/kiali/graph/telemetry/istio/appender" 17 "github.com/kiali/kiali/kubernetes" 18 "github.com/kiali/kiali/kubernetes/kubetest" 19 ) 20 21 const ( 22 testCluster = "defaultCluster" 23 appName = "ratings" 24 appNamespace = "testNamespace" 25 ) 26 27 func setupBusinessLayer(t *testing.T, istioObjects ...runtime.Object) *business.Layer { 28 k8s := kubetest.NewFakeK8sClient(istioObjects...) 29 conf := config.NewConfig() 30 conf.KubernetesConfig.ClusterName = testCluster 31 conf.ExternalServices.Istio.IstioAPIEnabled = false 32 config.Set(conf) 33 34 business.SetupBusinessLayer(t, k8s, *conf) 35 k8sclients := make(map[string]kubernetes.ClientInterface) 36 k8sclients[conf.KubernetesConfig.ClusterName] = k8s 37 businessLayer := business.NewWithBackends(k8sclients, k8sclients, nil, nil) 38 return businessLayer 39 } 40 41 func setupWorkloadEntries(t *testing.T) *business.Layer { 42 workloadV1 := &networking_v1beta1.WorkloadEntry{} 43 workloadV1.Name = "workloadA" 44 workloadV1.Namespace = appNamespace 45 workloadV1.Spec.Labels = map[string]string{ 46 "app": appName, 47 "version": "v1", 48 } 49 workloadV2 := &networking_v1beta1.WorkloadEntry{} 50 workloadV2.Name = "workloadB" 51 workloadV2.Namespace = appNamespace 52 workloadV2.Spec.Labels = map[string]string{ 53 "app": appName, 54 "version": "v2", 55 } 56 ns := &core_v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: appNamespace}} 57 return setupBusinessLayer(t, workloadV1, workloadV2, ns) 58 } 59 60 func workloadEntriesTrafficMap() map[string]*graph.Node { 61 // VersionedApp graph 62 trafficMap := make(map[string]*graph.Node) 63 64 // 1 service, 3 workloads. v1 and v2 are workload entries. v3 is not a workload entry e.g. a kube deployment. 65 66 // Service node 67 n0, _ := graph.NewNode(testCluster, appNamespace, appName, appNamespace, "", "", "", graph.GraphTypeVersionedApp) 68 69 // v1 Workload 70 n1, _ := graph.NewNode(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 71 72 // v2 Workload 73 n2, _ := graph.NewNode(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 74 75 // v3 Workload 76 n3, _ := graph.NewNode(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 77 78 // v4 Workload (just to test ignoring of outsider nodes) 79 n4, _ := graph.NewNode(testCluster, "outsider", "outsider", "outsider", "outsider-v1", "outsider", "v1", graph.GraphTypeVersionedApp) 80 81 trafficMap[n0.ID] = n0 82 trafficMap[n1.ID] = n1 83 trafficMap[n2.ID] = n2 84 trafficMap[n3.ID] = n3 85 trafficMap[n4.ID] = n4 86 87 n0.AddEdge(n1).Metadata[graph.ProtocolKey] = graph.HTTP.Name 88 n0.AddEdge(n2).Metadata[graph.ProtocolKey] = graph.HTTP.Name 89 n0.AddEdge(n3).Metadata[graph.ProtocolKey] = graph.HTTP.Name 90 n0.AddEdge(n4).Metadata[graph.ProtocolKey] = graph.HTTP.Name 91 // Need to put some metadata in here to ensure it gets counted as a workload 92 93 return trafficMap 94 } 95 96 func TestWorkloadEntry(t *testing.T) { 97 assert := require.New(t) 98 99 businessLayer := setupWorkloadEntries(t) 100 trafficMap := workloadEntriesTrafficMap() 101 102 assert.Equal(5, len(trafficMap)) 103 104 seSVCID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "", "", "", graph.GraphTypeVersionedApp) 105 seSVCNode, found := trafficMap[seSVCID] 106 assert.True(found) 107 assert.Equal(4, len(seSVCNode.Edges)) 108 109 v1WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 110 v1Node, found := trafficMap[v1WorkloadID] 111 assert.True(found) 112 assert.NotContains(v1Node.Metadata, graph.HasWorkloadEntry) 113 114 v2WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 115 v2Node, found := trafficMap[v2WorkloadID] 116 assert.True(found) 117 assert.NotContains(v2Node.Metadata, graph.HasWorkloadEntry) 118 119 v3WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 120 v3Node, found := trafficMap[v3WorkloadID] 121 assert.True(found) 122 assert.NotContains(v3Node.Metadata, graph.HasWorkloadEntry) 123 124 v4WorkloadID, _, _ := graph.Id(testCluster, "outsider", "outsider", "outsider", "outsider-v1", "outsider", "v1", graph.GraphTypeVersionedApp) 125 v4Node, found := trafficMap[v4WorkloadID] 126 assert.True(found) 127 assert.NotContains(v4Node.Metadata, graph.HasWorkloadEntry) 128 129 globalInfo := graph.NewAppenderGlobalInfo() 130 globalInfo.Business = businessLayer 131 namespaceInfo := graph.NewAppenderNamespaceInfo(appNamespace) 132 133 // Run the appender... 134 a := appender.WorkloadEntryAppender{} 135 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 136 137 assert.Equal(5, len(trafficMap)) 138 139 workloadV1ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 140 workloadV1Node, found := trafficMap[workloadV1ID] 141 assert.True(found) 142 assert.Equal(workloadV1Node.Metadata[graph.HasWorkloadEntry], []graph.WEInfo{{Name: "workloadA"}}) 143 144 workloadV2ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 145 workloadV2Node, found := trafficMap[workloadV2ID] 146 assert.True(found) 147 assert.Equal(workloadV2Node.Metadata[graph.HasWorkloadEntry], []graph.WEInfo{{Name: "workloadB"}}) 148 149 workloadV3ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 150 workloadV3Node, found := trafficMap[workloadV3ID] 151 assert.True(found) 152 assert.NotContains(workloadV3Node.Metadata, graph.HasWorkloadEntry) 153 } 154 155 func TestWorkloadEntryAppLabelNotMatching(t *testing.T) { 156 assert := require.New(t) 157 158 workloadV1 := &networking_v1beta1.WorkloadEntry{} 159 workloadV1.Name = "workloadA" 160 workloadV1.Namespace = appNamespace 161 workloadV1.Spec.Labels = map[string]string{ 162 "app": "pastamaker", 163 "version": "v1", 164 } 165 166 workloadV2 := &networking_v1beta1.WorkloadEntry{} 167 workloadV2.Name = "workloadB" 168 workloadV2.Namespace = appNamespace 169 workloadV2.Spec.Labels = map[string]string{ 170 "app": "pastamaker", 171 "version": "v2", 172 } 173 174 ns := &core_v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: appNamespace}} 175 businessLayer := setupBusinessLayer(t, workloadV1, workloadV2, ns) 176 trafficMap := workloadEntriesTrafficMap() 177 178 assert.Equal(5, len(trafficMap)) 179 180 seSVCID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "", "", "", graph.GraphTypeVersionedApp) 181 seSVCNode, found := trafficMap[seSVCID] 182 assert.True(found) 183 assert.Equal(4, len(seSVCNode.Edges)) 184 185 v1WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 186 v1Node, found := trafficMap[v1WorkloadID] 187 assert.True(found) 188 assert.NotContains(v1Node.Metadata, graph.HasWorkloadEntry) 189 190 v2WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 191 v2Node, found := trafficMap[v2WorkloadID] 192 assert.True(found) 193 assert.NotContains(v2Node.Metadata, graph.HasWorkloadEntry) 194 195 v3WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 196 v3Node, found := trafficMap[v3WorkloadID] 197 assert.True(found) 198 assert.NotContains(v3Node.Metadata, graph.HasWorkloadEntry) 199 200 globalInfo := graph.NewAppenderGlobalInfo() 201 globalInfo.Business = businessLayer 202 namespaceInfo := graph.NewAppenderNamespaceInfo(appNamespace) 203 204 // Run the appender... 205 a := appender.WorkloadEntryAppender{} 206 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 207 208 assert.Equal(5, len(trafficMap)) 209 210 workloadV1ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 211 workloadV1Node, found := trafficMap[workloadV1ID] 212 assert.True(found) 213 assert.NotContains(workloadV1Node.Metadata, graph.HasWorkloadEntry) 214 215 workloadV2ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 216 workloadV2Node, found := trafficMap[workloadV2ID] 217 assert.True(found) 218 assert.NotContains(workloadV2Node.Metadata, graph.HasWorkloadEntry) 219 220 workloadV3ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 221 workloadV3Node, found := trafficMap[workloadV3ID] 222 assert.True(found) 223 assert.NotContains(workloadV3Node.Metadata, graph.HasWorkloadEntry) 224 } 225 226 func TestMultipleWorkloadEntryForSameWorkload(t *testing.T) { 227 assert := require.New(t) 228 229 workloadV1A := &networking_v1beta1.WorkloadEntry{} 230 workloadV1A.Name = "workloadV1A" 231 workloadV1A.Namespace = appNamespace 232 workloadV1A.Spec.Labels = map[string]string{ 233 "app": appName, 234 "version": "v1", 235 } 236 237 workloadV1B := &networking_v1beta1.WorkloadEntry{} 238 workloadV1B.Name = "workloadV1B" 239 workloadV1B.Namespace = appNamespace 240 workloadV1B.Spec.Labels = map[string]string{ 241 "app": appName, 242 "version": "v1", 243 } 244 245 workloadV2 := &networking_v1beta1.WorkloadEntry{} 246 workloadV2.Name = "workloadV2" 247 workloadV2.Namespace = appNamespace 248 workloadV2.Spec.Labels = map[string]string{ 249 "app": appName, 250 "version": "v2", 251 } 252 253 ns := &core_v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: appNamespace}} 254 businessLayer := setupBusinessLayer(t, workloadV1A, workloadV1B, workloadV2, ns) 255 trafficMap := workloadEntriesTrafficMap() 256 257 assert.Equal(5, len(trafficMap)) 258 259 seSVCID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "", "", "", graph.GraphTypeVersionedApp) 260 seSVCNode, found := trafficMap[seSVCID] 261 assert.True(found) 262 assert.Equal(4, len(seSVCNode.Edges)) 263 264 v1WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 265 v1Node, found := trafficMap[v1WorkloadID] 266 assert.True(found) 267 assert.NotContains(v1Node.Metadata, graph.HasWorkloadEntry) 268 269 v2WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 270 v2Node, found := trafficMap[v2WorkloadID] 271 assert.True(found) 272 assert.NotContains(v2Node.Metadata, graph.HasWorkloadEntry) 273 274 v3WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 275 v3Node, found := trafficMap[v3WorkloadID] 276 assert.True(found) 277 assert.NotContains(v3Node.Metadata, graph.HasWorkloadEntry) 278 279 globalInfo := graph.NewAppenderGlobalInfo() 280 globalInfo.Business = businessLayer 281 namespaceInfo := graph.NewAppenderNamespaceInfo(appNamespace) 282 283 // Run the appender... 284 a := appender.WorkloadEntryAppender{} 285 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 286 287 assert.Equal(5, len(trafficMap)) 288 289 workloadV1ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 290 workloadV1Node, found := trafficMap[workloadV1ID] 291 assert.True(found) 292 res := workloadV1Node.Metadata[graph.HasWorkloadEntry].([]graph.WEInfo) 293 sort.Slice(res, func(i, j int) bool { 294 return res[i].Name < res[j].Name 295 }) 296 assert.Equal( 297 []graph.WEInfo{{Name: "workloadV1A"}, {Name: "workloadV1B"}}, 298 res, 299 ) 300 301 workloadV2ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 302 workloadV2Node, found := trafficMap[workloadV2ID] 303 assert.True(found) 304 assert.Equal(workloadV2Node.Metadata[graph.HasWorkloadEntry], []graph.WEInfo{{Name: "workloadV2"}}) 305 306 workloadV3ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 307 workloadV3Node, found := trafficMap[workloadV3ID] 308 assert.True(found) 309 assert.NotContains(workloadV3Node.Metadata, graph.HasWorkloadEntry) 310 } 311 312 func TestWorkloadWithoutWorkloadEntries(t *testing.T) { 313 assert := require.New(t) 314 315 businessLayer := setupBusinessLayer(t, &core_v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: appNamespace}}) 316 trafficMap := workloadEntriesTrafficMap() 317 318 assert.Equal(5, len(trafficMap)) 319 320 seSVCID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "", "", "", graph.GraphTypeVersionedApp) 321 seSVCNode, found := trafficMap[seSVCID] 322 assert.True(found) 323 assert.Equal(4, len(seSVCNode.Edges)) 324 325 v1WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 326 v1Node, found := trafficMap[v1WorkloadID] 327 assert.True(found) 328 assert.NotContains(v1Node.Metadata, graph.HasWorkloadEntry) 329 330 v2WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 331 v2Node, found := trafficMap[v2WorkloadID] 332 assert.True(found) 333 assert.NotContains(v2Node.Metadata, graph.HasWorkloadEntry) 334 335 v3WorkloadID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 336 v3Node, found := trafficMap[v3WorkloadID] 337 assert.True(found) 338 assert.NotContains(v3Node.Metadata, graph.HasWorkloadEntry) 339 340 globalInfo := graph.NewAppenderGlobalInfo() 341 globalInfo.Business = businessLayer 342 namespaceInfo := graph.NewAppenderNamespaceInfo(appNamespace) 343 344 // Run the appender... 345 a := appender.WorkloadEntryAppender{} 346 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 347 348 assert.Equal(5, len(trafficMap)) 349 350 workloadV1ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v1", appName, "v1", graph.GraphTypeVersionedApp) 351 workloadV1Node, found := trafficMap[workloadV1ID] 352 assert.True(found) 353 assert.NotContains(workloadV1Node.Metadata, graph.HasWorkloadEntry) 354 355 workloadV2ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v2", appName, "v2", graph.GraphTypeVersionedApp) 356 workloadV2Node, found := trafficMap[workloadV2ID] 357 assert.True(found) 358 assert.NotContains(workloadV2Node.Metadata, graph.HasWorkloadEntry) 359 360 workloadV3ID, _, _ := graph.Id(testCluster, appNamespace, appName, appNamespace, "ratings-v3", appName, "v3", graph.GraphTypeVersionedApp) 361 workloadV3Node, found := trafficMap[workloadV3ID] 362 assert.True(found) 363 assert.NotContains(workloadV3Node.Metadata, graph.HasWorkloadEntry) 364 }