diff --git a/docs/antctl.md b/docs/antctl.md index d4cc5ae9345..d3e1c276b30 100644 --- a/docs/antctl.md +++ b/docs/antctl.md @@ -826,6 +826,13 @@ ROUTE TYPE K8S-OBJ-REF fec0::192:168:77:100/128 EgressIP egress2 fd00:10:244:1::/64 NodeIPAMPodCIDR fec0::10:96:10:10/128 ServiceLoadBalancerIP default/svc2 + +# Get the list of all advertised routes of a specific type +$ antctl get bgproutes -T EgressIP + +ROUTE TYPE K8S-OBJ-REF +172.18.0.3/32 EgressIP egress1 +fec0::192:168:77:100/128 EgressIP egress2 ``` ### Upgrade existing objects of CRDs diff --git a/pkg/agent/apiserver/handlers/bgppeer/handler.go b/pkg/agent/apiserver/handlers/bgppeer/handler.go index 616e4d10635..08ef3937bb6 100644 --- a/pkg/agent/apiserver/handlers/bgppeer/handler.go +++ b/pkg/agent/apiserver/handlers/bgppeer/handler.go @@ -19,10 +19,13 @@ import ( "errors" "net" "net/http" + "net/netip" "reflect" + "slices" "strconv" "k8s.io/klog/v2" + utilnet "k8s.io/utils/net" "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/controller/bgp" @@ -59,7 +62,7 @@ func HandleFunc(bq querier.AgentBGPPolicyInfoQuerier) http.HandlerFunc { return } - peers, err := bq.GetBGPPeerStatus(r.Context(), !ipv6Only, !ipv4Only) + peers, err := bq.GetBGPPeerStatus(r.Context()) if err != nil { if errors.Is(err, bgp.ErrBGPPolicyNotFound) { http.Error(w, "there is no effective bgp policy applied to the Node", http.StatusNotFound) @@ -72,12 +75,31 @@ func HandleFunc(bq querier.AgentBGPPolicyInfoQuerier) http.HandlerFunc { var bgpPeersResp []apis.BGPPeerResponse for _, peer := range peers { + if ipv4Only && !utilnet.IsIPv4String(peer.Address) { + continue + } + if ipv6Only && !utilnet.IsIPv6String(peer.Address) { + continue + } bgpPeersResp = append(bgpPeersResp, apis.BGPPeerResponse{ Peer: net.JoinHostPort(peer.Address, strconv.Itoa(int(peer.Port))), ASN: peer.ASN, State: string(peer.SessionState), }) } + // make sure that we provide a stable order for the API response + slices.SortFunc(bgpPeersResp, func(a, b apis.BGPPeerResponse) int { + addrPortA, _ := netip.ParseAddrPort(a.Peer) + addrPortB, _ := netip.ParseAddrPort(b.Peer) + // IPv4 routes first, then IPv6 routes + if addrPortA.Addr().Is4() && !addrPortB.Addr().Is4() { + return -1 + } + if !addrPortA.Addr().Is4() && addrPortB.Addr().Is4() { + return 1 + } + return addrPortA.Compare(addrPortB) + }) if err := json.NewEncoder(w).Encode(bgpPeersResp); err != nil { w.WriteHeader(http.StatusInternalServerError) diff --git a/pkg/agent/apiserver/handlers/bgppeer/handler_test.go b/pkg/agent/apiserver/handlers/bgppeer/handler_test.go index aab1846ddde..f67ec57c80b 100644 --- a/pkg/agent/apiserver/handlers/bgppeer/handler_test.go +++ b/pkg/agent/apiserver/handlers/bgppeer/handler_test.go @@ -31,6 +31,35 @@ import ( queriertest "antrea.io/antrea/pkg/querier/testing" ) +var ( + bgpPeerStatus = []bgp.PeerStatus{ + { + Address: "192.168.77.201", + Port: 179, + ASN: 65002, + SessionState: bgp.SessionActive, + }, + { + Address: "fec0::196:168:77:252", + Port: 179, + ASN: 65002, + SessionState: bgp.SessionActive, + }, + { + Address: "192.168.77.200", + Port: 179, + ASN: 65001, + SessionState: bgp.SessionEstablished, + }, + { + Address: "fec0::196:168:77:251", + Port: 179, + ASN: 65001, + SessionState: bgp.SessionEstablished, + }, + } +) + func TestBGPPeerQuery(t *testing.T) { ctx := context.Background() tests := []struct { @@ -44,21 +73,7 @@ func TestBGPPeerQuery(t *testing.T) { name: "get ipv4 bgp peers only", url: "?ipv4-only", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPPeerStatus(ctx, true, false).Return( - []bgp.PeerStatus{ - { - Address: "192.168.77.200", - Port: 179, - ASN: 65001, - SessionState: bgp.SessionEstablished, - }, - { - Address: "192.168.77.201", - Port: 179, - ASN: 65002, - SessionState: bgp.SessionActive, - }, - }, nil) + mockBGPServer.EXPECT().GetBGPPeerStatus(ctx).Return(bgpPeerStatus, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPPeerResponse{ @@ -78,21 +93,7 @@ func TestBGPPeerQuery(t *testing.T) { name: "get ipv6 bgp peers only", url: "?ipv6-only=", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPPeerStatus(ctx, false, true).Return( - []bgp.PeerStatus{ - { - Address: "fec0::196:168:77:251", - Port: 179, - ASN: 65001, - SessionState: bgp.SessionEstablished, - }, - { - Address: "fec0::196:168:77:252", - Port: 179, - ASN: 65002, - SessionState: bgp.SessionActive, - }, - }, nil) + mockBGPServer.EXPECT().GetBGPPeerStatus(ctx).Return(bgpPeerStatus, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPPeerResponse{ @@ -111,21 +112,7 @@ func TestBGPPeerQuery(t *testing.T) { { name: "get all bgp peers", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPPeerStatus(ctx, true, true).Return( - []bgp.PeerStatus{ - { - Address: "192.168.77.200", - Port: 179, - ASN: 65001, - SessionState: bgp.SessionEstablished, - }, - { - Address: "fec0::196:168:77:251", - Port: 179, - ASN: 65002, - SessionState: bgp.SessionActive, - }, - }, nil) + mockBGPServer.EXPECT().GetBGPPeerStatus(ctx).Return(bgpPeerStatus, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPPeerResponse{ @@ -134,8 +121,18 @@ func TestBGPPeerQuery(t *testing.T) { ASN: 65001, State: "Established", }, + { + Peer: "192.168.77.201:179", + ASN: 65002, + State: "Active", + }, { Peer: "[fec0::196:168:77:251]:179", + ASN: 65001, + State: "Established", + }, + { + Peer: "[fec0::196:168:77:252]:179", ASN: 65002, State: "Active", }, @@ -144,7 +141,7 @@ func TestBGPPeerQuery(t *testing.T) { { name: "bgpPolicyState does not exist", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPPeerStatus(ctx, true, true).Return(nil, bgpcontroller.ErrBGPPolicyNotFound) + mockBGPServer.EXPECT().GetBGPPeerStatus(ctx).Return(nil, bgpcontroller.ErrBGPPolicyNotFound) }, expectedStatus: http.StatusNotFound, }, diff --git a/pkg/agent/apiserver/handlers/bgproute/handler.go b/pkg/agent/apiserver/handlers/bgproute/handler.go index 477a612830b..bdc06cc8b59 100644 --- a/pkg/agent/apiserver/handlers/bgproute/handler.go +++ b/pkg/agent/apiserver/handlers/bgproute/handler.go @@ -24,6 +24,7 @@ import ( "strings" "k8s.io/klog/v2" + utilnet "k8s.io/utils/net" "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/controller/bgp" @@ -40,6 +41,7 @@ func HandleFunc(bq querier.AgentBGPPolicyInfoQuerier) http.HandlerFunc { } values := r.URL.Query() + bgpRouteType := values.Get("type") var ipv4Only, ipv6Only bool if values.Has("ipv4-only") { if values.Get("ipv4-only") != "" { @@ -60,7 +62,7 @@ func HandleFunc(bq querier.AgentBGPPolicyInfoQuerier) http.HandlerFunc { return } - bgpRoutes, err := bq.GetBGPRoutes(r.Context(), !ipv6Only, !ipv4Only) + bgpRoutes, err := bq.GetBGPRoutes(r.Context()) if err != nil { if errors.Is(err, bgp.ErrBGPPolicyNotFound) { http.Error(w, "there is no effective bgp policy applied to the Node", http.StatusNotFound) @@ -71,11 +73,20 @@ func HandleFunc(bq querier.AgentBGPPolicyInfoQuerier) http.HandlerFunc { } var bgpRoutesResp []apis.BGPRouteResponse - for bgpRoute := range bgpRoutes { + for bgpRoute, routeMetadata := range bgpRoutes { + if ipv4Only && !utilnet.IsIPv4CIDRString(bgpRoute.Prefix) { + continue + } + if ipv6Only && !utilnet.IsIPv6CIDRString(bgpRoute.Prefix) { + continue + } + if bgpRouteType != "" && bgpRouteType != string(routeMetadata.Type) { + continue + } bgpRoutesResp = append(bgpRoutesResp, apis.BGPRouteResponse{ Route: bgpRoute.Prefix, - Type: string(bgpRoutes[bgpRoute].Type), - K8sObjRef: bgpRoutes[bgpRoute].K8sObjRef, + Type: string(routeMetadata.Type), + K8sObjRef: routeMetadata.K8sObjRef, }) } // make sure that we provide a stable order for the API response diff --git a/pkg/agent/apiserver/handlers/bgproute/handler_test.go b/pkg/agent/apiserver/handlers/bgproute/handler_test.go index b8cd0f7a75a..46465f4756c 100644 --- a/pkg/agent/apiserver/handlers/bgproute/handler_test.go +++ b/pkg/agent/apiserver/handlers/bgproute/handler_test.go @@ -43,17 +43,21 @@ var ( podIPv4CIDRRoute = bgp.Route{Prefix: podIPv4CIDR} clusterIPv4 = "10.96.10.10" clusterIPv4Route = bgp.Route{Prefix: ipStrToPrefix(clusterIPv4)} + egressIPv4 = "10.96.11.10" + egressIPv4Route = bgp.Route{Prefix: ipStrToPrefix(egressIPv4)} loadBalancerIPv6 = "fec0::192:168:77:150" loadBalancerIPv6Route = bgp.Route{Prefix: ipStrToPrefix(loadBalancerIPv6)} egressIPv6 = "fec0::192:168:77:200" egressIPv6Route = bgp.Route{Prefix: ipStrToPrefix(egressIPv6)} ipv4ClusterIPName = "clusterip-4" + ipv4EgressName = "egress-4" ipv6LoadBalancerName = "loadbalancer-6" ipv6EgressName = "egress-6" allRoutes = map[bgp.Route]bgpcontroller.RouteMetadata{ clusterIPv4Route: {Type: bgpcontroller.ServiceClusterIP, K8sObjRef: getServiceName(ipv4ClusterIPName)}, + egressIPv4Route: {Type: bgpcontroller.EgressIP, K8sObjRef: ipv4EgressName}, loadBalancerIPv6Route: {Type: bgpcontroller.ServiceLoadBalancerIP, K8sObjRef: getServiceName(ipv6LoadBalancerName)}, egressIPv6Route: {Type: bgpcontroller.EgressIP, K8sObjRef: ipv6EgressName}, podIPv4CIDRRoute: {Type: bgpcontroller.NodeIPAMPodCIDR}, @@ -72,22 +76,22 @@ func TestBGPRouteQuery(t *testing.T) { { name: "bgpPolicyState does not exist", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPRoutes(context.Background(), true, true).Return(nil, bgpcontroller.ErrBGPPolicyNotFound) + mockBGPServer.EXPECT().GetBGPRoutes(context.Background()).Return(nil, bgpcontroller.ErrBGPPolicyNotFound) }, expectedStatus: http.StatusNotFound, }, { name: "get all advertised routes", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPRoutes(ctx, true, true).Return( - map[bgp.Route]bgpcontroller.RouteMetadata{ - clusterIPv4Route: allRoutes[clusterIPv4Route], - podIPv4CIDRRoute: allRoutes[podIPv4CIDRRoute], - egressIPv6Route: allRoutes[egressIPv6Route], - }, nil) + mockBGPServer.EXPECT().GetBGPRoutes(ctx).Return(allRoutes, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPRouteResponse{ + { + Route: egressIPv4Route.Prefix, + Type: string(allRoutes[egressIPv4Route].Type), + K8sObjRef: allRoutes[egressIPv4Route].K8sObjRef, + }, { Route: podIPv4CIDR, Type: string(bgpcontroller.NodeIPAMPodCIDR), @@ -102,20 +106,26 @@ func TestBGPRouteQuery(t *testing.T) { Type: string(allRoutes[egressIPv6Route].Type), K8sObjRef: allRoutes[egressIPv6Route].K8sObjRef, }, + { + Route: loadBalancerIPv6Route.Prefix, + Type: string(allRoutes[loadBalancerIPv6Route].Type), + K8sObjRef: allRoutes[loadBalancerIPv6Route].K8sObjRef, + }, }, }, { name: "get advertised ipv4 routes only", url: "?ipv4-only", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPRoutes(ctx, true, false).Return( - map[bgp.Route]bgpcontroller.RouteMetadata{ - clusterIPv4Route: allRoutes[clusterIPv4Route], - podIPv4CIDRRoute: allRoutes[podIPv4CIDRRoute], - }, nil) + mockBGPServer.EXPECT().GetBGPRoutes(ctx).Return(allRoutes, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPRouteResponse{ + { + Route: egressIPv4Route.Prefix, + Type: string(allRoutes[egressIPv4Route].Type), + K8sObjRef: allRoutes[egressIPv4Route].K8sObjRef, + }, { Route: podIPv4CIDRRoute.Prefix, Type: string(allRoutes[podIPv4CIDRRoute].Type), @@ -131,11 +141,7 @@ func TestBGPRouteQuery(t *testing.T) { name: "get advertised ipv6 routes only", url: "?ipv6-only=", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { - mockBGPServer.EXPECT().GetBGPRoutes(ctx, false, true).Return( - map[bgp.Route]bgpcontroller.RouteMetadata{ - loadBalancerIPv6Route: allRoutes[loadBalancerIPv6Route], - egressIPv6Route: allRoutes[egressIPv6Route], - }, nil) + mockBGPServer.EXPECT().GetBGPRoutes(ctx).Return(allRoutes, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPRouteResponse{ @@ -161,6 +167,41 @@ func TestBGPRouteQuery(t *testing.T) { url: "?ipv4-only&ipv6-only", expectedStatus: http.StatusBadRequest, }, + { + name: "get all advertised egressIP routes", + url: "?type=EgressIP", + expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { + mockBGPServer.EXPECT().GetBGPRoutes(ctx).Return(allRoutes, nil) + }, + expectedStatus: http.StatusOK, + expectedResponse: []apis.BGPRouteResponse{ + { + Route: egressIPv4Route.Prefix, + Type: string(allRoutes[egressIPv4Route].Type), + K8sObjRef: allRoutes[egressIPv4Route].K8sObjRef, + }, + { + Route: egressIPv6Route.Prefix, + Type: string(allRoutes[egressIPv6Route].Type), + K8sObjRef: allRoutes[egressIPv6Route].K8sObjRef, + }, + }, + }, + { + name: "get advertised IPv4 egressIP routes", + url: "?ipv4-only&type=EgressIP", + expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { + mockBGPServer.EXPECT().GetBGPRoutes(ctx).Return(allRoutes, nil) + }, + expectedStatus: http.StatusOK, + expectedResponse: []apis.BGPRouteResponse{ + { + Route: egressIPv4Route.Prefix, + Type: string(allRoutes[egressIPv4Route].Type), + K8sObjRef: allRoutes[egressIPv4Route].K8sObjRef, + }, + }, + }, } for _, tt := range tests { diff --git a/pkg/agent/controller/bgp/controller.go b/pkg/agent/controller/bgp/controller.go index 6070bb85bee..185301ec470 100644 --- a/pkg/agent/controller/bgp/controller.go +++ b/pkg/agent/controller/bgp/controller.go @@ -1001,7 +1001,7 @@ func (c *Controller) GetBGPPolicyInfo() (string, string, int32, int32) { } // GetBGPPeerStatus returns current status of BGP Peers of effective BGP Policy applied on the Node. -func (c *Controller) GetBGPPeerStatus(ctx context.Context, ipv4Peers, ipv6Peers bool) ([]bgp.PeerStatus, error) { +func (c *Controller) GetBGPPeerStatus(ctx context.Context) ([]bgp.PeerStatus, error) { getBgpServer := func() bgp.Interface { c.bgpPolicyStateMutex.RLock() defer c.bgpPolicyStateMutex.RUnlock() @@ -1019,27 +1019,11 @@ func (c *Controller) GetBGPPeerStatus(ctx context.Context, ipv4Peers, ipv6Peers if err != nil { return nil, fmt.Errorf("failed to get bgp peers: %w", err) } - - peers := make([]bgp.PeerStatus, 0, len(allPeers)) - if ipv4Peers { // insert IPv4 peers - for _, peer := range allPeers { - if utilnet.IsIPv4String(peer.Address) { - peers = append(peers, peer) - } - } - } - if ipv6Peers { // insert IPv6 peers - for _, peer := range allPeers { - if utilnet.IsIPv6String(peer.Address) { - peers = append(peers, peer) - } - } - } - return peers, nil + return allPeers, nil } // GetBGPRoutes returns the advertised BGP routes. -func (c *Controller) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) (map[bgp.Route]RouteMetadata, error) { +func (c *Controller) GetBGPRoutes(ctx context.Context) (map[bgp.Route]RouteMetadata, error) { c.bgpPolicyStateMutex.RLock() defer c.bgpPolicyStateMutex.RUnlock() @@ -1048,12 +1032,8 @@ func (c *Controller) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bo } bgpRoutes := make(map[bgp.Route]RouteMetadata) - for route := range c.bgpPolicyState.routes { - if ipv4Routes && utilnet.IsIPv4CIDRString(route.Prefix) { - bgpRoutes[route] = c.bgpPolicyState.routes[route] - } else if ipv6Routes && utilnet.IsIPv6CIDRString(route.Prefix) { - bgpRoutes[route] = c.bgpPolicyState.routes[route] - } + for route, routeMetadata := range c.bgpPolicyState.routes { + bgpRoutes[route] = routeMetadata } return bgpRoutes, nil } diff --git a/pkg/agent/controller/bgp/controller_test.go b/pkg/agent/controller/bgp/controller_test.go index d275ab7c226..dc193ae2db1 100644 --- a/pkg/agent/controller/bgp/controller_test.go +++ b/pkg/agent/controller/bgp/controller_test.go @@ -2210,37 +2210,13 @@ func TestGetBGPPeerStatus(t *testing.T) { ctx := context.Background() testCases := []struct { name string - ipv4Peers bool - ipv6Peers bool existingState *bgpPolicyState expectedCalls func(mockBGPServer *bgptest.MockInterfaceMockRecorder) expectedBgpPeerStatus []bgp.PeerStatus expectedErr error }{ { - name: "get ipv4 bgp peers", - ipv4Peers: true, - existingState: &bgpPolicyState{}, - expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { - mockBGPServer.GetPeers(ctx).Return([]bgp.PeerStatus{ipv4Peer1Status, ipv4Peer2Status, - ipv6Peer1Status, ipv6Peer2Status}, nil) - }, - expectedBgpPeerStatus: []bgp.PeerStatus{ipv4Peer1Status, ipv4Peer2Status}, - }, - { - name: "get ipv6 bgp peers", - ipv6Peers: true, - existingState: &bgpPolicyState{}, - expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { - mockBGPServer.GetPeers(ctx).Return([]bgp.PeerStatus{ipv4Peer1Status, ipv4Peer2Status, - ipv6Peer1Status, ipv6Peer2Status}, nil) - }, - expectedBgpPeerStatus: []bgp.PeerStatus{ipv6Peer1Status, ipv6Peer2Status}, - }, - { - name: "get all bgp peers", - ipv4Peers: true, - ipv6Peers: true, + name: "get bgp peers status", existingState: &bgpPolicyState{}, expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { mockBGPServer.GetPeers(ctx).Return([]bgp.PeerStatus{ipv4Peer1Status, ipv4Peer2Status, @@ -2255,7 +2231,7 @@ func TestGetBGPPeerStatus(t *testing.T) { } for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - c := newFakeController(t, nil, nil, tt.ipv4Peers, tt.ipv6Peers) + c := newFakeController(t, nil, nil, true, true) // Fake the BGPPolicy state. c.bgpPolicyState = tt.existingState @@ -2267,7 +2243,7 @@ func TestGetBGPPeerStatus(t *testing.T) { tt.expectedCalls(c.mockBGPServer.EXPECT()) } - actualBgpPeerStatus, err := c.GetBGPPeerStatus(ctx, tt.ipv4Peers, tt.ipv6Peers) + actualBgpPeerStatus, err := c.GetBGPPeerStatus(ctx) if tt.expectedErr != nil { assert.ErrorIs(t, err, tt.expectedErr) } else { @@ -2290,16 +2266,12 @@ func TestGetBGPRoutes(t *testing.T) { ctx := context.Background() testCases := []struct { name string - ipv4Routes bool - ipv6Routes bool existingState *bgpPolicyState expectedBgpRoutes map[bgp.Route]RouteMetadata expectedErr string }{ { - name: "get all advertised routes", - ipv4Routes: true, - ipv6Routes: true, + name: "get advertised routes", existingState: effectivePolicyState, expectedBgpRoutes: map[bgp.Route]RouteMetadata{ clusterIPv4Route1: allRoutes[clusterIPv4Route1], @@ -2310,40 +2282,19 @@ func TestGetBGPRoutes(t *testing.T) { podIPv6CIDRRoute: allRoutes[podIPv6CIDRRoute], }, }, - { - name: "get advertised ipv4 routes only", - ipv4Routes: true, - existingState: effectivePolicyState, - expectedBgpRoutes: map[bgp.Route]RouteMetadata{ - clusterIPv4Route1: allRoutes[clusterIPv4Route1], - loadBalancerIPv4Route: allRoutes[loadBalancerIPv4Route], - podIPv4CIDRRoute: allRoutes[podIPv4CIDRRoute], - }, - }, - { - name: "get advertised ipv6 routes only", - ipv6Routes: true, - existingState: effectivePolicyState, - expectedBgpRoutes: map[bgp.Route]RouteMetadata{ - clusterIPv6Route1: allRoutes[clusterIPv6Route1], - loadBalancerIPv6Route: allRoutes[loadBalancerIPv6Route], - podIPv6CIDRRoute: allRoutes[podIPv6CIDRRoute], - }, - }, { name: "bgpPolicyState does not exist", - ipv4Routes: true, expectedErr: ErrBGPPolicyNotFound.Error(), }, } for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - c := newFakeController(t, nil, nil, tt.ipv4Routes, tt.ipv6Routes) + c := newFakeController(t, nil, nil, true, true) // Fake the BGPPolicy state. c.bgpPolicyState = tt.existingState - actualBgpRoutes, err := c.GetBGPRoutes(ctx, tt.ipv4Routes, tt.ipv6Routes) + actualBgpRoutes, err := c.GetBGPRoutes(ctx) if tt.expectedErr != "" { assert.EqualError(t, err, tt.expectedErr) } else { diff --git a/pkg/antctl/antctl.go b/pkg/antctl/antctl.go index 67629efb1b6..78981fcfe86 100644 --- a/pkg/antctl/antctl.go +++ b/pkg/antctl/antctl.go @@ -696,6 +696,8 @@ $ antctl get podmulticaststats pod -n namespace`, $ antctl get bgproutes --ipv4-only Get the list of advertised IPv6 bgp routes $ antctl get bgproutes --ipv6-only + Get the list of all advertised routes of a specific type + $ antctl get bgproutes -T EgressIP `, agentEndpoint: &endpoint{ nonResourceEndpoint: &nonResourceEndpoint{ @@ -711,6 +713,12 @@ $ antctl get podmulticaststats pod -n namespace`, usage: "Get advertised IPv6 bgp routes only", isBool: true, }, + { + name: "type", + shorthand: "T", + usage: "Get advertised bgp routes of a specific type. Valid types are EgressIP, ServiceLoadBalancerIP, ServiceExternalIP, ServiceClusterIP or NodeIPAMPodCIDR.", + supportedValues: []string{"EgressIP", "ServiceLoadBalancerIP", "ServiceExternalIP", "ServiceClusterIP", "NodeIPAMPodCIDR"}, + }, }, outputType: multiple, }, diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index 156e645f66f..e6e9ec0e78e 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -147,7 +147,7 @@ type AgentBGPPolicyInfoQuerier interface { // GetBGPPolicyInfo returns Name, RouterID, LocalASN and ListenPort of effective BGP Policy applied on the Node. GetBGPPolicyInfo() (string, string, int32, int32) // GetBGPPeerStatus returns current status of BGP Peers of effective BGP Policy applied on the Node. - GetBGPPeerStatus(ctx context.Context, ipv4Peers, ipv6Peers bool) ([]bgp.PeerStatus, error) + GetBGPPeerStatus(ctx context.Context) ([]bgp.PeerStatus, error) // GetBGPRoutes returns the advertised BGP routes. - GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) (map[bgp.Route]bgpcontroller.RouteMetadata, error) + GetBGPRoutes(ctx context.Context) (map[bgp.Route]bgpcontroller.RouteMetadata, error) } diff --git a/pkg/querier/testing/mock_querier.go b/pkg/querier/testing/mock_querier.go index fa27dc7f9a5..59b14b6d757 100644 --- a/pkg/querier/testing/mock_querier.go +++ b/pkg/querier/testing/mock_querier.go @@ -365,18 +365,18 @@ func (m *MockAgentBGPPolicyInfoQuerier) EXPECT() *MockAgentBGPPolicyInfoQuerierM } // GetBGPPeerStatus mocks base method. -func (m *MockAgentBGPPolicyInfoQuerier) GetBGPPeerStatus(ctx context.Context, ipv4Peers, ipv6Peers bool) ([]bgp.PeerStatus, error) { +func (m *MockAgentBGPPolicyInfoQuerier) GetBGPPeerStatus(ctx context.Context) ([]bgp.PeerStatus, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBGPPeerStatus", ctx, ipv4Peers, ipv6Peers) + ret := m.ctrl.Call(m, "GetBGPPeerStatus", ctx) ret0, _ := ret[0].([]bgp.PeerStatus) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBGPPeerStatus indicates an expected call of GetBGPPeerStatus. -func (mr *MockAgentBGPPolicyInfoQuerierMockRecorder) GetBGPPeerStatus(ctx, ipv4Peers, ipv6Peers any) *gomock.Call { +func (mr *MockAgentBGPPolicyInfoQuerierMockRecorder) GetBGPPeerStatus(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBGPPeerStatus", reflect.TypeOf((*MockAgentBGPPolicyInfoQuerier)(nil).GetBGPPeerStatus), ctx, ipv4Peers, ipv6Peers) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBGPPeerStatus", reflect.TypeOf((*MockAgentBGPPolicyInfoQuerier)(nil).GetBGPPeerStatus), ctx) } // GetBGPPolicyInfo mocks base method. @@ -397,16 +397,16 @@ func (mr *MockAgentBGPPolicyInfoQuerierMockRecorder) GetBGPPolicyInfo() *gomock. } // GetBGPRoutes mocks base method. -func (m *MockAgentBGPPolicyInfoQuerier) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) (map[bgp.Route]bgp0.RouteMetadata, error) { +func (m *MockAgentBGPPolicyInfoQuerier) GetBGPRoutes(ctx context.Context) (map[bgp.Route]bgp0.RouteMetadata, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBGPRoutes", ctx, ipv4Routes, ipv6Routes) + ret := m.ctrl.Call(m, "GetBGPRoutes", ctx) ret0, _ := ret[0].(map[bgp.Route]bgp0.RouteMetadata) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBGPRoutes indicates an expected call of GetBGPRoutes. -func (mr *MockAgentBGPPolicyInfoQuerierMockRecorder) GetBGPRoutes(ctx, ipv4Routes, ipv6Routes any) *gomock.Call { +func (mr *MockAgentBGPPolicyInfoQuerierMockRecorder) GetBGPRoutes(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBGPRoutes", reflect.TypeOf((*MockAgentBGPPolicyInfoQuerier)(nil).GetBGPRoutes), ctx, ipv4Routes, ipv6Routes) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBGPRoutes", reflect.TypeOf((*MockAgentBGPPolicyInfoQuerier)(nil).GetBGPRoutes), ctx) }