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 }