Code Monkey home page Code Monkey logo

opi-evpn-bridge's Introduction

OPI gRPC to EVPN GW FRR bridge

Linters CodeQL OpenSSF Scorecard tests Docker License codecov Go Report Card Go Doc Pulls Last Release GitHub stars GitHub Contributors

This repo includes OPI reference code for EVPN Gateway based on FRR. The specification for these APIs can be found here.

I Want To Contribute

This project welcomes contributions and suggestions. We are happy to have the Community involved via submission of Issues and Pull Requests (with substantive content or even just fixes). We are hoping for the documents, test framework, etc. to become a community process with active engagement. PRs can be reviewed by by any number of people, and a maintainer may accept.

See CONTRIBUTING and GitHub Basic Process for more details.

Getting started

โ— docker-compose is deprecated. For details, see Migrate to Compose V2.

Run docker-compose up -d or docker compose up -d

Manual gRPC example

using grpcurl

# create
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"vrf" : {"spec" : {"vni" : 1234, "loopback_ip_prefix" : {"addr": {"af": "IP_AF_INET", "v4_addr": 167772162} }, "len": 24}, "vtep_ip_prefix": {"addr": {"af": "IP_AF_INET", "v4_addr": 167772162} }, "len": 24} }}, "vrf_id" : "testvrf" }' localhost:50151 opi_api.network.evpn_gw.v1alpha1.VrfService.CreateVrf"
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"logical_bridge" : {"spec" : {"vni": 10, "vlan_id": 10 } }, "logical_bridge_id" : "testbridge" }' localhost:50151 opi_api.network.evpn_gw.v1alpha1.LogicalBridgeService.CreateLogicalBridge
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"bridge_port" : {"spec" : {mac_address: "qrvMAAAB", "ptype": "BRIDGE_PORT_TYPE_ACCESS", "logical_bridges": ["//network.opiproject.org/bridges/testbridge"] }}, "bridge_port_id" : "testport"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.CreateBridgePort
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"svi" : {"spec" : {"vrf": "//network.opiproject.org/vrfs/testvrf", "logical_bridge": "//network.opiproject.org/bridges/testbridge", mac_address: "qrvMAAAB", "gw_ip_prefix": [{"addr": {"af": "IP_AF_INET", "v4_addr": 167772162} }, "len": 24}] } }, "svi_id" : "testsvi" }' localhost:50151 opi_api.network.evpn_gw.v1alpha1.SviService.CreateSvi
# get
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name": "//network.opiproject.org/ports/testinterface"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.GetBridgePort
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name": "//network.opiproject.org/bridges/testbridge"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.LogicalBridgeService.GetLogicalBridge
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name": "//network.opiproject.org/svis/testsvi"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.SviService.GetSvi
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name": "//network.opiproject.org/vrfs/testvrf"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.VrfService.GetVrf
#list
docker-compose exec opi-evpn-bridge grpcurl -plaintext localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.ListBridgePorts
docker-compose exec opi-evpn-bridge grpcurl -plaintext localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.ListLogicalBridges
docker-compose exec opi-evpn-bridge grpcurl -plaintext localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.ListSvis
docker-compose exec opi-evpn-bridge grpcurl -plaintext localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.ListVrfs
# delete
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name": "//network.opiproject.org/ports/testinterface"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.BridgePortService.DeleteBridgePort
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name": "//network.opiproject.org/bridges/testbridge"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.LogicalBridgeService.DeleteLogicalBridge
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name" : "//network.opiproject.org/svis/testsvi"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.SviService.DeleteSvi
docker-compose exec opi-evpn-bridge grpcurl -plaintext -d '{"name" : "//network.opiproject.org/vrfs/testvrf"}' localhost:50151 opi_api.network.evpn_gw.v1alpha1.VrfService.DeleteVrf

using grpc_cli

$ docker run --rm -it --network=container:opi-evpn-bridge-opi-evpn-bridge-1 docker.io/namely/grpc-cli ls localhost:50151
grpc.reflection.v1.ServerReflection
grpc.reflection.v1alpha.ServerReflection
opi_api.network.evpn_gw.v1alpha1.BridgePortService
opi_api.network.evpn_gw.v1alpha1.LogicalBridgeService
opi_api.network.evpn_gw.v1alpha1.SviService
opi_api.network.evpn_gw.v1alpha1.VrfService

$ docker run --rm -it --network=container:opi-evpn-bridge-opi-evpn-bridge-1 docker.io/namely/grpc-cli call localhost:50151 VrfService.ListVrfs ""
connecting to localhost:50151
...
Rpc succeeded with OK status

using godpu

$ docker run --rm -it --network=host docker.io/opiproject/godpu:main evpn --help
Tests DPU evpn functionality

Usage:
  godpu evpn [flags]
  godpu evpn [command]

Aliases:
  evpn, g

Available Commands:
  create-bp   Create a bridge port
  create-lb   Create a logical bridge
  create-svi  Create a SVI
  create-vrf  Create a VRF
  delete-bp   Delete a bridge port
  delete-lb   Delete a logical bridge
  delete-svi  Delete a SVI
  delete-vrf  Delete a VRF
  get-bp      Show details of a bridge port
  get-lb      Show details of a logical bridge
  get-svi     Show details of a SVI
  get-vrf     Show details of a VRF
  list-bps    Show details of all bridge ports
  list-lbs    Show details of all logical bridges
  list-svis   Show details of all SVIs
  list-vrfs   Show details of all Vrfs
  update-bp   Update the bridge port
  update-lb   update the logical bridge
  update-svi  update the SVI
  update-vrf  update the VRF

Flags:
  -h, --help   help for evpn

Use "godpu evpn [command] --help" for more information about a command.

Manual HTTP example

In addition HTTP is supported via grpc gateway, for example:

curl -kL http://10.10.10.10:8082/v1/inventory/1/inventory/2

Architecture Diagram

OPI EVPN Bridge Architcture Diagram

Tests

Test your APIs even if unmerged using your private fork like this:

chmod a+w go.*
docker run --rm -it -v `pwd`:/app -w /app golang:alpine go mod edit -replace github.com/opiproject/opi-api@main=github.com/YOURUSERNAME/opi-api@main
docker run --rm -it -v `pwd`:/app -w /app golang:alpine go get -u github.com/YOURUSERNAME/opi-api/network/evpn-gw/v1alpha1/gen/go@0e2810d
docker run --rm -it -v `pwd`:/app -w /app golang:alpine go mod tidy

Generate mocks like this:

go install github.com/vektra/mockery/v2@latest
make mock-generate

# or using docker
docker run -v "$PWD":/src -w /src vektra/mockery --config=utils/mocks/.mockery.yaml --name=Netlink --dir pkg/utils --output pkg/utils/mocks --boilerplate-file pkg/utils/mocks/boilerplate.txt --with-expecter

POC diagrams

OPI EVPN Bridge POC Diagram for CI/CD OPI EVPN Bridge Diagram for L2VXLAN OPI EVPN Bridge Diagram for L3VXLAN Asymmetric IRB OPI EVPN Bridge Diagram for L3VXLAN Symmetric IRB OPI EVPN Bridge Diagram for L2VXLAN in_Symmetric IRB OPI EVPN Bridge Diagram for Leaf1_Detailed_View

opi-evpn-bridge's People

Contributors

artek-koltun avatar atulpatel261194 avatar glimchb avatar inbanoth avatar mardim91 avatar renovate[bot] avatar sandersms avatar udhay-104 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

opi-evpn-bridge's Issues

netlink: howto `type bridge_slave neigh_suppress on learning off`

see

      ip link add vni101 type vxlan local 10.0.0.2 dstport 4789 id 101 nolearning && \
      ip link set vni101 master br101 addrgenmode none && \
      ip link set vni101 type bridge_slave neigh_suppress on learning off && \
      ip link set vni101 up && \

vs from https://github.com/vishvananda/netlink

	vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: resourceID}, VxlanId: int(vxlanid), Port: 4789, Learning: false, SrcAddr: myip}
	if err := netlink.LinkAdd(vxlan); err != nil {
		fmt.Printf("Failed to create link: %v", err)
		return nil, err
	}

now to set type bridge_slave neigh_suppress on learning off ?

use `go.einride.tech/aip/pagination` to reduce code dup

see https://github.com/einride/aip-go/tree/master/pagination

see https://github.com/einride/aip-go/blob/d1496baa45a9dcbb474e8ad99c63387f6ce86c85/README.md#aip-132-standard-method-list

see

const (
maxPageSize = 250
defaultPageSize = 50
)
switch {
case pageSize < 0:
return -1, -1, status.Error(codes.InvalidArgument, "negative PageSize is not allowed")
case pageSize == 0:
size = defaultPageSize
case pageSize > maxPageSize:
size = maxPageSize
default:
size = int(pageSize)
}
// fetch offset from the database using opaque token
offset = 0
if pageToken != "" {
var ok bool
offset, ok = pagination[pageToken]
if !ok {
return -1, -1, status.Errorf(codes.NotFound, "unable to find pagination token %s", pageToken)
}
log.Printf("Found offset %d from pagination token: %s", offset, pageToken)
}

add ipv6 address support

          Do we need to create an issue to make the code handle ipv6 address as well?

Originally posted by @venkatmahalingam in #99 (comment)

see all the usage of GetV4Addr() across code, for example:

test: create `NewServerWithArgs` func

today

func NewServer() *Server {
	return &Server{
		Bridges: make(map[string]*pe.LogicalBridge),
		Ports:   make(map[string]*pe.BridgePort),
		Svis:    make(map[string]*pe.Svi),
		Vrfs:    make(map[string]*pe.Vrf),
		nLink:   &utils.NetlinkWrapper{},
	}
}

need to change to something like this to be more go-like:

func NewServerWithArgs(nLink utils.Netlink) *Server {
	return &Server{
		Bridges: make(map[string]*pe.LogicalBridge),
		Ports:   make(map[string]*pe.BridgePort),
		Svis:    make(map[string]*pe.Svi),
		Vrfs:    make(map[string]*pe.Vrf),
		nLink:   nLink,
	}
}
func NewServer() *Server {
    nLink := utils.NetlinkWrapper{}
    return NewServerWithArgs(nLink)
}
func NewTestServer() *Server {
    mockNetlink := mocks.Netlink{}
    return NewServerWithArgs(mockNetlink)
}

and then use it opi := NewTestServer() instead of current

opi := NewServer()
opi.nLink = &mocks.Netlink{}

explore how to align EVPN GW to cloud APIs

bridge: create utility funcs for BridgeVlanAdd for PVID and Trunk

for example in https://github.com/opiproject/opi-evpn-bridge/blob/main/pkg/utils/netlink.go add :

// BridgePVIDVlanAdd configure port VLAN id for link
func BridgePVIDVlanAdd(nlink Netlink, link netlink.Link, vlanID int) error {
	// pvid, egress untagged
	return nlink.BridgeVlanAdd(link, uint16(vlanID), true, true, false, true)
}

// BridgeTrunkVlanAdd configure vlan trunk on link
func BridgeTrunkVlanAdd(nlink Netlink, link netlink.Link, vlans []int) error {
	// egress tagged
	for _, vlanID := range vlans {
		if err := nlink.BridgeVlanAdd(link, uint16(vlanID), false, false, false, true); err != nil {
			return err
		}
	}
	return nil
}

because this is hard to read

if err := netlink.BridgeVlanAdd(iface, vid, true, true, false, false); err != nil {
:

netlink.BridgeVlanAdd(iface, vid, true, true, false, false)

VRF loopback IP on device or dummy iface ?

from slack

VRF loopback IP by @venkatmahalingam https://github.com/opiproject/opi-evpn-bridge/blob/main/docker-compose.yml#L67-L71

ip link add green type vrf table 1001 && \
ip link set green up && \
ip link add name lo2 type dummy && \
ip link set lo2 master green up && \
ip address add 10.0.2.2/32 dev lo2 && \

vs by @mardim91 and @JanScheurich

ip link add green type vrf table 1001
ip link set green up
ip address add 10.101.0.1 dev green

which one is correct ?

go: implement `vxlan`

ip link example:

ip link add vni100 type vxlan local 10.0.0.2 dstport 4789 id 100 nolearning && \
ip link set vni100 master br100 addrgenmode none && \
ip link set vni100 type bridge_slave neigh_suppress on learning off && \
ip link set vni100 up && \

in golang:

//	SrcAddr = net.IP = "10.0.0.2"
vxlani := &Vxlan{LinkAttrs: LinkAttrs{Name: "vni100"}, VxlanId: 100, Port: 4789, Learning: false, SrcAddr: "10.0.0.2"}
if err := nh.LinkAdd(vxlani); err != nil {
	t.Errorf("Failed to create link: %v", err)
}
// TODO: fetch bridge object like : s.Subnets[Spec.SubnetNameRef]
if err := netlink.LinkSetMaster(vxlani, "br100"); err != nil {
	fmt.Printf("Failed to add vxlan to bridge: %v", err)
	return nil, err
}
if err := netlink.LinkSetUp(vxlani); err != nil {
	fmt.Printf("Failed to up link: %v", err)
	return nil, err
}

need to understand what protobuf to use ?

port: use existing or create a new one

see more explanation in the commit 8d0d9bf
the base interface is not created, but assumed existing...
in this work, please consider creating base interface or not... what object in the API to use for it...

see where we assume existing and do not attempt to create a new one

// get base interface (e.g.: eth2)
iface, err := netlink.LinkByName(resourceID)
if err != nil {
err := status.Errorf(codes.NotFound, "unable to find key %s", resourceID)
log.Printf("error: %v", err)
return nil, err
}

use different ranges for L3VNIs and L2VNIs

          Just an idea. @venkatmahalingam comment also on that please. 

Maybe would be good to use different ranges for L3VNIs and L2VNIs. We can have the L3VNIs in range between 1000 and 3999 and the L2VNIs in a range over 10000. This way we can distinguish VNIs that are used for L3VPNs and VNIs that are used for L2VPNs. Also we can use the l3vni as routing table id so we can identify the routing table easily by the vni of the VRF. I think the range (1000 to 3999) is a valid range for linux routing tables.

Originally posted by @mardim91 in #66 (comment)

mocks: start using mockery.yaml

see

mockery --config=utils/mocks/.mockery.yaml --name=Netlink --dir pkg/utils --output pkg/utils/mocks --boilerplate-file pkg/utils/mocks/boilerplate.txt --with-expecter

today I use this to generate mocks:

docker run -v "$PWD":/src -w /src vektra/mockery --all --dir pkg/utils --output pkg/utils/mocks --boilerplate-file pkg/utils/mocks/boilerplate.txt --with-expecter

now see https://github.com/opiproject/opi-evpn-bridge/blob/main/pkg/utils/mocks/.mockery.yaml

but running

docker run -v "$PWD":/src -w /src vektra/mockery --config=pkg/utils/mocks/.mockery.yaml

fails with

failed to mkdir parents of: mocks/github.com/opiproject/opi-evpn-bridge/pkg/utils/mock_Netlink.go: mkdir mocks: permission denied

fix it...

utils: create utility function for `LinkByName`, `LinkSetDown` and `LinkDel`

a lot of duplication of this in the code... Example:

		// get device handle by name
		bridgedev, err := netlink.LinkByName(bridgeName)
		if err != nil {
			err := status.Errorf(codes.NotFound, "unable to find key %s", bridgeName)
			log.Printf("error: %v", err)
			return nil, err
		}
		// bring link down
		if err := netlink.LinkSetDown(bridgedev); err != nil {
			fmt.Printf("Failed to up link: %v", err)
			return nil, err
		}
		// use netlink to delete BRIDGE device
		if err := netlink.LinkDel(bridgedev); err != nil {
			fmt.Printf("Failed to delete link: %v", err)
			return nil, err
		}

improve POC diagram

  • VF3 -> VF5 (L2) on VLAN10
  • VF4->VF5 (L3) routing between VLAN22 and VLAN20
  • Remote -> VF5 (L3 VXLAN)

image

image

mocks: create one for `netlink` library using `mockery`

Create wrapper manually in pkg/utils/netlink.go :

// Netlink represents limited subset of functions from netlink package
type Netlink interface {
	LinkByName(string) (netlink.Link, error)
	LinkByIndex(index int) (netlink.Link, error)
	LinkSetHardwareAddr(netlink.Link, net.HardwareAddr) error
	LinkSetUp(netlink.Link) error
	LinkSetDown(netlink.Link) error
	LinkSetName(netlink.Link, string) error
	LinkSetMaster(netlink.Link, netlink.Link) error
	LinkSetNoMaster(netlink.Link) error
	BridgeVlanAdd(netlink.Link, uint16, bool, bool, bool, bool) error
	BridgeVlanDel(netlink.Link, uint16, bool, bool, bool, bool) error
	LinkSetMTU(netlink.Link, int) error
	LinkList() ([]netlink.Link, error)
}

// NetlinkWrapper wrapper for netlink package
type NetlinkWrapper struct {
}

// LinkByName is a wrapper for netlink.LinkByName
func (n *NetlinkWrapper) LinkByName(name string) (netlink.Link, error) {
	return netlink.LinkByName(name)
}

// todo: add more functions

now auto-generate mocks:

mkdir -p pkg/utils/mocks
chmod a+w pkg/utils/mocks
docker run -v "$PWD":/src -w /src vektra/mockery --all --dir pkg/utils --output pkg/utils/mocks

and then use in code like:

import "github.com/opiproject/opi-evpn-bridge/pkg/utils"
 const (
@@ -26,6 +28,7 @@ type Server struct {
        Ports   map[string]*pe.BridgePort
        Svis    map[string]*pe.Svi
        Vrfs    map[string]*pe.Vrf
+       nLink   utils.Netlink
 }

 // NewServer creates initialized instance of EVPN server
@@ -35,6 +38,7 @@ func NewServer() *Server {
                Ports:   make(map[string]*pe.BridgePort),
                Svis:    make(map[string]*pe.Svi),
                Vrfs:    make(map[string]*pe.Vrf),
+               nLink:   &utils.NetlinkWrapper{},
        }
 }

and use in tests like:

import "github.com/opiproject/opi-evpn-bridge/pkg/utils/mocks"
opi := NewServer()
opi.nLink = &mocks.Netlink{}

`CreateLogicalBridge` what about hard coded IP `10.0.0.100` ?

I see no field for IP address

ip link add vni10 type vxlan id 10 local 10.0.0.100 dstport 4789 nolearning proxy
ip link set vni10 master br-tenant up
bridge vlan add dev vni10 vid 10 pvid untagged
bridge link set dev vni10 neigh_suppress on

but

message LogicalBridgeSpec {
    // the VLAN of the L2 domain
    uint32 vlan_id         = 1 [(google.api.field_behavior) = REQUIRED];
    //VXLAN VNI for the L2 EVPN. Also used as EVPN route target
    uint32 vni             = 2;
}

see hard-coded

// TODO: remove hard-coded 167772162 == "10.0.0.2"
binary.BigEndian.PutUint32(myip, 167772162)

@mardim91 please advise

Port: review the netlink commands

see

// not found, so create a new one
bridgeName := "br-tenant"
// get tenant bridge device by name
bridge, err := netlink.LinkByName(bridgeName)
if err != nil {
err := status.Errorf(codes.NotFound, "unable to find key %s", bridgeName)
log.Printf("error: %v", err)
return nil, err
}
// get base interface (e.g.: eth2)
iface, err := netlink.LinkByName(resourceID)
if err != nil {
err := status.Errorf(codes.NotFound, "unable to find key %s", resourceID)
log.Printf("error: %v", err)
return nil, err
}
// Example: ip link set eth2 addr aa:bb:cc:00:00:41
if len(in.BridgePort.Spec.MacAddress) > 0 {
if err := netlink.LinkSetHardwareAddr(iface, in.BridgePort.Spec.MacAddress); err != nil {
fmt.Printf("Failed to set MAC on link: %v", err)
return nil, err
}
}
// Example: ip link set eth2 master br-tenant
if err := netlink.LinkSetMaster(iface, bridge); err != nil {
fmt.Printf("Failed to add iface to bridge: %v", err)
return nil, err
}
// add port to specified logical bridges
for _, bridgeRefName := range in.BridgePort.Spec.LogicalBridges {
fmt.Printf("add iface to logical bridge %s", bridgeRefName)
// get object from DB
bridgeObject, ok := s.Bridges[bridgeRefName]
if !ok {
err := status.Errorf(codes.NotFound, "unable to find key %s", bridgeRefName)
log.Printf("error: %v", err)
return nil, err
}
vid := uint16(bridgeObject.Spec.VlanId)
switch in.BridgePort.Spec.Ptype {
case pb.BridgePortType_ACCESS:
// Example: bridge vlan add dev eth2 vid 20 pvid untagged
if err := netlink.BridgeVlanAdd(iface, vid, true, true, false, false); err != nil {
fmt.Printf("Failed to add vlan to bridge: %v", err)
return nil, err
}
case pb.BridgePortType_TRUNK:
// Example: bridge vlan add dev eth2 vid 20
if err := netlink.BridgeVlanAdd(iface, vid, false, false, false, false); err != nil {
fmt.Printf("Failed to add vlan to bridge: %v", err)
return nil, err
}
default:
msg := fmt.Sprintf("Only ACCESS or TRUNK supported and not (%d)", in.BridgePort.Spec.Ptype)
log.Print(msg)
return nil, status.Errorf(codes.InvalidArgument, msg)
}
}
// Example: ip link set eth2 up
if err := netlink.LinkSetUp(iface); err != nil {
fmt.Printf("Failed to up iface link: %v", err)
return nil, err
}
response := proto.Clone(in.BridgePort).(*pb.BridgePort)

need another look and review

tests: start using mocks

see https://github.com/opiproject/opi-evpn-bridge/tree/main/pkg/utils/mocks
so now can write new tests using mocks...

example (not the best one):

		It("Link is part of a bridge", func() {
			expectedBridgeName := "test1"
			nLinkMock.On("LinkByIndex", 1).Return(
				&netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: expectedBridgeName}}, nil)
			br, err := GetParentBridgeForLink(nLinkMock, &netlink.Device{LinkAttrs: netlink.LinkAttrs{MasterIndex: 1}})
			Expect(err).NotTo(HaveOccurred())
			Expect(br).NotTo(BeNil())
			Expect(br.Attrs().Name).To(BeEquivalentTo(expectedBridgeName))
		})

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • fix(deps): update github.com/opiproject/opi-api digest to e44db26
  • fix(deps): update github.com/opiproject/opi-smbios-bridge digest to 898160c
  • chore(deps): update pre-commit hook renovatebot/pre-commit-hooks to v37.140.6
  • fix(deps): update module github.com/onsi/ginkgo/v2 to v2.15.0
  • fix(deps): update module go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc to v0.47.0
  • fix(deps): update opentelemetry-go monorepo to v1.22.0 (go.opentelemetry.io/otel, go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc, go.opentelemetry.io/otel/sdk, go.opentelemetry.io/otel/trace)

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

docker-compose
docker-compose.yml
  • quay.io/frrouting/frr 9.1.0
  • quay.io/frrouting/frr 9.1.0
  • quay.io/frrouting/frr 9.1.0
  • quay.io/frrouting/frr 9.1.0
  • jaegertracing/all-in-one 1.53.0
  • redis 7.2.3-alpine3.18
  • curlimages/curl 8.5.0
  • curlimages/curl 8.5.0
  • docker.io/library/alpine 3.19
  • docker.io/library/alpine 3.19
  • docker.io/library/alpine 3.19
  • docker.io/library/alpine 3.19
dockerfile
Dockerfile
  • docker.io/library/golang 1.21.6-alpine
  • alpine 3.19
  • docker.io/fullstorydev/grpcurl v1.8.9-alpine
github-actions
.github/workflows/codeql.yml
.github/workflows/commitlint.yml
.github/workflows/docker-publish.yml
.github/workflows/go.yml
.github/workflows/linters.yml
.github/workflows/release-please.yml
.github/workflows/scorecard.yml
.github/workflows/update-copyright-years-in-license-file.yml
gomod
go.mod
  • go 1.19
  • github.com/golangci/golangci-lint v1.55.2
  • github.com/google/uuid v1.5.0
  • github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1
  • github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0
  • github.com/onsi/ginkgo/v2 v2.14.0
  • github.com/opiproject/opi-api v0.0.0-20240115075233-7dc729079487@7dc729079487
  • github.com/opiproject/opi-smbios-bridge v0.1.3-0.20240113044816-4401aa6a3d1a@4401aa6a3d1a
  • github.com/philippgille/gokv v0.6.0
  • github.com/philippgille/gokv/gomap v0.6.0
  • github.com/philippgille/gokv/redis v0.6.0
  • github.com/stretchr/testify v1.8.4
  • github.com/vektra/mockery/v2 v2.38.0
  • github.com/vishvananda/netlink v1.2.1-beta.2
  • github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b@c3b780dc415b
  • go.einride.tech/aip v0.66.0
  • go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1
  • go.opentelemetry.io/otel v1.21.0
  • go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0
  • go.opentelemetry.io/otel/sdk v1.21.0
  • go.opentelemetry.io/otel/trace v1.21.0
  • golang.org/x/tools v0.17.0
  • google.golang.org/grpc v1.60.1
  • google.golang.org/protobuf v1.32.0
pre-commit
.pre-commit-config.yaml
  • pre-commit/pre-commit-hooks v4.5.0
  • renovatebot/pre-commit-hooks 37.131.0
  • alessandrojcm/commitlint-pre-commit-hook v9.11.0
  • golangci/golangci-lint v1.55.2

  • Check this box to trigger a request for Renovate to run again on this repository

document few more cli examples using docker in readme

it took me a minute to make it work, so think it is helpful for people to have this info documented

$ docker run --rm -it --network=container:opi-evpn-bridge-opi-evpn-bridge-1 docker.io/namely/grpc-cli ls localhost:50151
grpc.reflection.v1.ServerReflection
grpc.reflection.v1alpha.ServerReflection
opi_api.network.evpn_gw.v1alpha1.BridgePortService
opi_api.network.evpn_gw.v1alpha1.LogicalBridgeService
opi_api.network.evpn_gw.v1alpha1.SviService
opi_api.network.evpn_gw.v1alpha1.VrfService

and

$ docker run --rm -it --network=container:opi-evpn-bridge-opi-evpn-bridge-1 docker.io/opiproject/godpu:main evpn list-vrfs --addr=localhost:50151
2023/09/13 17:00:21 VRF with
 name: //network.opiproject.org/vrfs/blue
 operation status: 0
 vni : 0
 vtep ip : addr:{af:IP_AF_INET v4_addr:167772162} len:32
 loopback ip: addr:{af:IP_AF_INET v4_addr:167772418} len:32
2023/09/13 17:00:21 VRF with
 name: //network.opiproject.org/vrfs/green
 operation status: 0
 vni : 100
 vtep ip : addr:{af:IP_AF_INET v4_addr:167772162} len:32
 loopback ip: addr:{af:IP_AF_INET v4_addr:167772674} len:32
2023/09/13 17:00:21 VRF with
 name: //network.opiproject.org/vrfs/yellow
 operation status: 0
 vni : 101
 vtep ip : addr:{af:IP_AF_INET v4_addr:167772162} len:32
 loopback ip: addr:{af:IP_AF_INET v4_addr:167772930} len:32

frr: Error loading shared library `grpc`: No such file or directory

See from https://docs.frrouting.org/en/latest/grpc.html
same from https://github.com/FRRouting/frr/blob/master/doc/developer/grpc.rst
Proto defined https://github.com/FRRouting/frr/blob/master/grpc/frr-northbound.proto

$ docker run --rm -it quay.io/frrouting/frr:8.5.2 bash
b0e55a99e418:/# /usr/lib/frr/ospfd  -d -F traditional -A 127.0.0.1 -M grpc:50051
frr_init: loader error: dlopen(/usr/lib/frr/modules/ospfd_grpc.so): Error loading shared library /usr/lib/frr/modules/ospfd_grpc.so: No such file or directory
frr_init: loader error: dlopen(/usr/lib/frr/modules/grpc.so): Error loading shared library /usr/lib/frr/modules/grpc.so: No such file or directory
frr_init: loader error: dlopen(grpc): Error loading shared library grpc: No such file or directory

looks like pre-built container has no grpc libs

b0e55a99e418:/# grep grpc /etc/frr/daemons
bgpd_options="  -A 127.0.0.1 -M grpc:50051"

from documentation https://docs.frrouting.org/en/latest/grpc.html

gRPC provides a combined front end to all FRR daemons using the YANG northbound. 
It is currently disabled by default due its experimental stage, but it can be enabled with 
[--enable-grpc](https://docs.frrouting.org/en/latest/installation.html#cmdoption-configure-enable-grpc) option in the configure script.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.