github.com/cilium/cilium@v1.16.2/pkg/hubble/testutils/fake.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 // Copyright Authors of Cilium 5 6 package testutils 7 8 import ( 9 "context" 10 "net" 11 "net/netip" 12 "time" 13 14 "google.golang.org/grpc" 15 "google.golang.org/grpc/connectivity" 16 17 flowpb "github.com/cilium/cilium/api/v1/flow" 18 "github.com/cilium/cilium/api/v1/models" 19 observerpb "github.com/cilium/cilium/api/v1/observer" 20 peerpb "github.com/cilium/cilium/api/v1/peer" 21 cgroupManager "github.com/cilium/cilium/pkg/cgroups/manager" 22 "github.com/cilium/cilium/pkg/hubble/parser/getters" 23 peerTypes "github.com/cilium/cilium/pkg/hubble/peer/types" 24 poolTypes "github.com/cilium/cilium/pkg/hubble/relay/pool/types" 25 "github.com/cilium/cilium/pkg/identity" 26 "github.com/cilium/cilium/pkg/ipcache" 27 slim_corev1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1" 28 "github.com/cilium/cilium/pkg/labels" 29 policyTypes "github.com/cilium/cilium/pkg/policy/types" 30 ) 31 32 // FakeGetFlowsServer is used for unit tests and implements the 33 // observerpb.Observer_GetFlowsServer interface. 34 type FakeGetFlowsServer struct { 35 OnSend func(response *observerpb.GetFlowsResponse) error 36 *FakeGRPCServerStream 37 } 38 39 // Send implements observerpb.Observer_GetFlowsServer.Send. 40 func (s *FakeGetFlowsServer) Send(response *observerpb.GetFlowsResponse) error { 41 if s.OnSend != nil { 42 // TODO: completely convert this into using flowpb.Flow 43 return s.OnSend(response) 44 } 45 panic("OnSend not set") 46 } 47 48 // FakeGetAgentEventsServer is used for unit tests and implements the 49 // observerpb.Observer_GetAgentEventsServer interface. 50 type FakeGetAgentEventsServer struct { 51 OnSend func(response *observerpb.GetAgentEventsResponse) error 52 *FakeGRPCServerStream 53 } 54 55 // Send implements observerpb.Observer_GetAgentEventsServer.Send. 56 func (s *FakeGetAgentEventsServer) Send(response *observerpb.GetAgentEventsResponse) error { 57 if s.OnSend != nil { 58 return s.OnSend(response) 59 } 60 panic("OnSend not set") 61 } 62 63 // FakeObserverClient is used for unit tests and implements the 64 // observerpb.ObserverClient interface. 65 type FakeObserverClient struct { 66 OnGetFlows func(ctx context.Context, in *observerpb.GetFlowsRequest, opts ...grpc.CallOption) (observerpb.Observer_GetFlowsClient, error) 67 OnGetAgentEvents func(ctx context.Context, in *observerpb.GetAgentEventsRequest, opts ...grpc.CallOption) (observerpb.Observer_GetAgentEventsClient, error) 68 OnGetDebugEvents func(ctx context.Context, in *observerpb.GetDebugEventsRequest, opts ...grpc.CallOption) (observerpb.Observer_GetDebugEventsClient, error) 69 OnGetNodes func(ctx context.Context, in *observerpb.GetNodesRequest, opts ...grpc.CallOption) (*observerpb.GetNodesResponse, error) 70 OnGetNamespaces func(ctx context.Context, in *observerpb.GetNamespacesRequest, opts ...grpc.CallOption) (*observerpb.GetNamespacesResponse, error) 71 OnServerStatus func(ctx context.Context, in *observerpb.ServerStatusRequest, opts ...grpc.CallOption) (*observerpb.ServerStatusResponse, error) 72 } 73 74 // GetFlows implements observerpb.ObserverClient.GetFlows. 75 func (c *FakeObserverClient) GetFlows(ctx context.Context, in *observerpb.GetFlowsRequest, opts ...grpc.CallOption) (observerpb.Observer_GetFlowsClient, error) { 76 if c.OnGetFlows != nil { 77 return c.OnGetFlows(ctx, in, opts...) 78 } 79 panic("OnGetFlows not set") 80 } 81 82 // GetAgentEvents implements observerpb.ObserverClient.GetAgentEvents. 83 func (c *FakeObserverClient) GetAgentEvents(ctx context.Context, in *observerpb.GetAgentEventsRequest, opts ...grpc.CallOption) (observerpb.Observer_GetAgentEventsClient, error) { 84 if c.OnGetAgentEvents != nil { 85 return c.OnGetAgentEvents(ctx, in, opts...) 86 } 87 panic("OnGetAgentEvents not set") 88 } 89 90 // GetDebugEvents implements observerpb.ObserverClient.GetDebugEvents. 91 func (c *FakeObserverClient) GetDebugEvents(ctx context.Context, in *observerpb.GetDebugEventsRequest, opts ...grpc.CallOption) (observerpb.Observer_GetDebugEventsClient, error) { 92 if c.OnGetDebugEvents != nil { 93 return c.OnGetDebugEvents(ctx, in, opts...) 94 } 95 panic("OnGetDebugEvents not set") 96 } 97 98 // GetNodes implements observerpb.ObserverClient.GetNodes. 99 func (c *FakeObserverClient) GetNodes(ctx context.Context, in *observerpb.GetNodesRequest, opts ...grpc.CallOption) (*observerpb.GetNodesResponse, error) { 100 if c.OnGetNodes != nil { 101 return c.OnGetNodes(ctx, in, opts...) 102 } 103 panic("OnGetNodes not set") 104 } 105 106 // GetNamespaces implements observerpb.ObserverClient.GetNamespaces. 107 func (c *FakeObserverClient) GetNamespaces(ctx context.Context, in *observerpb.GetNamespacesRequest, opts ...grpc.CallOption) (*observerpb.GetNamespacesResponse, error) { 108 if c.OnGetNamespaces != nil { 109 return c.OnGetNamespaces(ctx, in, opts...) 110 } 111 panic("OnGetNamespaces not set") 112 } 113 114 // ServerStatus implements observerpb.ObserverClient.ServerStatus. 115 func (c *FakeObserverClient) ServerStatus(ctx context.Context, in *observerpb.ServerStatusRequest, opts ...grpc.CallOption) (*observerpb.ServerStatusResponse, error) { 116 if c.OnServerStatus != nil { 117 return c.OnServerStatus(ctx, in, opts...) 118 } 119 panic("OnServerStatus not set") 120 } 121 122 // FakeGetFlowsClient is used for unit tests and implements the 123 // observerpb.Observer_GetFlowsClient interface. 124 type FakeGetFlowsClient struct { 125 OnRecv func() (*observerpb.GetFlowsResponse, error) 126 *FakeGRPCClientStream 127 } 128 129 // Recv implements observerpb.Observer_GetFlowsClient.Recv. 130 func (c *FakeGetFlowsClient) Recv() (*observerpb.GetFlowsResponse, error) { 131 if c.OnRecv != nil { 132 return c.OnRecv() 133 } 134 panic("OnRecv not set") 135 } 136 137 // FakePeerNotifyServer is used for unit tests and implements the 138 // peerpb.Peer_NotifyServer interface. 139 type FakePeerNotifyServer struct { 140 OnSend func(response *peerpb.ChangeNotification) error 141 *FakeGRPCServerStream 142 } 143 144 // Send implements peerpb.Peer_NotifyServer.Send. 145 func (s *FakePeerNotifyServer) Send(response *peerpb.ChangeNotification) error { 146 if s.OnSend != nil { 147 return s.OnSend(response) 148 } 149 panic("OnSend not set") 150 } 151 152 // FakePeerNotifyClient is used for unit tests and implements the 153 // peerpb.Peer_NotifyClient interface. 154 type FakePeerNotifyClient struct { 155 OnRecv func() (*peerpb.ChangeNotification, error) 156 *FakeGRPCClientStream 157 } 158 159 // Recv implements peerpb.Peer_NotifyClient.Recv. 160 func (c *FakePeerNotifyClient) Recv() (*peerpb.ChangeNotification, error) { 161 if c.OnRecv != nil { 162 return c.OnRecv() 163 } 164 panic("OnRecv not set") 165 } 166 167 // FakePeerClient is used for unit tests and implements the peerTypes.Client 168 // interface. 169 type FakePeerClient struct { 170 OnNotify func(ctx context.Context, in *peerpb.NotifyRequest, opts ...grpc.CallOption) (peerpb.Peer_NotifyClient, error) 171 OnClose func() error 172 } 173 174 // Notify implements peerTypes.Client.Notify. 175 func (c *FakePeerClient) Notify(ctx context.Context, in *peerpb.NotifyRequest, opts ...grpc.CallOption) (peerpb.Peer_NotifyClient, error) { 176 if c.OnNotify != nil { 177 return c.OnNotify(ctx, in, opts...) 178 } 179 panic("OnNotify not set") 180 } 181 182 // Close implements peerTypes.Client.Close. 183 func (c *FakePeerClient) Close() error { 184 if c.OnClose != nil { 185 return c.OnClose() 186 } 187 panic("OnClose not set") 188 } 189 190 // FakePeerClientBuilder is used for unit tests and implements the 191 // peerTypes.ClientBuilder interface. 192 type FakePeerClientBuilder struct { 193 OnClient func(target string) (peerTypes.Client, error) 194 } 195 196 // Client implements peerTypes.ClientBuilder.Client. 197 func (b FakePeerClientBuilder) Client(target string) (peerTypes.Client, error) { 198 if b.OnClient != nil { 199 return b.OnClient(target) 200 } 201 panic("OnClient not set") 202 } 203 204 // FakePeerLister is used for unit tests and implements the 205 // relay/observer.PeerListReporter interface. 206 type FakePeerLister struct { 207 OnList func() []poolTypes.Peer 208 } 209 210 // List implements relay/observer.PeerListReporter.List. 211 func (r *FakePeerLister) List() []poolTypes.Peer { 212 if r.OnList != nil { 213 return r.OnList() 214 } 215 panic("OnList not set") 216 } 217 218 // FakeClientConn is used for unit tests and implements the 219 // poolTypes.ClientConn interface. 220 type FakeClientConn struct { 221 OnGetState func() connectivity.State 222 OnClose func() error 223 OnInvoke func(ctx context.Context, method string, args interface{}, reply interface{}, opts ...grpc.CallOption) error 224 OnNewStream func(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) 225 } 226 227 // GetState implements poolTypes.ClientConn.GetState. 228 func (c FakeClientConn) GetState() connectivity.State { 229 if c.OnGetState != nil { 230 return c.OnGetState() 231 } 232 panic("OnGetState not set") 233 } 234 235 // Close implements poolTypes.ClientConn.Close. 236 func (c FakeClientConn) Close() error { 237 if c.OnClose != nil { 238 return c.OnClose() 239 } 240 panic("OnClose not set") 241 } 242 243 // Invoke implements poolTypes.ClientConn.Invoke. 244 func (c FakeClientConn) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...grpc.CallOption) error { 245 if c.OnInvoke != nil { 246 return c.OnInvoke(ctx, method, args, reply, opts...) 247 } 248 panic("OnInvoke not set") 249 } 250 251 // NewStream implements poolTypes.ClientConn.NewStream. 252 func (c FakeClientConn) NewStream(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) { 253 if c.OnNewStream != nil { 254 return c.OnNewStream(ctx, desc, method, opts...) 255 } 256 panic("OnNewStream not set") 257 } 258 259 // FakeFQDNCache is used for unit tests that needs FQDNCache and/or DNSGetter. 260 type FakeFQDNCache struct { 261 OnInitializeFrom func(entries []*models.DNSLookup) 262 OnAddDNSLookup func(epID uint32, lookupTime time.Time, domainName string, ips []net.IP, ttl uint32) 263 OnGetNamesOf func(epID uint32, ip netip.Addr) []string 264 } 265 266 // InitializeFrom implements FQDNCache.InitializeFrom. 267 func (f *FakeFQDNCache) InitializeFrom(entries []*models.DNSLookup) { 268 if f.OnInitializeFrom != nil { 269 f.OnInitializeFrom(entries) 270 return 271 } 272 panic("InitializeFrom([]*models.DNSLookup) should not have been called since it was not defined") 273 } 274 275 // AddDNSLookup implements FQDNCache.AddDNSLookup. 276 func (f *FakeFQDNCache) AddDNSLookup(epID uint32, lookupTime time.Time, domainName string, ips []net.IP, ttl uint32) { 277 if f.OnAddDNSLookup != nil { 278 f.OnAddDNSLookup(epID, lookupTime, domainName, ips, ttl) 279 return 280 } 281 panic("AddDNSLookup(uint32, time.Time, string, []net.IP, uint32) should not have been called since it was not defined") 282 } 283 284 // GetNamesOf implements FQDNCache.GetNameOf. 285 func (f *FakeFQDNCache) GetNamesOf(epID uint32, ip netip.Addr) []string { 286 if f.OnGetNamesOf != nil { 287 return f.OnGetNamesOf(epID, ip) 288 } 289 panic("GetNamesOf(uint32, netip.Addr) should not have been called since it was not defined") 290 } 291 292 // NoopDNSGetter always returns an empty response. 293 var NoopDNSGetter = FakeFQDNCache{ 294 OnGetNamesOf: func(sourceEpID uint32, ip netip.Addr) (fqdns []string) { 295 return nil 296 }, 297 } 298 299 // FakeEndpointGetter is used for unit tests that needs EndpointGetter. 300 type FakeEndpointGetter struct { 301 OnGetEndpointInfo func(ip netip.Addr) (endpoint getters.EndpointInfo, ok bool) 302 OnGetEndpointInfoByID func(id uint16) (endpoint getters.EndpointInfo, ok bool) 303 } 304 305 // GetEndpointInfo implements EndpointGetter.GetEndpointInfo. 306 func (f *FakeEndpointGetter) GetEndpointInfo(ip netip.Addr) (endpoint getters.EndpointInfo, ok bool) { 307 if f.OnGetEndpointInfo != nil { 308 return f.OnGetEndpointInfo(ip) 309 } 310 panic("OnGetEndpointInfo not set") 311 } 312 313 // GetEndpointInfoByID implements EndpointGetter.GetEndpointInfoByID. 314 func (f *FakeEndpointGetter) GetEndpointInfoByID(id uint16) (endpoint getters.EndpointInfo, ok bool) { 315 if f.OnGetEndpointInfoByID != nil { 316 return f.OnGetEndpointInfoByID(id) 317 } 318 panic("GetEndpointInfoByID not set") 319 } 320 321 // NoopEndpointGetter always returns an empty response. 322 var NoopEndpointGetter = FakeEndpointGetter{ 323 OnGetEndpointInfo: func(ip netip.Addr) (endpoint getters.EndpointInfo, ok bool) { 324 return nil, false 325 }, 326 OnGetEndpointInfoByID: func(id uint16) (endpoint getters.EndpointInfo, ok bool) { 327 return nil, false 328 }, 329 } 330 331 type FakeLinkGetter struct{} 332 333 func (e *FakeLinkGetter) Name(ifindex uint32) string { 334 return "lo" 335 } 336 337 func (e *FakeLinkGetter) GetIfNameCached(ifindex int) (string, bool) { 338 return e.Name(uint32(ifindex)), true 339 } 340 341 var NoopLinkGetter = FakeLinkGetter{} 342 343 // FakeIPGetter is used for unit tests that needs IPGetter. 344 type FakeIPGetter struct { 345 OnGetK8sMetadata func(ip netip.Addr) *ipcache.K8sMetadata 346 OnLookupSecIDByIP func(ip netip.Addr) (ipcache.Identity, bool) 347 } 348 349 // GetK8sMetadata implements FakeIPGetter.GetK8sMetadata. 350 func (f *FakeIPGetter) GetK8sMetadata(ip netip.Addr) *ipcache.K8sMetadata { 351 if f.OnGetK8sMetadata != nil { 352 return f.OnGetK8sMetadata(ip) 353 } 354 panic("OnGetK8sMetadata not set") 355 } 356 357 // LookupSecIDByIP implements FakeIPGetter.LookupSecIDByIP. 358 func (f *FakeIPGetter) LookupSecIDByIP(ip netip.Addr) (ipcache.Identity, bool) { 359 if f.OnLookupSecIDByIP != nil { 360 return f.OnLookupSecIDByIP(ip) 361 } 362 panic("OnLookupByIP not set") 363 } 364 365 // NoopIPGetter always returns an empty response. 366 var NoopIPGetter = FakeIPGetter{ 367 OnGetK8sMetadata: func(ip netip.Addr) *ipcache.K8sMetadata { 368 return nil 369 }, 370 OnLookupSecIDByIP: func(ip netip.Addr) (ipcache.Identity, bool) { 371 return ipcache.Identity{}, false 372 }, 373 } 374 375 // FakeServiceGetter is used for unit tests that need ServiceGetter. 376 type FakeServiceGetter struct { 377 OnGetServiceByAddr func(ip netip.Addr, port uint16) *flowpb.Service 378 } 379 380 // GetServiceByAddr implements FakeServiceGetter.GetServiceByAddr. 381 func (f *FakeServiceGetter) GetServiceByAddr(ip netip.Addr, port uint16) *flowpb.Service { 382 if f.OnGetServiceByAddr != nil { 383 return f.OnGetServiceByAddr(ip, port) 384 } 385 panic("OnGetServiceByAddr not set") 386 } 387 388 // NoopServiceGetter always returns an empty response. 389 var NoopServiceGetter = FakeServiceGetter{ 390 OnGetServiceByAddr: func(ip netip.Addr, port uint16) *flowpb.Service { 391 return nil 392 }, 393 } 394 395 // FakeIdentityGetter is used for unit tests that need IdentityGetter. 396 type FakeIdentityGetter struct { 397 OnGetIdentity func(securityIdentity uint32) (*identity.Identity, error) 398 } 399 400 // GetIdentity implements IdentityGetter.GetIPIdentity. 401 func (f *FakeIdentityGetter) GetIdentity(securityIdentity uint32) (*identity.Identity, error) { 402 if f.OnGetIdentity != nil { 403 return f.OnGetIdentity(securityIdentity) 404 } 405 panic("OnGetIdentity not set") 406 } 407 408 // NoopIdentityGetter always returns an empty response. 409 var NoopIdentityGetter = FakeIdentityGetter{ 410 OnGetIdentity: func(securityIdentity uint32) (*identity.Identity, error) { 411 return &identity.Identity{}, nil 412 }, 413 } 414 415 // FakeEndpointInfo implements getters.EndpointInfo for unit tests. All interface 416 // methods return values exposed in the fields. 417 type FakeEndpointInfo struct { 418 ContainerIDs []string 419 ID uint64 420 Identity identity.NumericIdentity 421 IPv4 net.IP 422 IPv6 net.IP 423 PodName string 424 PodNamespace string 425 Labels []string 426 Pod *slim_corev1.Pod 427 428 PolicyMap map[policyTypes.Key]labels.LabelArrayList 429 PolicyRevision uint64 430 } 431 432 // GetID returns the ID of the endpoint. 433 func (e *FakeEndpointInfo) GetID() uint64 { 434 return e.ID 435 } 436 437 // GetIdentity returns the numerical security identity of the endpoint. 438 func (e *FakeEndpointInfo) GetIdentity() identity.NumericIdentity { 439 return e.Identity 440 } 441 442 // GetK8sPodName returns the pod name of the endpoint. 443 func (e *FakeEndpointInfo) GetK8sPodName() string { 444 return e.PodName 445 } 446 447 // GetK8sNamespace returns the pod namespace of the endpoint. 448 func (e *FakeEndpointInfo) GetK8sNamespace() string { 449 return e.PodNamespace 450 } 451 452 // GetLabels returns the labels of the endpoint. 453 func (e *FakeEndpointInfo) GetLabels() []string { 454 return e.Labels 455 } 456 457 // GetPod return the pod object of the endpoint. 458 func (e *FakeEndpointInfo) GetPod() *slim_corev1.Pod { 459 return e.Pod 460 } 461 462 func (e *FakeEndpointInfo) GetRealizedPolicyRuleLabelsForKey(key policyTypes.Key) ( 463 derivedFrom labels.LabelArrayList, 464 revision uint64, 465 ok bool, 466 ) { 467 derivedFrom, ok = e.PolicyMap[key] 468 return derivedFrom, e.PolicyRevision, ok 469 } 470 471 // FakePodMetadataGetter is used for unit tests that need a PodMetadataGetter. 472 type FakePodMetadataGetter struct { 473 OnGetPodMetadataForContainer func(cgroupId uint64) *cgroupManager.PodMetadata 474 } 475 476 // GetPodMetadataForContainer implements PodMetadataGetter.GetPodMetadataForContainer. 477 func (f *FakePodMetadataGetter) GetPodMetadataForContainer(cgroupId uint64) *cgroupManager.PodMetadata { 478 if f.OnGetPodMetadataForContainer != nil { 479 return f.OnGetPodMetadataForContainer(cgroupId) 480 } 481 panic("GetPodMetadataForContainer not set") 482 } 483 484 // NoopPodMetadataGetter always returns an empty response. 485 var NoopPodMetadataGetter = FakePodMetadataGetter{ 486 OnGetPodMetadataForContainer: func(cgroupId uint64) *cgroupManager.PodMetadata { 487 return nil 488 }, 489 }