From f553cf1af9eb7ad2422e78f2a505316844a2e70d Mon Sep 17 00:00:00 2001 From: atulpatel261194 Date: Thu, 28 Mar 2024 09:22:27 -0700 Subject: [PATCH] fix(evpn): fix evpn and unit test Signed-off-by: atulpatel261194 Co-authored-by: Dimitrios Markou Co-authored-by: Venkatesh Vemula Co-authored-by: Banoth Saikumar Co-authored-by: Jambekar Vishakha --- cmd/network/evpn-logical-brige.go | 12 ++++++++---- cmd/network/evpn-vrf.go | 11 +++++------ network/bridge_port.go | 9 ++++++++- network/bridge_port_test.go | 4 +++- network/evpn.go | 4 ++-- network/logical_bridge.go | 23 +++++++++++++++++------ network/logical_bridge_test.go | 3 ++- network/svi.go | 9 ++++++++- network/svi_test.go | 5 ++++- network/vrf.go | 23 ++++++++++++++++------- network/vrf_test.go | 2 +- 11 files changed, 74 insertions(+), 31 deletions(-) diff --git a/cmd/network/evpn-logical-brige.go b/cmd/network/evpn-logical-brige.go index 3514330..eb1645f 100644 --- a/cmd/network/evpn-logical-brige.go +++ b/cmd/network/evpn-logical-brige.go @@ -28,6 +28,7 @@ func CreateLogicalBridge() *cobra.Command { Short: "Create a logical bridge", Long: "Create a logical bridge with the specified name, VLAN ID, and VNI", Run: func(_ *cobra.Command, _ []string) { + var vniparam *uint32 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) evpnClient, err := network.NewLogicalBridge(addr) if err != nil { @@ -35,7 +36,11 @@ func CreateLogicalBridge() *cobra.Command { } defer cancel() - lb, err := evpnClient.CreateLogicalBridge(ctx, name, vlanID, vni, vtep) + if vni != 0 { + vniparam = &vni + } + + lb, err := evpnClient.CreateLogicalBridge(ctx, name, vlanID, vniparam, vtep) if err != nil { log.Fatalf("failed to create logical bridge: %v", err) } @@ -59,9 +64,8 @@ func CreateLogicalBridge() *cobra.Command { if err := cmd.MarkFlagRequired("vlan-id"); err != nil { log.Fatalf("Error marking flag as required: %v", err) } - if err := cmd.MarkFlagRequired("vni"); err != nil { - log.Fatalf("Error marking flag as required: %v", err) - } + + cmd.MarkFlagsRequiredTogether("vni", "vtep") return cmd } diff --git a/cmd/network/evpn-vrf.go b/cmd/network/evpn-vrf.go index f66d6e1..5f5e0a3 100644 --- a/cmd/network/evpn-vrf.go +++ b/cmd/network/evpn-vrf.go @@ -27,14 +27,17 @@ func CreateVRF() *cobra.Command { Use: "create-vrf", Short: "Create a VRF", Run: func(_ *cobra.Command, _ []string) { + var vniparam *uint32 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) evpnClient, err := network.NewVRF(addr) if err != nil { log.Fatalf("could not create gRPC client: %v", err) } defer cancel() - - vrf, err := evpnClient.CreateVrf(ctx, name, vni, loopback, vtep) + if vni != 0 { + vniparam = &vni + } + vrf, err := evpnClient.CreateVrf(ctx, name, vniparam, loopback, vtep) if err != nil { log.Fatalf("failed to create vrf: %v", err) } @@ -49,10 +52,6 @@ func CreateVRF() *cobra.Command { cmd.Flags().StringVar(&vtep, "vtep", "", "VTEP IP address") cmd.Flags().StringVar(&addr, "addr", "localhost:50151", "address of OPI gRPC server") - if err := cmd.MarkFlagRequired("vni"); err != nil { - log.Fatalf("Error marking flag as required: %v", err) - } - if err := cmd.MarkFlagRequired("loopback"); err != nil { log.Fatalf("Error marking flag as required: %v", err) } diff --git a/network/bridge_port.go b/network/bridge_port.go index 7c21e6f..6269291 100644 --- a/network/bridge_port.go +++ b/network/bridge_port.go @@ -7,7 +7,9 @@ package network import ( "context" + "fmt" "log" + "net" pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go" "google.golang.org/protobuf/types/known/emptypb" @@ -25,6 +27,11 @@ func (c evpnClientImpl) CreateBridgePort(ctx context.Context, name string, mac s defer closer() client := c.getEvpnBridgePortClient(conn) + macBytes, err := net.ParseMAC(mac) + if err != nil { + fmt.Println("Error parsing MAC address:", err) + return nil, err + } switch bridgePortType { case "access": typeOfPort = pb.BridgePortType_BRIDGE_PORT_TYPE_ACCESS @@ -37,7 +44,7 @@ func (c evpnClientImpl) CreateBridgePort(ctx context.Context, name string, mac s BridgePortId: name, BridgePort: &pb.BridgePort{ Spec: &pb.BridgePortSpec{ - MacAddress: []byte(mac), + MacAddress: macBytes, Ptype: typeOfPort, LogicalBridges: logicalBridges, }, diff --git a/network/bridge_port_test.go b/network/bridge_port_test.go index 6498ff5..a6dd797 100644 --- a/network/bridge_port_test.go +++ b/network/bridge_port_test.go @@ -8,6 +8,7 @@ package network import ( "context" "errors" + "net" "testing" "github.com/opiproject/godpu/mocks" @@ -22,9 +23,10 @@ import ( ) func TestCreateBridgePort(t *testing.T) { + macBytes, _ := net.ParseMAC("00:11:22:aa:bb:cc") testBridgePort := &pb.BridgePort{ Spec: &pb.BridgePortSpec{ - MacAddress: []byte("00:11:22:aa:bb:cc"), + MacAddress: macBytes, Ptype: pb.BridgePortType_BRIDGE_PORT_TYPE_ACCESS, LogicalBridges: []string{"lb1", "lb2"}, }, diff --git a/network/evpn.go b/network/evpn.go index 400c8e9..ce7672b 100644 --- a/network/evpn.go +++ b/network/evpn.go @@ -41,7 +41,7 @@ type evpnClientImpl struct { type EvpnClient interface { // Logical Bridge interfaces - CreateLogicalBridge(ctx context.Context, name string, vlanID uint32, vni uint32, vtepIP string) (*pb.LogicalBridge, error) + CreateLogicalBridge(ctx context.Context, name string, vlanID uint32, vni *uint32, vtepIP string) (*pb.LogicalBridge, error) DeleteLogicalBridge(ctx context.Context, name string, allowMissing bool) (*emptypb.Empty, error) GetLogicalBridge(ctx context.Context, name string) (*pb.LogicalBridge, error) ListLogicalBridges(ctx context.Context, pageSize int32, pageToken string) (*pb.ListLogicalBridgesResponse, error) @@ -55,7 +55,7 @@ type EvpnClient interface { UpdateBridgePort(ctx context.Context, name string, updateMask []string, allowMissing bool) (*pb.BridgePort, error) // VRF Interfaces - CreateVrf(ctx context.Context, name string, vni uint32, loopback string, vtep string) (*pb.Vrf, error) + CreateVrf(ctx context.Context, name string, vni *uint32, loopback string, vtep string) (*pb.Vrf, error) DeleteVrf(ctx context.Context, name string, allowMissing bool) (*emptypb.Empty, error) GetVrf(ctx context.Context, name string) (*pb.Vrf, error) ListVrfs(ctx context.Context, pageSize int32, pageToken string) (*pb.ListVrfsResponse, error) diff --git a/network/logical_bridge.go b/network/logical_bridge.go index cc9e9b6..64aee26 100644 --- a/network/logical_bridge.go +++ b/network/logical_bridge.go @@ -7,15 +7,19 @@ package network import ( "context" + "errors" "log" pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go" + pc "github.com/opiproject/opi-api/network/opinetcommon/v1alpha1/gen/go" "google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/fieldmaskpb" ) // CreateLogicalBridge creates an Logical Bridge an OPI server -func (c evpnClientImpl) CreateLogicalBridge(ctx context.Context, name string, vlanID uint32, vni uint32, vtepIP string) (*pb.LogicalBridge, error) { +func (c evpnClientImpl) CreateLogicalBridge(ctx context.Context, name string, vlanID uint32, vni *uint32, vtepIP string) (*pb.LogicalBridge, error) { + var ipVtep *pc.IPPrefix + conn, closer, err := c.NewConn() if err != nil { log.Printf("error creating connection: %s\n", err) @@ -24,17 +28,24 @@ func (c evpnClientImpl) CreateLogicalBridge(ctx context.Context, name string, vl defer closer() client := c.getEvpnLogicalBridgeClient(conn) - ipVtep, err := parseIPAndPrefix(vtepIP) - if err != nil { - log.Printf("parseIPAndPrefix: error creating vrf: %s\n", err) - return nil, err + + if (vni == nil && vtepIP != "") || (vni != nil && vtepIP == "") { + return nil, errors.New("one of the required together parameter [vni, vtep] wasn't passed ") + } + + if vni != nil && vtepIP != "" { + ipVtep, err = parseIPAndPrefix(vtepIP) + if err != nil { + log.Printf("parseIPAndPrefix: error creating Logical Bridge: %s\n", err) + return nil, err + } } data, err := client.CreateLogicalBridge(ctx, &pb.CreateLogicalBridgeRequest{ LogicalBridgeId: name, LogicalBridge: &pb.LogicalBridge{ Spec: &pb.LogicalBridgeSpec{ VlanId: vlanID, - Vni: &vni, + Vni: vni, VtepIpPrefix: ipVtep, }, }, diff --git a/network/logical_bridge_test.go b/network/logical_bridge_test.go index 8f32523..0c9a0c0 100644 --- a/network/logical_bridge_test.go +++ b/network/logical_bridge_test.go @@ -23,6 +23,7 @@ import ( ) func TestCreateLogicalBridge(t *testing.T) { + testVni := uint32(500) wantIPPefix := &pc.IPPrefix{ Addr: &pc.IPAddress{ Af: pc.IpAf_IP_AF_INET, @@ -106,7 +107,7 @@ func TestCreateLogicalBridge(t *testing.T) { response, err := c.CreateLogicalBridge( context.Background(), - "lb1", 100, 500, "192.168.1.0/24", + "lb1", 100, &testVni, "192.168.1.0/24", ) assert.Equal(t, tt.wantErr, err) diff --git a/network/svi.go b/network/svi.go index d31423a..4de9628 100644 --- a/network/svi.go +++ b/network/svi.go @@ -7,7 +7,9 @@ package network import ( "context" + "fmt" "log" + "net" pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go" "google.golang.org/protobuf/types/known/emptypb" @@ -30,13 +32,18 @@ func (c evpnClientImpl) CreateSvi(ctx context.Context, name string, vrf string, log.Printf("error parsing GwIPs: %s\n", err) return nil, err } + macBytes, err := net.ParseMAC(mac) + if err != nil { + fmt.Println("Error parsing MAC address:", err) + return nil, err + } data, err := client.CreateSvi(ctx, &pb.CreateSviRequest{ SviId: name, Svi: &pb.Svi{ Spec: &pb.SviSpec{ Vrf: vrf, LogicalBridge: logicalBridge, - MacAddress: []byte(mac), + MacAddress: macBytes, GwIpPrefix: gwPrefixes, EnableBgp: ebgp, RemoteAs: remoteAS, diff --git a/network/svi_test.go b/network/svi_test.go index 36cf7d3..9e40707 100644 --- a/network/svi_test.go +++ b/network/svi_test.go @@ -8,6 +8,7 @@ package network import ( "context" "errors" + "net" "testing" "github.com/opiproject/godpu/mocks" @@ -33,11 +34,13 @@ func TestCreateSvi(t *testing.T) { Len: 32, }, } + macBytes, _ := net.ParseMAC("01:23:45:67:89:ab") + testSvi := &pb.Svi{ Spec: &pb.SviSpec{ Vrf: "vrf1", LogicalBridge: "logical1", - MacAddress: []byte("01:23:45:67:89:ab"), + MacAddress: macBytes, GwIpPrefix: wantGWPrefixes, EnableBgp: true, RemoteAs: 65000, diff --git a/network/vrf.go b/network/vrf.go index 4ab6751..146c006 100644 --- a/network/vrf.go +++ b/network/vrf.go @@ -7,16 +7,19 @@ package network import ( "context" + "errors" "log" pb "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go" + pc "github.com/opiproject/opi-api/network/opinetcommon/v1alpha1/gen/go" "google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/fieldmaskpb" ) // CreateVrf Create vrf on OPI Server -func (c evpnClientImpl) CreateVrf(ctx context.Context, name string, vni uint32, loopback string, vtep string) (*pb.Vrf, error) { +func (c evpnClientImpl) CreateVrf(ctx context.Context, name string, vni *uint32, loopbackIP string, vtepIP string) (*pb.Vrf, error) { conn, closer, err := c.NewConn() + var ipVtep *pc.IPPrefix if err != nil { log.Printf("error creating connection: %s\n", err) return nil, err @@ -24,21 +27,27 @@ func (c evpnClientImpl) CreateVrf(ctx context.Context, name string, vni uint32, defer closer() client := c.getEvpnVRFClient(conn) - ipLoopback, err := parseIPAndPrefix(loopback) + ipLoopback, err := parseIPAndPrefix(loopbackIP) if err != nil { log.Printf("parseIPAndPrefix: error creating vrf: %s\n", err) return nil, err } - ipVtep, err := parseIPAndPrefix(vtep) - if err != nil { - log.Printf("parseIPAndPrefix: error creating vrf: %s\n", err) - return nil, err + if (vni == nil && vtepIP != "") || (vni != nil && vtepIP == "") { + return nil, errors.New("one of the required together parameter [vni, vtep] wasn't passed ") + } + + if vni != nil && vtepIP != "" { + ipVtep, err = parseIPAndPrefix(vtepIP) + if err != nil { + log.Printf("parseIPAndPrefix: error creating vrf: %s\n", err) + return nil, err + } } data, err := client.CreateVrf(ctx, &pb.CreateVrfRequest{ VrfId: name, Vrf: &pb.Vrf{ Spec: &pb.VrfSpec{ - Vni: &vni, + Vni: vni, LoopbackIpPrefix: ipLoopback, VtepIpPrefix: ipVtep, }, diff --git a/network/vrf_test.go b/network/vrf_test.go index 822c2a4..f6c777e 100644 --- a/network/vrf_test.go +++ b/network/vrf_test.go @@ -100,7 +100,7 @@ func TestCreateVrf(t *testing.T) { }, ) - response, err := c.CreateVrf(context.Background(), "Vrf1", 100, "192.168.1.1/24", "10.0.0.1/32") + response, err := c.CreateVrf(context.Background(), "Vrf1", &vni, "192.168.1.1/24", "10.0.0.1/32") assert.Equal(t, tt.wantErr, err) assert.True(t, proto.Equal(response, tt.wantResponse))