Skip to content

Commit

Permalink
feat: complete ci and slowpath implementation of new arch
Browse files Browse the repository at this point in the history
Co-authored-by: Vemula Venkatesh <venkatesh.vemula@intel.com>
Co-authored-by: Patel Atul <Atul.patel@intel.com>
Co-authored-by: Saikumar Banoth <banoth.saikumar@intel.com>
Co-authored-by: Jambekar Vishakha <vishakha.jambekar@intel.com>
Signed-off-by: Dimitrios Markou <dimitrios.markou@ericsson.com>
  • Loading branch information
5 people authored and sandersms committed Apr 25, 2024
1 parent 5440fb9 commit 632bc86
Show file tree
Hide file tree
Showing 64 changed files with 6,558 additions and 2,984 deletions.
11 changes: 8 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
FROM docker.io/library/golang:1.21.6-alpine as builder

WORKDIR /app

# Download necessary Go modules
COPY config.yaml ./
COPY go.mod ./
COPY go.sum ./
RUN go mod download

# build an app
COPY cmd/ cmd/
COPY pkg/ pkg/
Expand All @@ -20,6 +19,12 @@ FROM alpine:3.19
RUN apk add --no-cache --no-check-certificate hwdata && rm -rf /var/cache/apk/*
COPY --from=builder /opi-evpn-bridge /
COPY --from=docker.io/fullstorydev/grpcurl:v1.8.9-alpine /bin/grpcurl /usr/local/bin/
COPY --from=builder /app/config.yaml /
RUN apk add --no-cache iproute2 && \
mkdir -p /etc/iproute2/ && \
echo "255 opi_evpn_br" > /etc/iproute2/rt_protos && \
cat /etc/iproute2/rt_protos && \
ls -al /
EXPOSE 50051 8082
CMD [ "/opi-evpn-bridge", "-grpc_port=50051", "-http_port=8082" ]
CMD [ "/opi-evpn-bridge", "--grpcport=50051", "--httpport=8082"]
HEALTHCHECK CMD grpcurl -plaintext localhost:50051 list || exit 1
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ build:
@echo " > Building binaries..."
@CGO_ENABLED=0 go build -o ${PROJECTNAME} ./cmd/...

build-arm:
@echo " > Building binaries..."
@CGO_ENABLED=0 env GOOS=linux GOARCH=arm64 go build -o ${PROJECTNAME} ./cmd/...

get:
@echo " > Checking if there are any missing dependencies..."
@CGO_ENABLED=0 go get ./...
Expand Down
217 changes: 177 additions & 40 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,79 +1,201 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2022-2023 Intel Corporation, or its subsidiaries.
// Copyright (c) 2022-2023 Dell Inc, or its subsidiaries.
// Copyright (C) 2023 Nordix Foundation.

// Package main is the main package of the application
package main

import (
"context"
"flag"
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"path/filepath"
"strconv"
"time"

"github.com/spf13/cobra"
"github.com/spf13/viper"

pc "github.com/opiproject/opi-api/inventory/v1/gen/go"
pe "github.com/opiproject/opi-api/network/evpn-gw/v1alpha1/gen/go"
"github.com/opiproject/opi-evpn-bridge/pkg/bridge"
"github.com/opiproject/opi-evpn-bridge/pkg/config"
"github.com/opiproject/opi-evpn-bridge/pkg/infradb"
"github.com/opiproject/opi-evpn-bridge/pkg/infradb/taskmanager"
"github.com/opiproject/opi-evpn-bridge/pkg/port"
"github.com/opiproject/opi-evpn-bridge/pkg/svi"
"github.com/opiproject/opi-evpn-bridge/pkg/utils"
"github.com/opiproject/opi-evpn-bridge/pkg/vrf"
"github.com/opiproject/opi-smbios-bridge/pkg/inventory"

"github.com/philippgille/gokv"
"github.com/philippgille/gokv/redis"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"

"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"

ci_linux "github.com/opiproject/opi-evpn-bridge/pkg/LinuxCIModule"
gen_linux "github.com/opiproject/opi-evpn-bridge/pkg/LinuxGeneralModule"
ipu_linux "github.com/opiproject/opi-evpn-bridge/pkg/LinuxVendorModule/ipu"
frr "github.com/opiproject/opi-evpn-bridge/pkg/frr"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
)

func main() {
var grpcPort int
flag.IntVar(&grpcPort, "grpc_port", 50151, "The gRPC server port")
const (
configFilePath = "./"
)

var rootCmd = &cobra.Command{
Use: "opi-evpn-bridge",
Short: "evpn bridge",
Long: "evpn bridge application",
PreRunE: func(_ *cobra.Command, _ []string) error {
return validateConfigs()
},
Run: func(_ *cobra.Command, _ []string) {

taskmanager.TaskMan.StartTaskManager()

var httpPort int
flag.IntVar(&httpPort, "http_port", 8082, "The HTTP server port")
err := infradb.NewInfraDB(config.GlobalConfig.DBAddress, config.GlobalConfig.Database)
if err != nil {
log.Println("error in creating db", err)
}
go runGatewayServer(config.GlobalConfig.GRPCPort, config.GlobalConfig.HTTPPort)

var tlsFiles string
flag.StringVar(&tlsFiles, "tls", "", "TLS files in server_cert:server_key:ca_cert format.")
defer func() {
if err := infradb.Close(); err != nil {
log.Fatal(err)
}
}()

var redisAddress string
flag.StringVar(&redisAddress, "redis_addr", "127.0.0.1:6379", "Redis address in ip_address:port format")
switch config.GlobalConfig.Buildenv {
case "ipu":
gen_linux.Init()
ipu_linux.Init()
frr.Init()

case "ci":
gen_linux.Init()
ci_linux.Init()
frr.Init()
default:
log.Fatal(" ERROR: Could not find Build env ")
}

var frrAddress string
flag.StringVar(&frrAddress, "frr_addr", "127.0.0.1", "Frr address in ip_address format, no port")
// Create GRD VRF configuration during startup
if err := createGrdVrf(); err != nil {
log.Printf("Error in creating GRD VRF %+v\n", err)
}

runGrpcServer(config.GlobalConfig.GRPCPort, config.GlobalConfig.TLSFiles)
},
}

flag.Parse()
// initialize the cobra configuration and bind the flags
func initialize() {
cobra.OnInitialize(initConfig)

// Create KV store for persistence
options := redis.DefaultOptions
options.Address = redisAddress
options.Codec = utils.ProtoCodec{}
store, err := redis.NewClient(options)
rootCmd.PersistentFlags().StringVarP(&config.GlobalConfig.CfgFile, "config", "c", "config.yaml", "config file path")
rootCmd.PersistentFlags().IntVar(&config.GlobalConfig.GRPCPort, "grpcport", 50151, "The gRPC server port")
rootCmd.PersistentFlags().IntVar(&config.GlobalConfig.HTTPPort, "httpport", 8082, "The HTTP server port")
rootCmd.PersistentFlags().StringVar(&config.GlobalConfig.TLSFiles, "tlsfiles", "", "TLS files in server_cert:server_key:ca_cert format.")
rootCmd.PersistentFlags().StringVar(&config.GlobalConfig.DBAddress, "dbaddress", "127.0.0.1:6379", "db address in ip_address:port format")
rootCmd.PersistentFlags().StringVar(&config.GlobalConfig.FRRAddress, "frraddress", "127.0.0.1", "Frr address in ip_address format, no port")
rootCmd.PersistentFlags().StringVar(&config.GlobalConfig.Database, "database", "redis", "Database connection string")

if err := viper.GetViper().BindPFlags(rootCmd.PersistentFlags()); err != nil {
log.Printf("Error binding flags to Viper: %v\n", err)
os.Exit(1)
}
}

// initConfig read the config from file
func initConfig() {
if config.GlobalConfig.CfgFile != "" {
viper.SetConfigFile(config.GlobalConfig.CfgFile)
} else {
// Search config in the default location
viper.AddConfigPath(configFilePath)
viper.SetConfigType("yaml")
viper.SetConfigName("config.yaml")
}
config.LoadConfig()
}

const logfile string = "opi-evpn-bridge.log"

var logger *log.Logger

// setupLogger sets the config for logger
func setupLogger(filename string) {
var err error
filename = filepath.Clean(filename)
out, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
log.Panic(err)
log.Fatal(err)
}
defer func(store gokv.Store) {
err := store.Close()
if err != nil {
log.Panic(err)
}
}(store)
logger = log.New(io.MultiWriter(out), "", log.Lshortfile|log.LstdFlags)
log.SetOutput(logger.Writer())
}

go runGatewayServer(grpcPort, httpPort)
runGrpcServer(grpcPort, tlsFiles, frrAddress, store)
// validateConfigs validates the config parameters
func validateConfigs() error {
var err error

grpcPort := viper.GetInt("grpcport")
if grpcPort <= 0 || grpcPort > 65535 {
err = fmt.Errorf("grpcPort must be a positive integer between 1 and 65535")
return err
}

httpPort := viper.GetInt("httpport")
if httpPort <= 0 || httpPort > 65535 {
err = fmt.Errorf("httpPort must be a positive integer between 1 and 65535")
return err
}

dbAddr := viper.GetString("dbaddress")
_, port, err := net.SplitHostPort(dbAddr)
if err != nil {
err = fmt.Errorf("invalid DBAddress format. It should be in ip_address:port format")
return err
}

dbPort, err := strconv.Atoi(port)
if err != nil || dbPort <= 0 || dbPort > 65535 {
err = fmt.Errorf("invalid db port. It must be a positive integer between 1 and 65535")
return err
}

frrAddr := viper.GetString("frraddress")
if net.ParseIP(frrAddr) == nil {
err = fmt.Errorf("invalid FRRAddress format. It should be a valid IP address")
return err
}

return nil
}

func runGrpcServer(grpcPort int, tlsFiles, frrAddress string, store gokv.Store) {
// main function
func main() {
// setup file and console logger
setupLogger(logfile)
// initialize cobra config
initialize()
// start the main cmd
if err := rootCmd.Execute(); err != nil {
log.Println(err)
os.Exit(1)
}
}

// runGrpcServer start the grpc server for all the components
func runGrpcServer(grpcPort int, tlsFiles string) {
tp := utils.InitTracerProvider("opi-evpn-bridge")
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
Expand Down Expand Up @@ -102,6 +224,7 @@ func runGrpcServer(grpcPort int, tlsFiles, frrAddress string, store gokv.Store)
}
serverOptions = append(serverOptions, option)
}

serverOptions = append(serverOptions,
grpc.StatsHandler(otelgrpc.NewServerHandler()),
grpc.UnaryInterceptor(
Expand All @@ -116,14 +239,10 @@ func runGrpcServer(grpcPort int, tlsFiles, frrAddress string, store gokv.Store)
)
s := grpc.NewServer(serverOptions...)

nLink := utils.NewNetlinkWrapper()
frr := utils.NewFrrWrapperWithArgs(frrAddress)

bridgeServer := bridge.NewServerWithArgs(nLink, frr, store)
portServer := port.NewServerWithArgs(nLink, frr, store)
vrfServer := vrf.NewServerWithArgs(nLink, frr, store)
sviServer := svi.NewServerWithArgs(nLink, frr, store)

bridgeServer := bridge.NewServer()
portServer := port.NewServer()
vrfServer := vrf.NewServer()
sviServer := svi.NewServer()
pe.RegisterLogicalBridgeServiceServer(s, bridgeServer)
pe.RegisterBridgePortServiceServer(s, portServer)
pe.RegisterVrfServiceServer(s, vrfServer)
Expand All @@ -138,6 +257,7 @@ func runGrpcServer(grpcPort int, tlsFiles, frrAddress string, store gokv.Store)
}
}

// runGatewayServer
func runGatewayServer(grpcPort int, httpPort int) {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
Expand Down Expand Up @@ -167,3 +287,20 @@ func runGatewayServer(grpcPort int, httpPort int) {
log.Panic("cannot start HTTP gateway server")
}
}

// createGrdVrf creates the grd vrf with vni 0
func createGrdVrf() error {
grdVrf, err := infradb.NewVrfWithArgs("//network.opiproject.org/vrfs/GRD", nil, nil, nil)
if err != nil {
log.Printf("CreateGrdVrf(): Error in initializing GRD VRF object %+v\n", err)
return err
}

err = infradb.CreateVrf(grdVrf)
if err != nil {
log.Printf("CreateGrdVrf(): Error in creating GRD VRF object %+v\n", err)
return err
}

return nil
}
32 changes: 32 additions & 0 deletions config-ipu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
grpcport: 50151
httpport: 8082
tlsfiles:
database: redis
dbaddress: 127.0.0.1:6379
frraddress: 127.0.0.1
buildenv: ipu
subscribers:
- name: "lvm"
priority: 2
events: ["vrf", "bridge-port"]
- name: "lgm"
priority: 1
events: ["vrf", "svi", "logical-bridge"]
- name: "frr"
priority: 3
events: ["vrf", "svi"]
- name: "ipu"
priority: 4
events: ["vrf"]
grpc:
server_addresses:
- 0.0.0.0
server_port: 51703
num_threads: 10
static_external_macs: []
linuxfrr:
enabled: true
defaultvtep: "vxlan-vtep"
portmux: "enp0s1f0d5"
vrfmux: "enp0s1f0d4"
ipmtu: 2962
27 changes: 27 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
grpcport: 50151
httpport: 8082
tlsfiles:
database: redis
dbaddress: 127.0.0.1:6379
frraddress: 127.0.0.1
buildenv: ci
subscribers:
- name: "lgm"
priority: 1
events: ["vrf", "svi", "logical-bridge"]
- name: "frr"
priority: 3
events: ["vrf", "svi"]
- name: "lci"
priority: 2
events: ["bridge-port"]
grpc:
server_addresses:
- 0.0.0.0
server_port: 51703
num_threads: 10
static_external_macs: []
linuxfrr:
enabled: true
defaultvtep: "vxlan-vtep"
ipmtu: 1500
Loading

0 comments on commit 632bc86

Please sign in to comment.