github.com/kiali/kiali@v1.84.0/graph/telemetry/istio/appender/security_policy_test.go (about)

     1  package appender
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/prometheus/common/model"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/kiali/kiali/config"
    12  	"github.com/kiali/kiali/graph"
    13  )
    14  
    15  func TestSecurityPolicyDefaultRates(t *testing.T) {
    16  	assert := assert.New(t)
    17  
    18  	q0 := `round((sum(rate(istio_requests_total{mesh_id="mesh1",reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0) OR (sum(rate(istio_tcp_sent_bytes_total{mesh_id="mesh1",reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0),0.001)`
    19  	v0 := model.Vector{}
    20  
    21  	q1 := `round((sum(rate(istio_requests_total{mesh_id="mesh1",reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0) OR (sum(rate(istio_tcp_sent_bytes_total{mesh_id="mesh1",reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0),0.001)`
    22  	q1m0 := model.Metric{
    23  		"source_cluster":                 config.DefaultClusterID,
    24  		"source_workload_namespace":      "istio-system",
    25  		"source_workload":                "ingressgateway-unknown",
    26  		"source_canonical_service":       "ingressgateway",
    27  		"source_canonical_revision":      model.LabelValue(graph.Unknown),
    28  		"source_principal":               "source-principal-test",
    29  		"destination_cluster":            config.DefaultClusterID,
    30  		"destination_service_namespace":  "bookinfo",
    31  		"destination_service_name":       "productpage",
    32  		"destination_workload_namespace": "bookinfo",
    33  		"destination_workload":           "productpage-v1",
    34  		"destination_canonical_service":  "productpage",
    35  		"destination_canonical_revision": "v1",
    36  		"destination_principal":          "destination-principal-test",
    37  		"connection_security_policy":     "mutual_tls"}
    38  	q1m1 := model.Metric{
    39  		"source_cluster":                 config.DefaultClusterID,
    40  		"source_workload_namespace":      "istio-system",
    41  		"source_workload":                "ingressgateway-unknown",
    42  		"source_canonical_service":       "ingressgateway",
    43  		"source_canonical_revision":      model.LabelValue(graph.Unknown),
    44  		"source_principal":               "source-principal-test",
    45  		"destination_cluster":            config.DefaultClusterID,
    46  		"destination_service_namespace":  "bookinfo",
    47  		"destination_service_name":       "productpage",
    48  		"destination_workload_namespace": "bookinfo",
    49  		"destination_workload":           "productpage-v1",
    50  		"destination_canonical_service":  "productpage",
    51  		"destination_canonical_revision": "v1",
    52  		"destination_principal":          "destination-principal-test",
    53  		"connection_security_policy":     "none"}
    54  	v1 := model.Vector{
    55  		&model.Sample{
    56  			Metric: q1m0,
    57  			Value:  10.0},
    58  		&model.Sample{
    59  			Metric: q1m1,
    60  			Value:  10.0}}
    61  
    62  	client, api, err := setupMockedWithQueryScope("mesh1")
    63  	if err != nil {
    64  		t.Error(err)
    65  		return
    66  	}
    67  	mockQuery(api, q0, &v0)
    68  	mockQuery(api, q1, &v1)
    69  
    70  	trafficMap := securityPolicyTestTraffic()
    71  	ingressID, _, _ := graph.Id(config.DefaultClusterID, "istio-system", "", "istio-system", "ingressgateway-unknown", "ingressgateway", graph.Unknown, graph.GraphTypeVersionedApp)
    72  	ingress, ok := trafficMap[ingressID]
    73  	assert.Equal(true, ok)
    74  	assert.Equal("ingressgateway", ingress.App)
    75  	assert.Equal(1, len(ingress.Edges))
    76  	assert.Equal(nil, ingress.Edges[0].Metadata[graph.IsMTLS])
    77  
    78  	duration, _ := time.ParseDuration("60s")
    79  	appender := SecurityPolicyAppender{
    80  		GraphType:          graph.GraphTypeVersionedApp,
    81  		InjectServiceNodes: false,
    82  		Namespaces: graph.NamespaceInfoMap{
    83  			"bookinfo": graph.NamespaceInfo{
    84  				Name:     "bookinfo",
    85  				Duration: duration,
    86  				IsIstio:  false,
    87  			},
    88  		},
    89  		QueryTime: time.Now().Unix(),
    90  		Rates: graph.RequestedRates{
    91  			Grpc: graph.RateRequests,
    92  			Http: graph.RateRequests,
    93  			Tcp:  graph.RateSent,
    94  		},
    95  	}
    96  
    97  	appender.appendGraph(trafficMap, "bookinfo", client)
    98  
    99  	ingress, ok = trafficMap[ingressID]
   100  	assert.Equal(true, ok)
   101  	assert.Equal("ingressgateway", ingress.App)
   102  	assert.Equal(1, len(ingress.Edges))
   103  	assert.Equal(50.0, ingress.Edges[0].Metadata[graph.IsMTLS])
   104  
   105  	productpage := ingress.Edges[0].Dest
   106  	assert.Equal("productpage", productpage.App)
   107  	assert.Equal("v1", productpage.Version)
   108  }
   109  
   110  func TestSecurityPolicyTotalRates(t *testing.T) {
   111  	assert := assert.New(t)
   112  
   113  	q0 := fmt.Sprintf("round((%s) OR (%s) OR (%s) OR (%s) OR (%s),0.001)",
   114  		`sum(rate(istio_requests_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   115  		`sum(rate(istio_request_messages_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   116  		`sum(rate(istio_response_messages_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   117  		`sum(rate(istio_tcp_sent_bytes_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   118  		`sum(rate(istio_tcp_received_bytes_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`)
   119  	v0 := model.Vector{}
   120  
   121  	q1 := fmt.Sprintf("round((%s) OR (%s) OR (%s) OR (%s) OR (%s),0.001)",
   122  		`sum(rate(istio_requests_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   123  		`sum(rate(istio_request_messages_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   124  		`sum(rate(istio_response_messages_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   125  		`sum(rate(istio_tcp_sent_bytes_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`,
   126  		`sum(rate(istio_tcp_received_bytes_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0`)
   127  	q1m0 := model.Metric{
   128  		"source_cluster":                 config.DefaultClusterID,
   129  		"source_workload_namespace":      "istio-system",
   130  		"source_workload":                "ingressgateway-unknown",
   131  		"source_canonical_service":       "ingressgateway",
   132  		"source_canonical_revision":      model.LabelValue(graph.Unknown),
   133  		"source_principal":               "source-principal-test",
   134  		"destination_cluster":            config.DefaultClusterID,
   135  		"destination_service_namespace":  "bookinfo",
   136  		"destination_service_name":       "productpage",
   137  		"destination_workload_namespace": "bookinfo",
   138  		"destination_workload":           "productpage-v1",
   139  		"destination_canonical_service":  "productpage",
   140  		"destination_canonical_revision": "v1",
   141  		"destination_principal":          "destination-principal-test",
   142  		"connection_security_policy":     "mutual_tls"}
   143  	q1m1 := model.Metric{
   144  		"source_cluster":                 config.DefaultClusterID,
   145  		"source_workload_namespace":      "istio-system",
   146  		"source_workload":                "ingressgateway-unknown",
   147  		"source_canonical_service":       "ingressgateway",
   148  		"source_canonical_revision":      model.LabelValue(graph.Unknown),
   149  		"source_principal":               "source-principal-test",
   150  		"destination_cluster":            config.DefaultClusterID,
   151  		"destination_service_namespace":  "bookinfo",
   152  		"destination_service_name":       "productpage",
   153  		"destination_workload_namespace": "bookinfo",
   154  		"destination_workload":           "productpage-v1",
   155  		"destination_canonical_service":  "productpage",
   156  		"destination_canonical_revision": "v1",
   157  		"destination_principal":          "destination-principal-test",
   158  		"connection_security_policy":     "none"}
   159  	v1 := model.Vector{
   160  		&model.Sample{
   161  			Metric: q1m0,
   162  			Value:  10.0},
   163  		&model.Sample{
   164  			Metric: q1m1,
   165  			Value:  10.0}}
   166  
   167  	client, api, err := setupMocked()
   168  	if err != nil {
   169  		t.Error(err)
   170  		return
   171  	}
   172  	mockQuery(api, q0, &v0)
   173  	mockQuery(api, q1, &v1)
   174  
   175  	trafficMap := securityPolicyTestTraffic()
   176  	ingressID, _, _ := graph.Id(config.DefaultClusterID, "istio-system", "", "istio-system", "ingressgateway-unknown", "ingressgateway", graph.Unknown, graph.GraphTypeVersionedApp)
   177  	ingress, ok := trafficMap[ingressID]
   178  	assert.Equal(true, ok)
   179  	assert.Equal("ingressgateway", ingress.App)
   180  	assert.Equal(1, len(ingress.Edges))
   181  	assert.Equal(nil, ingress.Edges[0].Metadata[graph.IsMTLS])
   182  
   183  	duration, _ := time.ParseDuration("60s")
   184  	appender := SecurityPolicyAppender{
   185  		GraphType:          graph.GraphTypeVersionedApp,
   186  		InjectServiceNodes: false,
   187  		Namespaces: graph.NamespaceInfoMap{
   188  			"bookinfo": graph.NamespaceInfo{
   189  				Name:     "bookinfo",
   190  				Duration: duration,
   191  				IsIstio:  false,
   192  			},
   193  		},
   194  		QueryTime: time.Now().Unix(),
   195  		Rates: graph.RequestedRates{
   196  			Grpc: graph.RateTotal,
   197  			Http: graph.RateRequests,
   198  			Tcp:  graph.RateTotal,
   199  		},
   200  	}
   201  
   202  	appender.appendGraph(trafficMap, "bookinfo", client)
   203  
   204  	ingress, ok = trafficMap[ingressID]
   205  	assert.Equal(true, ok)
   206  	assert.Equal("ingressgateway", ingress.App)
   207  	assert.Equal(1, len(ingress.Edges))
   208  	assert.Equal(50.0, ingress.Edges[0].Metadata[graph.IsMTLS])
   209  
   210  	productpage := ingress.Edges[0].Dest
   211  	assert.Equal("productpage", productpage.App)
   212  	assert.Equal("v1", productpage.Version)
   213  }
   214  
   215  func TestSecurityPolicyWithServiceNodes(t *testing.T) {
   216  	assert := assert.New(t)
   217  
   218  	q0 := `round((sum(rate(istio_requests_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0) OR (sum(rate(istio_tcp_sent_bytes_total{reporter="destination",source_workload_namespace!="bookinfo",destination_service_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0),0.001)`
   219  	v0 := model.Vector{}
   220  
   221  	q1 := `round((sum(rate(istio_requests_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0) OR (sum(rate(istio_tcp_sent_bytes_total{reporter="destination",source_workload_namespace="bookinfo"}[60s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,source_principal,destination_cluster,destination_service_namespace,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,destination_principal,connection_security_policy) > 0),0.001)`
   222  	q1m0 := model.Metric{
   223  		"source_cluster":                 config.DefaultClusterID,
   224  		"source_workload_namespace":      "istio-system",
   225  		"source_workload":                "ingressgateway-unknown",
   226  		"source_canonical_service":       "ingressgateway",
   227  		"source_canonical_revision":      model.LabelValue(graph.Unknown),
   228  		"source_principal":               "source-principal-test",
   229  		"destination_cluster":            config.DefaultClusterID,
   230  		"destination_service_namespace":  "bookinfo",
   231  		"destination_service_name":       "productpage",
   232  		"destination_workload_namespace": "bookinfo",
   233  		"destination_workload":           "productpage-v1",
   234  		"destination_canonical_service":  "productpage",
   235  		"destination_canonical_revision": "v1",
   236  		"destination_principal":          "destination-principal-test",
   237  		"connection_security_policy":     "mutual_tls"}
   238  	v1 := model.Vector{
   239  		&model.Sample{
   240  			Metric: q1m0,
   241  			Value:  10.0}}
   242  
   243  	client, api, err := setupMocked()
   244  	if err != nil {
   245  		t.Error(err)
   246  		return
   247  	}
   248  	mockQuery(api, q0, &v0)
   249  	mockQuery(api, q1, &v1)
   250  
   251  	trafficMap := securityPolicyTestTrafficWithServiceNodes()
   252  	ingressId, _, _ := graph.Id(config.DefaultClusterID, "istio-system", "", "istio-system", "ingressgateway-unknown", "ingressgateway", graph.Unknown, graph.GraphTypeVersionedApp)
   253  	ingress, ok := trafficMap[ingressId]
   254  	assert.Equal(true, ok)
   255  	assert.Equal("ingressgateway", ingress.App)
   256  	assert.Equal(1, len(ingress.Edges))
   257  	assert.Equal(nil, ingress.Edges[0].Metadata[graph.IsMTLS])
   258  
   259  	duration, _ := time.ParseDuration("60s")
   260  	appender := SecurityPolicyAppender{
   261  		GraphType:          graph.GraphTypeVersionedApp,
   262  		InjectServiceNodes: true,
   263  		Namespaces: map[string]graph.NamespaceInfo{
   264  			"bookinfo": {
   265  				Name:     "bookinfo",
   266  				Duration: duration,
   267  			},
   268  		},
   269  		QueryTime: time.Now().Unix(),
   270  		Rates: graph.RequestedRates{
   271  			Grpc: graph.RateRequests,
   272  			Http: graph.RateRequests,
   273  			Tcp:  graph.RateSent,
   274  		},
   275  	}
   276  
   277  	appender.appendGraph(trafficMap, "bookinfo", client)
   278  
   279  	ingress, ok = trafficMap[ingressId]
   280  	assert.Equal(true, ok)
   281  	assert.Equal("ingressgateway", ingress.App)
   282  	assert.Equal(1, len(ingress.Edges))
   283  	assert.Equal(100.0, ingress.Edges[0].Metadata[graph.IsMTLS])
   284  
   285  	productpagesvc := ingress.Edges[0].Dest
   286  	assert.Equal("productpage", productpagesvc.Service)
   287  	assert.Equal(1, len(productpagesvc.Edges))
   288  	assert.Equal(100.0, productpagesvc.Edges[0].Metadata[graph.IsMTLS])
   289  
   290  	productpage := productpagesvc.Edges[0].Dest
   291  	assert.Equal("productpage", productpage.App)
   292  	assert.Equal("v1", productpage.Version)
   293  }
   294  
   295  func securityPolicyTestTraffic() graph.TrafficMap {
   296  	ingress, _ := graph.NewNode(config.DefaultClusterID, "istio-system", "", "istio-system", "ingressgateway-unknown", "ingressgateway", graph.Unknown, graph.GraphTypeVersionedApp)
   297  	productpage, _ := graph.NewNode(config.DefaultClusterID, "bookinfo", "productpage", "bookinfo", "productpage-v1", "productpage", "v1", graph.GraphTypeVersionedApp)
   298  	trafficMap := graph.NewTrafficMap()
   299  	trafficMap[ingress.ID] = ingress
   300  	trafficMap[productpage.ID] = productpage
   301  
   302  	ingress.AddEdge(productpage)
   303  
   304  	return trafficMap
   305  }
   306  
   307  func securityPolicyTestTrafficWithServiceNodes() graph.TrafficMap {
   308  	ingress, _ := graph.NewNode(config.DefaultClusterID, "istio-system", "", "istio-system", "ingressgateway-unknown", "ingressgateway", graph.Unknown, graph.GraphTypeVersionedApp)
   309  	productpagesvc, _ := graph.NewNode(config.DefaultClusterID, "bookinfo", "productpage", "bookinfo", "", "", "", graph.GraphTypeVersionedApp)
   310  	productpage, _ := graph.NewNode(config.DefaultClusterID, "bookinfo", "productpage", "bookinfo", "productpage-v1", "productpage", "v1", graph.GraphTypeVersionedApp)
   311  	trafficMap := graph.NewTrafficMap()
   312  	trafficMap[ingress.ID] = ingress
   313  	trafficMap[productpagesvc.ID] = productpagesvc
   314  	trafficMap[productpage.ID] = productpage
   315  
   316  	ingress.AddEdge(productpagesvc)
   317  	productpagesvc.AddEdge(productpage)
   318  
   319  	return trafficMap
   320  }