github.com/kiali/kiali@v1.84.0/graph/telemetry/istio/appender/mesh_check_test.go (about) 1 package appender 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/stretchr/testify/assert" 8 apps_v1 "k8s.io/api/apps/v1" 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/kubernetes" 17 "github.com/kiali/kiali/kubernetes/kubetest" 18 ) 19 20 func TestWorkloadSidecarsPasses(t *testing.T) { 21 trafficMap := buildWorkloadTrafficMap() 22 businessLayer := setupSidecarsCheckWorkloads(t, buildFakeWorkloadDeployments(), buildFakeWorkloadPods()) 23 24 globalInfo := graph.NewAppenderGlobalInfo() 25 globalInfo.Business = businessLayer 26 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 27 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 28 29 a := MeshCheckAppender{ 30 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 31 key: &graph.AccessibleNamespace{ 32 Cluster: config.DefaultClusterID, 33 CreationTimestamp: time.Now(), 34 Name: "testNamespace", 35 }}} 36 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 37 38 for _, node := range trafficMap { 39 _, ok := node.Metadata[graph.IsOutOfMesh].(bool) 40 assert.False(t, ok) 41 } 42 } 43 44 func TestWorkloadWithMissingSidecarsIsFlagged(t *testing.T) { 45 trafficMap := buildWorkloadTrafficMap() 46 businessLayer := setupSidecarsCheckWorkloads(t, buildFakeWorkloadDeployments(), buildFakeWorkloadPodsNoSidecar()) 47 48 globalInfo := graph.NewAppenderGlobalInfo() 49 globalInfo.Business = businessLayer 50 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 51 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 52 53 a := MeshCheckAppender{ 54 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 55 key: &graph.AccessibleNamespace{ 56 Cluster: config.DefaultClusterID, 57 CreationTimestamp: time.Now(), 58 Name: "testNamespace", 59 }}} 60 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 61 62 for _, node := range trafficMap { 63 flag, ok := node.Metadata[graph.IsOutOfMesh].(bool) 64 assert.True(t, ok) 65 assert.True(t, flag) 66 } 67 } 68 69 func TestInaccessibleWorkload(t *testing.T) { 70 trafficMap := buildInaccessibleWorkloadTrafficMap() 71 businessLayer := setupSidecarsCheckWorkloads(t, buildFakeWorkloadDeployments(), buildFakeWorkloadPodsNoSidecar()) 72 73 globalInfo := graph.NewAppenderGlobalInfo() 74 globalInfo.Business = businessLayer 75 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 76 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 77 78 a := MeshCheckAppender{ 79 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 80 key: &graph.AccessibleNamespace{ 81 Cluster: config.DefaultClusterID, 82 CreationTimestamp: time.Now(), 83 Name: "testNamespace", 84 }}} 85 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 86 87 for _, node := range trafficMap { 88 _, ok := node.Metadata[graph.IsOutOfMesh].(bool) 89 assert.False(t, ok) 90 } 91 } 92 93 func TestAppNoPodsPasses(t *testing.T) { 94 trafficMap := buildAppTrafficMap() 95 businessLayer := setupSidecarsCheckWorkloads(t, []apps_v1.Deployment{}, []core_v1.Pod{}) 96 97 globalInfo := graph.NewAppenderGlobalInfo() 98 globalInfo.Business = businessLayer 99 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 100 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 101 102 a := MeshCheckAppender{ 103 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 104 key: &graph.AccessibleNamespace{ 105 Cluster: config.DefaultClusterID, 106 CreationTimestamp: time.Now(), 107 Name: "testNamespace", 108 }}} 109 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 110 111 for _, node := range trafficMap { 112 _, ok := node.Metadata[graph.IsOutOfMesh].(bool) 113 assert.False(t, ok) 114 } 115 } 116 117 func TestAppSidecarsPasses(t *testing.T) { 118 trafficMap := buildAppTrafficMap() 119 businessLayer := setupSidecarsCheckWorkloads(t, []apps_v1.Deployment{}, buildFakeWorkloadPods()) 120 121 globalInfo := graph.NewAppenderGlobalInfo() 122 globalInfo.Business = businessLayer 123 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 124 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 125 126 a := MeshCheckAppender{ 127 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 128 key: &graph.AccessibleNamespace{ 129 Cluster: config.DefaultClusterID, 130 CreationTimestamp: time.Now(), 131 Name: "testNamespace", 132 }}} 133 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 134 135 for _, node := range trafficMap { 136 _, ok := node.Metadata[graph.IsOutOfMesh].(bool) 137 assert.False(t, ok) 138 } 139 } 140 141 func TestAppWithMissingSidecarsIsFlagged(t *testing.T) { 142 trafficMap := buildAppTrafficMap() 143 businessLayer := setupSidecarsCheckWorkloads(t, []apps_v1.Deployment{}, buildFakeWorkloadPodsNoSidecar()) 144 145 globalInfo := graph.NewAppenderGlobalInfo() 146 globalInfo.Business = businessLayer 147 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 148 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 149 150 a := MeshCheckAppender{ 151 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 152 key: &graph.AccessibleNamespace{ 153 Cluster: config.DefaultClusterID, 154 CreationTimestamp: time.Now(), 155 Name: "testNamespace", 156 }}} 157 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 158 159 for _, node := range trafficMap { 160 flag, ok := node.Metadata[graph.IsOutOfMesh].(bool) 161 assert.True(t, ok) 162 assert.True(t, flag) 163 } 164 } 165 166 func TestAppWithAmbientIsFlagged(t *testing.T) { 167 trafficMap := buildAppTrafficMap() 168 businessLayer := setupSidecarsCheckWorkloads(t, []apps_v1.Deployment{}, buildFakeWorkloadPodsAmbient()) 169 170 globalInfo := graph.NewAppenderGlobalInfo() 171 globalInfo.Business = businessLayer 172 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 173 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 174 175 a := MeshCheckAppender{ 176 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 177 key: &graph.AccessibleNamespace{ 178 Cluster: config.DefaultClusterID, 179 CreationTimestamp: time.Now(), 180 Name: "testNamespace", 181 }}} 182 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 183 184 for _, node := range trafficMap { 185 flag, ok := node.Metadata[graph.IsOutOfMesh].(bool) 186 assert.False(t, ok) 187 assert.False(t, flag) 188 } 189 } 190 191 func TestServicesAreAlwaysValid(t *testing.T) { 192 trafficMap := buildServiceTrafficMap() 193 businessLayer := setupSidecarsCheckWorkloads(t, []apps_v1.Deployment{}, []core_v1.Pod{}) 194 195 globalInfo := graph.NewAppenderGlobalInfo() 196 globalInfo.Business = businessLayer 197 namespaceInfo := graph.NewAppenderNamespaceInfo("testNamespace") 198 key := graph.GetClusterSensitiveKey(config.DefaultClusterID, "testNamespace") 199 200 a := MeshCheckAppender{ 201 AccessibleNamespaces: map[graph.ClusterSensitiveKey]*graph.AccessibleNamespace{ 202 key: &graph.AccessibleNamespace{ 203 Cluster: config.DefaultClusterID, 204 CreationTimestamp: time.Now(), 205 Name: "testNamespace", 206 }}} 207 a.AppendGraph(trafficMap, globalInfo, namespaceInfo) 208 209 for _, node := range trafficMap { 210 _, ok := node.Metadata[graph.IsOutOfMesh].(bool) 211 assert.False(t, ok) 212 } 213 } 214 215 func buildWorkloadTrafficMap() graph.TrafficMap { 216 trafficMap := graph.NewTrafficMap() 217 conf := config.NewConfig() 218 conf.KubernetesConfig.ClusterName = config.DefaultClusterID 219 config.Set(conf) 220 node, _ := graph.NewNode(conf.KubernetesConfig.ClusterName, "testNamespace", "", "testNamespace", "workload-1", graph.Unknown, graph.Unknown, graph.GraphTypeWorkload) 221 trafficMap[node.ID] = node 222 223 return trafficMap 224 } 225 226 func buildInaccessibleWorkloadTrafficMap() graph.TrafficMap { 227 trafficMap := graph.NewTrafficMap() 228 conf := config.NewConfig() 229 conf.KubernetesConfig.ClusterName = config.DefaultClusterID 230 config.Set(conf) 231 node, _ := graph.NewNode(conf.KubernetesConfig.ClusterName, "inaccessibleNamespace", "", "inaccessibleNamespace", "workload-1", graph.Unknown, graph.Unknown, graph.GraphTypeVersionedApp) 232 trafficMap[node.ID] = node 233 234 return trafficMap 235 } 236 237 func buildAppTrafficMap() graph.TrafficMap { 238 trafficMap := graph.NewTrafficMap() 239 conf := config.NewConfig() 240 conf.KubernetesConfig.ClusterName = config.DefaultClusterID 241 config.Set(conf) 242 node, _ := graph.NewNode(conf.KubernetesConfig.ClusterName, "testNamespace", "", "testNamespace", graph.Unknown, "myTest", graph.Unknown, graph.GraphTypeVersionedApp) 243 trafficMap[node.ID] = node 244 245 return trafficMap 246 } 247 248 func buildServiceTrafficMap() graph.TrafficMap { 249 trafficMap := graph.NewTrafficMap() 250 conf := config.NewConfig() 251 conf.KubernetesConfig.ClusterName = config.DefaultClusterID 252 config.Set(conf) 253 node, _ := graph.NewNode(conf.KubernetesConfig.ClusterName, "testNamespace", "svc", "testNamespace", graph.Unknown, graph.Unknown, graph.Unknown, graph.GraphTypeVersionedApp) 254 trafficMap[node.ID] = node 255 256 return trafficMap 257 } 258 259 func buildFakeWorkloadDeployments() []apps_v1.Deployment { 260 return []apps_v1.Deployment{ 261 { 262 ObjectMeta: meta_v1.ObjectMeta{ 263 Name: "workload-1", 264 Namespace: "testNamespace", 265 }, 266 Spec: apps_v1.DeploymentSpec{ 267 Template: core_v1.PodTemplateSpec{ 268 ObjectMeta: meta_v1.ObjectMeta{ 269 Labels: map[string]string{"app": "myTest", "wk": "wk-1"}, 270 }, 271 }, 272 }, 273 }, 274 } 275 } 276 277 func buildFakeWorkloadPods() []core_v1.Pod { 278 istioAnnotation := config.Get().ExternalServices.Istio.IstioSidecarAnnotation 279 280 return []core_v1.Pod{ 281 { 282 ObjectMeta: meta_v1.ObjectMeta{ 283 Name: "wk-1-asdf", 284 Namespace: "testNamespace", 285 Labels: map[string]string{"app": "myTest", "wk": "wk-1"}, 286 CreationTimestamp: meta_v1.NewTime(time.Date(2018, 8, 24, 14, 0, 0, 0, time.UTC)), 287 Annotations: map[string]string{ 288 istioAnnotation: "{ \"containers\":[\"istio-proxy\"] }", 289 }, 290 }, 291 }, 292 } 293 } 294 295 func buildFakeWorkloadPodsNoSidecar() []core_v1.Pod { 296 istioAnnotation := config.Get().ExternalServices.Istio.IstioSidecarAnnotation 297 298 podList := buildFakeWorkloadPods() 299 podList[0].ObjectMeta.Annotations[istioAnnotation] = "{}" 300 301 return podList 302 } 303 304 func buildFakeWorkloadPodsAmbient() []core_v1.Pod { 305 306 podList := buildFakeWorkloadPodsNoSidecar() 307 podList[0].ObjectMeta.Annotations["ambient.istio.io/redirection"] = "enabled" 308 309 return podList 310 } 311 312 func setupSidecarsCheckWorkloads(t *testing.T, deployments []apps_v1.Deployment, pods []core_v1.Pod) *business.Layer { 313 objects := []runtime.Object{&core_v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: "testNamespace"}}} 314 for _, obj := range deployments { 315 o := obj 316 objects = append(objects, &o) 317 } 318 for _, obj := range pods { 319 o := obj 320 objects = append(objects, &o) 321 } 322 k8s := kubetest.NewFakeK8sClient(objects...) 323 324 conf := config.NewConfig() 325 conf.ExternalServices.Istio.IstioAPIEnabled = false 326 conf.KubernetesConfig.ClusterName = config.DefaultClusterID 327 config.Set(conf) 328 329 business.SetupBusinessLayer(t, k8s, *conf) 330 k8sclients := make(map[string]kubernetes.ClientInterface) 331 k8sclients[conf.KubernetesConfig.ClusterName] = k8s 332 businessLayer := business.NewWithBackends(k8sclients, k8sclients, nil, nil) 333 return businessLayer 334 }