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  }