github.com/cilium/cilium@v1.16.2/pkg/hubble/parser/agent/parser_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package agent_test
     5  
     6  import (
     7  	"encoding/json"
     8  	"errors"
     9  	"fmt"
    10  	"net"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"google.golang.org/protobuf/types/known/timestamppb"
    16  	"google.golang.org/protobuf/types/known/wrapperspb"
    17  
    18  	flowpb "github.com/cilium/cilium/api/v1/flow"
    19  	"github.com/cilium/cilium/pkg/hubble/parser/agent"
    20  	monitorAPI "github.com/cilium/cilium/pkg/monitor/api"
    21  )
    22  
    23  type mockEndpoint struct {
    24  	ID        uint16
    25  	Labels    []string
    26  	PodName   string
    27  	Namespace string
    28  }
    29  
    30  func (e *mockEndpoint) GetID() uint64           { return uint64(e.ID) }
    31  func (e *mockEndpoint) GetOpLabels() []string   { return e.Labels }
    32  func (e *mockEndpoint) GetK8sPodName() string   { return e.PodName }
    33  func (e *mockEndpoint) GetK8sNamespace() string { return e.Namespace }
    34  func (e *mockEndpoint) GetID16() uint16         { return e.ID }
    35  
    36  func TestDecodeAgentEvent(t *testing.T) {
    37  	unknownNotification := struct {
    38  		Foo int64
    39  		Bar int32
    40  	}{
    41  		Foo: 23,
    42  		Bar: 42,
    43  	}
    44  	unknownNotificationJSON, _ := json.Marshal(unknownNotification)
    45  
    46  	agentStartTS := time.Now()
    47  	agentStartTSProto := timestamppb.New(agentStartTS)
    48  	assert.NoError(t, agentStartTSProto.CheckValid())
    49  
    50  	mockEP := &mockEndpoint{
    51  		ID:        65535,
    52  		Labels:    []string{"custom=label", "label=another"},
    53  		PodName:   "devnull",
    54  		Namespace: "hubble",
    55  	}
    56  
    57  	oldID := uint32(511)
    58  
    59  	tt := []struct {
    60  		name string
    61  		msg  monitorAPI.AgentNotifyMessage
    62  		ev   *flowpb.AgentEvent
    63  	}{
    64  		{
    65  			name: "empty",
    66  			msg:  monitorAPI.AgentNotifyMessage{},
    67  			ev: &flowpb.AgentEvent{
    68  				Type: flowpb.AgentEventType_AGENT_EVENT_UNKNOWN,
    69  				Notification: &flowpb.AgentEvent_Unknown{
    70  					Unknown: &flowpb.AgentEventUnknown{
    71  						Type:         fmt.Sprintf("%d", monitorAPI.AgentNotifyUnspec),
    72  						Notification: "null",
    73  					},
    74  				},
    75  			},
    76  		},
    77  		{
    78  			name: "unspecified",
    79  			msg: monitorAPI.AgentNotifyMessage{
    80  				Type:         monitorAPI.AgentNotifyUnspec,
    81  				Notification: unknownNotification,
    82  			},
    83  			ev: &flowpb.AgentEvent{
    84  				Type: flowpb.AgentEventType_AGENT_EVENT_UNKNOWN,
    85  				Notification: &flowpb.AgentEvent_Unknown{
    86  					Unknown: &flowpb.AgentEventUnknown{
    87  						Type:         fmt.Sprintf("%d", monitorAPI.AgentNotifyUnspec),
    88  						Notification: string(unknownNotificationJSON),
    89  					},
    90  				},
    91  			},
    92  		},
    93  		{
    94  			name: "type and notification type mismatch",
    95  			msg: monitorAPI.AgentNotifyMessage{
    96  				Type:         monitorAPI.AgentNotifyStart,
    97  				Notification: unknownNotification,
    98  			},
    99  			ev: &flowpb.AgentEvent{
   100  				Type: flowpb.AgentEventType_AGENT_EVENT_UNKNOWN,
   101  				Notification: &flowpb.AgentEvent_Unknown{
   102  					Unknown: &flowpb.AgentEventUnknown{
   103  						Type:         fmt.Sprintf("%d", monitorAPI.AgentNotifyStart),
   104  						Notification: string(unknownNotificationJSON),
   105  					},
   106  				},
   107  			},
   108  		},
   109  
   110  		{
   111  			name: "StartMessage",
   112  			msg:  monitorAPI.StartMessage(agentStartTS),
   113  			ev: &flowpb.AgentEvent{
   114  				Type: flowpb.AgentEventType_AGENT_STARTED,
   115  				Notification: &flowpb.AgentEvent_AgentStart{
   116  					AgentStart: &flowpb.TimeNotification{
   117  						Time: agentStartTSProto,
   118  					},
   119  				},
   120  			},
   121  		},
   122  		{
   123  			name: "PolicyUpdateMessage",
   124  			msg:  monitorAPI.PolicyUpdateMessage(42, []string{"hubble=rocks", "cilium=too"}, 7),
   125  			ev: &flowpb.AgentEvent{
   126  				Type: flowpb.AgentEventType_POLICY_UPDATED,
   127  				Notification: &flowpb.AgentEvent_PolicyUpdate{
   128  					PolicyUpdate: &flowpb.PolicyUpdateNotification{
   129  						RuleCount: 42,
   130  						Labels:    []string{"hubble=rocks", "cilium=too"},
   131  						Revision:  7,
   132  					},
   133  				},
   134  			},
   135  		},
   136  		{
   137  			name: "PolicyDeleteMessage",
   138  			msg:  monitorAPI.PolicyDeleteMessage(23, []string{"foo=bar"}, 255),
   139  			ev: &flowpb.AgentEvent{
   140  				Type: flowpb.AgentEventType_POLICY_DELETED,
   141  				Notification: &flowpb.AgentEvent_PolicyUpdate{
   142  					PolicyUpdate: &flowpb.PolicyUpdateNotification{
   143  						RuleCount: 23,
   144  						Labels:    []string{"foo=bar"},
   145  						Revision:  255,
   146  					},
   147  				},
   148  			},
   149  		},
   150  		{
   151  			name: "EndpointRegenMessage success",
   152  			msg:  monitorAPI.EndpointRegenMessage(mockEP, nil),
   153  			ev: &flowpb.AgentEvent{
   154  				Type: flowpb.AgentEventType_ENDPOINT_REGENERATE_SUCCESS,
   155  				Notification: &flowpb.AgentEvent_EndpointRegenerate{
   156  					EndpointRegenerate: &flowpb.EndpointRegenNotification{
   157  						Id:     mockEP.GetID(),
   158  						Labels: mockEP.GetOpLabels(),
   159  						Error:  "",
   160  					},
   161  				},
   162  			},
   163  		},
   164  		{
   165  			name: "EndpointRegenMessage failure",
   166  			msg:  monitorAPI.EndpointRegenMessage(mockEP, errors.New("error regenerating endpoint")),
   167  			ev: &flowpb.AgentEvent{
   168  				Type: flowpb.AgentEventType_ENDPOINT_REGENERATE_FAILURE,
   169  				Notification: &flowpb.AgentEvent_EndpointRegenerate{
   170  					EndpointRegenerate: &flowpb.EndpointRegenNotification{
   171  						Id:     mockEP.GetID(),
   172  						Labels: mockEP.GetOpLabels(),
   173  						Error:  "error regenerating endpoint",
   174  					},
   175  				},
   176  			},
   177  		},
   178  		{
   179  			name: "EndpointCreateMessage",
   180  			msg:  monitorAPI.EndpointCreateMessage(mockEP),
   181  			ev: &flowpb.AgentEvent{
   182  				Type: flowpb.AgentEventType_ENDPOINT_CREATED,
   183  				Notification: &flowpb.AgentEvent_EndpointUpdate{
   184  					EndpointUpdate: &flowpb.EndpointUpdateNotification{
   185  						Id:        mockEP.GetID(),
   186  						Labels:    mockEP.GetOpLabels(),
   187  						Error:     "",
   188  						PodName:   mockEP.GetK8sPodName(),
   189  						Namespace: mockEP.GetK8sNamespace(),
   190  					},
   191  				},
   192  			},
   193  		},
   194  		{
   195  			name: "EndpointDeleteMessage",
   196  			msg:  monitorAPI.EndpointDeleteMessage(mockEP),
   197  			ev: &flowpb.AgentEvent{
   198  				Type: flowpb.AgentEventType_ENDPOINT_DELETED,
   199  				Notification: &flowpb.AgentEvent_EndpointUpdate{
   200  					EndpointUpdate: &flowpb.EndpointUpdateNotification{
   201  						Id:        mockEP.GetID(),
   202  						Labels:    mockEP.GetOpLabels(),
   203  						Error:     "",
   204  						PodName:   mockEP.GetK8sPodName(),
   205  						Namespace: mockEP.GetK8sNamespace(),
   206  					},
   207  				},
   208  			},
   209  		},
   210  		{
   211  			name: "IPCacheUpsertedMessage (insert)",
   212  			msg:  monitorAPI.IPCacheUpsertedMessage("10.0.1.42/32", 1023, nil, net.ParseIP("10.1.5.4"), nil, 0xff, "default", "foobar"),
   213  			ev: &flowpb.AgentEvent{
   214  				Type: flowpb.AgentEventType_IPCACHE_UPSERTED,
   215  				Notification: &flowpb.AgentEvent_IpcacheUpdate{
   216  					IpcacheUpdate: &flowpb.IPCacheNotification{
   217  						Cidr:        "10.0.1.42/32",
   218  						Identity:    1023,
   219  						OldIdentity: nil,
   220  						HostIp:      "10.1.5.4",
   221  						OldHostIp:   "",
   222  						EncryptKey:  0xff,
   223  						Namespace:   "default",
   224  						PodName:     "foobar",
   225  					},
   226  				},
   227  			},
   228  		},
   229  		{
   230  			name: "IPCacheUpsertedMessage (update)",
   231  			msg:  monitorAPI.IPCacheUpsertedMessage("192.168.10.11/32", 1023, &oldID, net.ParseIP("10.1.5.4"), net.ParseIP("10.2.6.11"), 5, "hubble", "podmcpodface"),
   232  			ev: &flowpb.AgentEvent{
   233  				Type: flowpb.AgentEventType_IPCACHE_UPSERTED,
   234  				Notification: &flowpb.AgentEvent_IpcacheUpdate{
   235  					IpcacheUpdate: &flowpb.IPCacheNotification{
   236  						Cidr:     "192.168.10.11/32",
   237  						Identity: 1023,
   238  						OldIdentity: &wrapperspb.UInt32Value{
   239  							Value: oldID,
   240  						},
   241  						HostIp:     "10.1.5.4",
   242  						OldHostIp:  "10.2.6.11",
   243  						EncryptKey: 5,
   244  						Namespace:  "hubble",
   245  						PodName:    "podmcpodface",
   246  					},
   247  				},
   248  			},
   249  		},
   250  		{
   251  			name: "IPCacheDeletedMessage",
   252  			msg:  monitorAPI.IPCacheDeletedMessage("192.168.10.0/24", 6048, nil, net.ParseIP("10.1.5.4"), nil, 0, "", ""),
   253  			ev: &flowpb.AgentEvent{
   254  				Type: flowpb.AgentEventType_IPCACHE_DELETED,
   255  				Notification: &flowpb.AgentEvent_IpcacheUpdate{
   256  					IpcacheUpdate: &flowpb.IPCacheNotification{
   257  						Cidr:        "192.168.10.0/24",
   258  						Identity:    6048,
   259  						OldIdentity: nil,
   260  						HostIp:      "10.1.5.4",
   261  						OldHostIp:   "",
   262  						EncryptKey:  0,
   263  						Namespace:   "",
   264  						PodName:     "",
   265  					},
   266  				},
   267  			},
   268  		},
   269  		{
   270  			name: "ServiceUpsertMessage",
   271  			msg: monitorAPI.ServiceUpsertMessage(
   272  				214,
   273  				monitorAPI.ServiceUpsertNotificationAddr{
   274  					IP:   net.ParseIP("10.240.12.1"),
   275  					Port: 8080,
   276  				},
   277  				[]monitorAPI.ServiceUpsertNotificationAddr{
   278  					{
   279  						IP:   net.ParseIP("192.168.3.59"),
   280  						Port: 9099,
   281  					},
   282  					{
   283  						IP:   net.ParseIP("192.168.3.57"),
   284  						Port: 7077,
   285  					},
   286  				},
   287  				"ClusterIP",
   288  				"myTrafficPolicyExt",
   289  				"myTrafficPolicyInt",
   290  				"myService",
   291  				"myNamespace",
   292  			),
   293  			ev: &flowpb.AgentEvent{
   294  				Type: flowpb.AgentEventType_SERVICE_UPSERTED,
   295  				Notification: &flowpb.AgentEvent_ServiceUpsert{
   296  					ServiceUpsert: &flowpb.ServiceUpsertNotification{
   297  						Id: 214,
   298  						FrontendAddress: &flowpb.ServiceUpsertNotificationAddr{
   299  							Ip:   "10.240.12.1",
   300  							Port: 8080,
   301  						},
   302  						BackendAddresses: []*flowpb.ServiceUpsertNotificationAddr{
   303  							{
   304  								Ip:   "192.168.3.59",
   305  								Port: 9099,
   306  							},
   307  							{
   308  								Ip:   "192.168.3.57",
   309  								Port: 7077,
   310  							},
   311  						},
   312  						Type:             "ClusterIP",
   313  						TrafficPolicy:    "myTrafficPolicyExt",
   314  						ExtTrafficPolicy: "myTrafficPolicyExt",
   315  						IntTrafficPolicy: "myTrafficPolicyInt",
   316  						Name:             "myService",
   317  						Namespace:        "myNamespace",
   318  					},
   319  				},
   320  			},
   321  		},
   322  		{
   323  			name: "ServiceDeleteMessage",
   324  			msg:  monitorAPI.ServiceDeleteMessage(1048575),
   325  			ev: &flowpb.AgentEvent{
   326  				Type: flowpb.AgentEventType_SERVICE_DELETED,
   327  				Notification: &flowpb.AgentEvent_ServiceDelete{
   328  					ServiceDelete: &flowpb.ServiceDeleteNotification{
   329  						Id: 1048575,
   330  					},
   331  				},
   332  			},
   333  		},
   334  	}
   335  
   336  	for _, tc := range tt {
   337  		t.Run(tc.name, func(t *testing.T) {
   338  			ev := agent.NotifyMessageToProto(tc.msg)
   339  			assert.Equal(t, tc.ev, ev)
   340  		})
   341  	}
   342  }