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 }