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  }