Skip to content
Snippets Groups Projects
Commit 3214a446 authored by Neil-Jocelyn Schark's avatar Neil-Jocelyn Schark
Browse files

Merge branch 'renovate/golangci-golangci-lint-1.x' of...

Merge branch 'renovate/golangci-golangci-lint-1.x' of code.fbi.h-da.de:danet/gosdn into renovate/golangci-golangci-lint-1.x
parents 54f5e2b5 ac4709d8
No related branches found
No related tags found
2 merge requests!998[renovate] Update golangci/golangci-lint Docker tag to v1.60.1,!883[renovate] Update golangci/golangci-lint Docker tag to v1.59.0
Pipeline #200528 failed
This commit is part of merge request !998. Comments created here will be created in the context of that merge request.
Showing
with 267 additions and 70 deletions
......@@ -5,7 +5,7 @@
"build": {
"dockerfile": "Dockerfile",
"args": {
"_CLAB_VERSION": "0.52.0"
"_CLAB_VERSION": "0.54.2"
}
},
"features": {
......
code-quality:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golangci/golangci-lint:v1.57.2-alpine
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golangci/golangci-lint:v1.59.0-alpine
stage: analyze
script:
# writes golangci-lint output to gl-code-quality-report.json
......
build-mkdocs:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/python:3.12.2-slim-bookworm
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/python:3.12.3-slim-bookworm
stage: build
before_script:
- pip install mkdocs-material
......@@ -13,7 +13,7 @@ build-mkdocs:
- if: $CI_COMMIT_REF_PROTECTED == "true"
.pages-options: &pages-options
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/python:3.12.2-slim-bookworm
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/python:3.12.3-slim-bookworm
stage: deploy
script:
- mv mkdocs-built public
......
renovate:
stage: tools
image: renovate/renovate:37.273.0
image: renovate/renovate:37.382.3
variables:
LOG_LEVEL: debug
......
......@@ -85,6 +85,13 @@ dev-env-start: generate-gnmi-target-certs generate-gosdn-certs containerize-gosd
dev-env-stop:
./scripts/simple-dev-setup.sh --mode stop --topology dev_env_data/clab/basic_two_gnmi_targets.yaml
basic-compose-up: generate-certs containerize-gosdn containerize-plugin-registry
docker-compose -f dev_env_data/docker-compose/basic_docker-compose.yml down
docker-compose -f dev_env_data/docker-compose/basic_docker-compose.yml up -d
basic-compose-down:
docker-compose -f dev_env_data/docker-compose/basic_docker-compose.yml down
generate-certs: generate-gnmi-target-certs generate-gosdn-certs
integration-tests: generate-certs containerize-gosdn containerize-plugin-registry
......
......@@ -136,11 +136,32 @@ system.
With the help of [containerlab](https://containerlab.dev/) we provide simple test environments to play around with.
```sh
# start containerlab
make containerlab-slim-start
# stop the containerlab topology
make containerlab-slim-stop
```
If you don't want to install containerlab, you can also use a docker-compose config. For most tasks it works as well, but it is missing the static IP and link configurations.
```sh
# start the environment
make basic-compose-up
# stop the environment
make basic-compose-down
```
### Labs
The environment Lab 01 contains two [Arista
cEOS](https://www.arista.com/en/products/software-controlled-container-networking),
a goSDN, a gNMI target, a plugin-registry, a MongoDB and a RabbitMQ.
The environment Lab 00 contains two gNMI targets used as switches, s goSDN, two Linux servers, a plugin-registry, a MongoDB and a RabbitMQ. Lab 00 is lighter than Lab 01.
The environment Lab 00 contains two gNMI targets used as switches, goSDN, two Linux servers, a plugin-registry, a MongoDB and a RabbitMQ. Lab 00 is lighter than Lab 01.
> If you're a member of the danet group you should have access to the
> containers repo. Don't forget to `sudo docker login
......@@ -153,14 +174,6 @@ The environment Lab 00 contains two gNMI targets used as switches, s goSDN, two
> cEOS image by yourself. Don't forget to change the image name (line `11` in
> the `gosdn.clab.yml` file) to the local one you've downloaded.
```sh
# starts the containerlab topology which contains two Arista cEOS, an cSBI orchestrator, a goSDN controller and gNMI target.
make containerlab-start
# stop the containerlab topology
make containerlab-stop
```
### Additional services
There are optional and mandatory services that can be used with the controller. They can be started via the provided `docker-compose.yml`:
......
......@@ -11,7 +11,7 @@ import (
// Register registers a new app at the control plane.
func Register(ctx context.Context, gosdnAddress, name, token string) (string, error) {
conn, err := grpc.Dial(gosdnAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
conn, err := grpc.NewClient(gosdnAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return "", err
}
......
......@@ -40,7 +40,7 @@ func (a *Application) Run(controllerAddress string) {
})
a.eventServiceRoutes.SetupEventReciever(a.stopChannel)
conn, err := grpc.Dial(controllerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
conn, err := grpc.NewClient(controllerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
......
......@@ -31,7 +31,7 @@ func (a *Application) Run(controllerAddress string) {
})
a.eventServiceNetworkElements.SetupEventReciever(a.stopChannel)
conn, err := grpc.Dial(controllerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
conn, err := grpc.NewClient(controllerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
......
......@@ -35,7 +35,7 @@ func (a *Application) Run() {
})
a.eventService.SetupEventReciever(a.stopChannel)
conn, err := grpc.Dial("localhost:55055", grpc.WithTransportCredentials(insecure.NewCredentials()))
conn, err := grpc.NewClient("localhost:55055", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
......
......@@ -50,7 +50,7 @@ func NewVenvManager(dialConnectionURL string, dialOption grpc.DialOption, topolo
}
func (v *VenvManager) createConnection() (*grpc.ClientConn, error) {
conn, err := grpc.Dial(v.dialConnectionURL, v.dialOption, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(100*1024*1024)))
conn, err := grpc.NewClient(v.dialConnectionURL, v.dialOption, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(100*1024*1024)))
if err != nil {
return nil, err
}
......
......@@ -50,7 +50,7 @@ A description must be passed as positional argument.`,
Run: func(cmd *cobra.Command, args []string) {
spinner, _ := pterm.DefaultSpinner.Start("Creating new PND")
_, err := api.AddPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription)
_, err := api.CreatePnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription)
if err != nil {
spinner.Fail("Failed creating the PND with name: ", pndName)
spinner.Fail(err)
......
......@@ -47,7 +47,7 @@ var pndListCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
spinner, _ := pterm.DefaultSpinner.Start("Fetching PND list from controller")
resp, err := api.GetPnds(createContextWithAuthorization(), pndAdapter.Endpoint())
resp, err := api.GetPndList(createContextWithAuthorization(), pndAdapter.Endpoint())
if err != nil {
spinner.Fail(err)
return
......
......@@ -9,10 +9,13 @@ import (
"code.fbi.h-da.de/danet/gosdn/controller/store"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"google.golang.org/grpc/resolver"
)
func Test_Init(t *testing.T) {
viper.SetConfigFile("./api_test.toml")
resolver.SetDefaultScheme("passthrough")
if err := Init(context.TODO(), bufnet); err != nil {
t.Error(err)
}
......@@ -55,7 +58,7 @@ func ensureStoreFileForTestsIsRemoved(storeName string) {
func Test_AddPnd(t *testing.T) {
defer ensureFilesForTestsAreRemoved()
resp, err := AddPnd(context.TODO(), bufnet, "test", "test pnd")
resp, err := CreatePnd(context.TODO(), bufnet, "test", "test pnd")
if err != nil {
t.Error(err)
return
......
package api
import (
"context"
"time"
apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/app"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
)
// Register checks if the app already exists and if not creates a new one.
func Register(ctx context.Context, addr, appname, token string) (*apb.AppRegisterResponse, error) {
appClient, err := nbi.AppClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &apb.AppRegisterRequest{
Timestamp: time.Now().UnixNano(),
Appname: appname,
Token: token,
}
return appClient.Register(ctx, req)
}
// Deregister deregisters an app.
func Deregister(ctx context.Context, addr, appname, token string) (*apb.AppDeregisterResponse, error) {
appClient, err := nbi.AppClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &apb.AppDeregisterRequest{
Timestamp: time.Now().UnixNano(),
Appname: appname,
}
return appClient.Deregister(ctx, req)
}
package api
import (
"context"
"time"
cpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/configurationmanagement"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
)
// ExportSDNConfig returns the SDN configuration.
func ExportSDNConfig(ctx context.Context, addr, pid string) (*cpb.ExportSDNConfigResponse, error) {
configClient, err := nbi.ConfigurationManagementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &cpb.ExportSDNConfigRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
}
return configClient.ExportSDNConfig(ctx, req)
}
// ImportSDNConfig receives an SDN configuration and imports it.
func ImportSDNConfig(ctx context.Context, addr, pid, sdnConfigData string) (*cpb.ImportSDNConfigResponse, error) {
configClient, err := nbi.ConfigurationManagementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &cpb.ImportSDNConfigRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
SdnConfigData: sdnConfigData,
}
return configClient.ImportSDNConfig(ctx, req)
}
......@@ -2,19 +2,15 @@ package api
import (
"context"
"errors"
"io"
"time"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
pipb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal"
spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
"github.com/google/uuid"
"github.com/openconfig/goyang/pkg/yang"
"github.com/openconfig/ygot/ygot"
log "github.com/sirupsen/logrus"
)
......@@ -50,6 +46,23 @@ func AddNetworkElement(ctx context.Context, addr, mneName, mneUUID string, opt *
return client.AddList(ctx, req)
}
// AddNetworkElementList adds all the network elements to the controller. The name of each network element is optional.
// If no name is provided a name will be generated upon network element creation.
func AddNetworkElementList(ctx context.Context, addr, pid string, mneList []*mnepb.SetMne) (*mnepb.AddListResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.AddListRequest{
Timestamp: time.Now().UnixNano(),
Mne: mneList,
Pid: pid,
}
return client.AddList(ctx, req)
}
// GetNetworkElement requests one network element belonging to a given
// PrincipalNetworkDomain from the controller. If no network element identifier
// is provided, an error is thrown.
......@@ -72,51 +85,19 @@ func GetNetworkElement(ctx context.Context, addr, pid string, mneid string) (*mn
return client.Get(ctx, req)
}
// GetPluginSchemaTree gets the schema tree for a plugin.
func GetPluginSchemaTree(ctx context.Context, addr string, pluginID uuid.UUID) (map[string]*yang.Entry, error) {
pluginClient, err := nbi.PluginClient(addr, dialOptions...)
// GetNetworkElements requests all available network elements related to one PND.
func GetNetworkElements(ctx context.Context, addr, pid string) (*mnepb.GetAllResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return map[string]*yang.Entry{}, err
return nil, err
}
req := &pipb.GetPluginSchemaRequest{
req := &mnepb.GetAllRequest{
Timestamp: time.Now().UnixNano(),
Pid: pluginID.String(),
}
ctx, cancel := context.WithTimeout(ctx, time.Minute*10)
defer cancel()
sClient, err := pluginClient.GetPluginSchema(ctx, req)
if err != nil {
return map[string]*yang.Entry{}, err
}
sTreeBytes := []byte{}
for {
payload, err := sClient.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
log.Error(err)
closeErr := sClient.CloseSend()
if closeErr != nil {
return nil, err
}
return map[string]*yang.Entry{}, err
}
sTreeBytes = append(sTreeBytes, payload.Chunk...)
}
sTreeMap, err := ygot.GzipToSchema(sTreeBytes)
if err != nil {
return map[string]*yang.Entry{}, err
Pid: pid,
}
return sTreeMap, nil
return client.GetAll(ctx, req)
}
// GetFlattenedNetworkElement requests a network elements belonging to a given
......@@ -218,3 +199,28 @@ func DeleteNetworkElement(ctx context.Context, addr, pid, mneid string) (*mnepb.
return client.Delete(ctx, req)
}
// UpdateNetworkElement changes the metadata of the network element which is stored in the controller storage.
// Correct resource version needs to be provided to allow a change of the object in the storage.
func UpdateNetworkElement(ctx context.Context, addr, mneid, updatedName, updatedTransportAddress, updatedPid string, resourceVersion *conflict.Metadata) (*mnepb.UpdateNetworkElementResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.UpdateNetworkElementRequest{
Timestamp: time.Now().UnixNano(),
NetworkElement: &mnepb.ManagedNetworkElement{
Id: mneid,
Name: updatedName,
TransportAddress: updatedTransportAddress,
TransportOption: &tpb.TransportOption{
Address: updatedTransportAddress,
},
Metadata: resourceVersion,
AssociatedPnd: updatedPid,
},
}
return client.Update(ctx, req)
}
......@@ -2,11 +2,18 @@ package api
import (
"context"
"errors"
"io"
"time"
pib "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal"
pipb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal"
prb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-registry"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
"github.com/google/uuid"
"github.com/openconfig/goyang/pkg/yang"
"github.com/openconfig/ygot/ygot"
"github.com/sirupsen/logrus"
)
// GetAvailablePlugins requests all available plugins that can be registered
......@@ -24,3 +31,50 @@ func GetAvailablePlugins(ctx context.Context, addr string) (*prb.GetResponse, er
return pluginRegistryClient.AvailablePlugins(ctx, req)
}
// GetPluginSchemaTree gets the schema tree for a plugin.
func GetPluginSchemaTree(ctx context.Context, addr string, pluginID uuid.UUID) (map[string]*yang.Entry, error) {
pluginClient, err := nbi.PluginClient(addr, dialOptions...)
if err != nil {
return map[string]*yang.Entry{}, err
}
req := &pipb.GetPluginSchemaRequest{
Timestamp: time.Now().UnixNano(),
Pid: pluginID.String(),
}
ctx, cancel := context.WithTimeout(ctx, time.Minute*10)
defer cancel()
sClient, err := pluginClient.GetPluginSchema(ctx, req)
if err != nil {
return map[string]*yang.Entry{}, err
}
sTreeBytes := []byte{}
for {
payload, err := sClient.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
logrus.Error(err)
closeErr := sClient.CloseSend()
if closeErr != nil {
return nil, err
}
return map[string]*yang.Entry{}, err
}
sTreeBytes = append(sTreeBytes, payload.Chunk...)
}
sTreeMap, err := ygot.GzipToSchema(sTreeBytes)
if err != nil {
return map[string]*yang.Entry{}, err
}
return sTreeMap, nil
}
......@@ -9,9 +9,9 @@ import (
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
)
// AddPnd takes a name, description and SBI UUID to create a new
// CreatePnd takes an address, a name and a description to create a new
// PrincipalNetworkDomain on the controller.
func AddPnd(ctx context.Context, addr, name, description string) (*ppb.CreatePndListResponse, error) {
func CreatePnd(ctx context.Context, addr, name, description string) (*ppb.CreatePndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
......@@ -30,6 +30,21 @@ func AddPnd(ctx context.Context, addr, name, description string) (*ppb.CreatePnd
return pndClient.CreatePndList(ctx, req)
}
// CreatePndList uses the provided creation properties to add all the PNDs to the controller.
func CreatePndList(ctx context.Context, addr string, pnds []*ppb.PndCreateProperties) (*ppb.CreatePndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.CreatePndListRequest{
Timestamp: time.Now().UnixNano(),
Pnd: pnds,
}
return pndClient.CreatePndList(ctx, req)
}
// GetPnd requests one PrincipalNetworkDomain from the
// controller.
func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse, error) {
......@@ -48,9 +63,9 @@ func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse,
return pndClient.GetPnd(ctx, req)
}
// GetPnds requests all PrincipalNetworkDomains from the
// GetPndList requests all PrincipalNetworkDomains from the
// controller.
func GetPnds(ctx context.Context, addr string, args ...string) (*ppb.GetPndListResponse, error) {
func GetPndList(ctx context.Context, addr string, args ...string) (*ppb.GetPndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
......
amqphost = 'rabbitmq'
amqppassword = 'guest'
amqpport = '5672'
amqpprefix = 'amqp://'
amqpuser = 'guest'
basepnduuid = '5f20f34b-cbd0-4511-9ddc-c50cf6a3b49d'
config = './gosdn/controller/configs/integration-test-gosdn.toml'
csbi-orchestrator = 'localhost:55056'
databaseconnection = 'mongodb://root:example@mongo:27017'
defaultjwtduration = 24
filesystempathtostores = 'stores'
gnmisubscriptionspath = 'configs/gNMISubscriptions.txt'
help = false
log-level = 'debug'
plugin-folder = 'plugins'
plugin-registry = 'plugin-registry:55057'
security = 'insecure'
socket = ':55055'
tlscacertfile = '/ssl/ca.crt'
tlscertfile = '/ssl/certs/gosdn-selfsigned.crt'
tlskeyfile = '/ssl/private/gosdn-selfsigned.key'
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment