Skip to content
Snippets Groups Projects
Commit 301d60ba authored by Manuel Kieweg's avatar Manuel Kieweg
Browse files

Merge branch 'revert-7d6f3967' into...

Merge branch 'revert-7d6f3967' into '74-follow-up-from-draft-resolve-pnd-handling-via-cli-and-database'

Revert "Merge branch 'develop' into...

See merge request cocsn/gosdn!115
parents 7d6f3967 16e7ad36
No related branches found
No related tags found
3 merge requests!116Resolve "Transport Tests",!115Revert "Merge branch 'develop' into...,!90Develop
Pipeline #66812 passed with warnings
Showing
with 81 additions and 405 deletions
...@@ -12,5 +12,4 @@ documentation/design/*.pdf ...@@ -12,5 +12,4 @@ documentation/design/*.pdf
.idea/modules.xml .idea/modules.xml
.idea/vcs.xml .idea/vcs.xml
.idea/workspace.xml .idea/workspace.xml
restconf/bin/bin restconf/bin/bin
test/.terraform.local/ \ No newline at end of file
...@@ -2,22 +2,16 @@ variables: ...@@ -2,22 +2,16 @@ variables:
SECURE_ANALYZERS_PREFIX: registry.gitlab.com/gitlab-org/security-products/analyzers SECURE_ANALYZERS_PREFIX: registry.gitlab.com/gitlab-org/security-products/analyzers
stages: stages:
- .pre
- test - test
- build - build
- deploy - deploy
- apply
- integration-test
- .post
default: before_script:
before_script: - git config --global url."https://$GO_MODULES_USER:$GO_MODULES_ACCESS_TOKEN@code.fbi.h-da.de".insteadOf "https://code.fbi.h-da.de"
- git config --global url."https://$GO_MODULES_USER:$GO_MODULES_ACCESS_TOKEN@code.fbi.h-da.de".insteadOf "https://code.fbi.h-da.de"
include: include:
- local: '/build/ci/.code-quality-ci.yml' - local: '/build/ci/.code-quality-ci.yml'
- local: '/build/ci/.documentation-ci.yml' - local: '/build/ci/.documentation-ci.yml'
- local: '/build/ci/.security-and-compliance-ci.yml' - local: '/build/ci/.security-and-compliance-ci.yml'
- local: '/build/ci/.build-container.yml' - local: '/build/ci/.build-container.yml'
- local: '/build/ci/.test.yml' - local: '/build/ci/.test.yml'
- local: '/build/ci/.terraform-ci.yml' \ No newline at end of file
\ No newline at end of file
# goSDN Architecture
This document describes the the high-level architecture of the goSDN project. All contributors should familiarize themselves with it. To avoid too much divergence from the changing code this document does focus on high-level concepts instead of implementation details.
## Bird's Eye View
[<img src="documentation/architecture.png" style="height:50%; width:50%" > ](documentation/architecture.png)
On the highest level goSDn provides a gRPC northbound-interface and two types of southbound-interfaces: RESTCONF and gRPC-based. The northbound interface allows the interaction with a running goSDN daemon and may allow the stacking of multiple controllers in the future. The southbound interface (SBI) capabilities are split in `nucleus` models and plugins. The supported `nucleus` models are OpenConfig yang [openconfig-yang](https://github.com/openconfig/yang) and TAPI. Third party models and more SBI-transports can be attached using the go plugin architecture.
The internal data representation uses [ygot](https://github.com/openconfig/ygot) generated go-structs.
It is important to note that these go-structs are generated from yang models and thus are not generic data structures. This means that the `nucleus` code is organized in silos, i.e., one particular southbound-interface is visible in the `nucleus`, as the internal data representation depend on the used yang modes in the southbound-interface.
## Code Map
This section briefly describes important directories and data structures. It also introduces important API calls to relevant libraries.
It also mentions **architecture invariants** and **API boundaries**
### `api`
API specification for gRPC and protobuf definitions.
**Architecture invariant:** To import gRPC related protobuf definitions use `pb` as an import prefix. For gNMI related protobuf definitions use `gpb`
### `forks`
Forks of `google/gnxi/gnmi` and `arista/goarista/gnmi` for gNMI server and client respectively. Subject of change once we converge to own clients and servers.
### `nucleus/principalNetworkDomain`
`nucleus` is the core package of goSDN. The main data structure is the `principalNetworkDomain` (PND). It reflects one administrative entity, i.e., as set of connected network devices, and is the source of truth for network state and configuration. A PND is SBI agnostic and supports multiple SBI implementations simultaneously.
**API boundary:** The PND' is the only way to interact with an `orchestratedNetworkingDevice`
### `nucleus/device`
This is the representation of an `orchestratedNetworkingDevice` (OND). An `orchestratedNetworkingDevice` is the network device that is directly managed by goSDN. It holds a reference to the device's `transport` and `southboundInterface` implementation. It contains a fakeroot device based on its attached SBI.
**Architecture invariant:** The device is does not provide any functionality to upper API layers.
### `nucleus/southbound`
Implementation of SBI specifics. Provides SBI models to other callers and SBI specific function deviations.
**Architecture invariant:** Only SBIs defined by a YANG model will be supported by goSDN.
### `nucleus/transport` `nucleus/gnmi_transport` `nucleus/restconf_transport`
Transport between goSDN and ONDs. Current core implementations are gNMI and RESTCONF. Additionally to implementing the transports the packages also provide a mapping from general purpose goSDN API calls to diverging SBI API calls.
For example `gNMI::Subscribe` and `RESTCONF::Push` are mapped to `gosdn::Subscribe`.
The `gnmi_transport` implementation uses `ytypes.SetNode` to write to a device struct.
image: docker:19.03.12
services:
- docker:19.03.12-dind
variables: variables:
DOCKER_TLS_CERTDIR: "/certs" ACTIVE_DEVELOP: "v.0.1.0-codename-threadbare"
DOCKER_IMAGE_SHA: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA DOCKER_IMAGE_SHA: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
build:docker: build:docker:
...@@ -12,9 +7,8 @@ build:docker: ...@@ -12,9 +7,8 @@ build:docker:
tags: tags:
- baremetal - baremetal
rules: rules:
- if: $CI_COMMIT_BRANCH == "develop" - if: $CI_COMMIT_BRANCH == $ACTIVE_DEVELOP
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script: script:
- > - >
docker build \ docker build \
...@@ -38,37 +32,20 @@ deploy:develop: ...@@ -38,37 +32,20 @@ deploy:develop:
TAG: $CI_REGISTRY_IMAGE:develop TAG: $CI_REGISTRY_IMAGE:develop
HOOK: $PORTAINER_HOOK_DEVELOP HOOK: $PORTAINER_HOOK_DEVELOP
rules: rules:
- if: $CI_COMMIT_BRANCH == "develop" - if: $CI_COMMIT_BRANCH == $ACTIVE_DEVELOP
<<: *deploy <<: *deploy
deploy:latest: deploy:tagged:
variables:
TAG: $CI_REGISTRY_IMAGE:latest
HOOK: $PORTAINER_HOOK_LATEST
rules: rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG
<<: *deploy
.deploy:mr: &deploy-mr
stage: deploy
needs: ["build:docker"]
tags:
- baremetal
script: script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker tag $DOCKER_IMAGE_SHA $TAG - docker tag $CI_REGISTRY_IMAGE:latest $CI_COMMIT_TAG
- docker push $TAG - docker push $CI_COMMIT_TAG
deploy:merge-request:master:
variables:
TAG: $CI_REGISTRY_IMAGE:mr-master
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
<<: *deploy-mr
deploy:merge-mr:develop: deploy:latest:
variables: variables:
TAG: $CI_REGISTRY_IMAGE:mr-develop TAG: $CI_REGISTRY_IMAGE:latest
rules: rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop' - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
<<: *deploy-mr <<: *deploy
image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
variables:
TF_ROOT: ${CI_PROJECT_DIR}/test/terraform
TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/integration
cache:
key: integration
paths:
- ${TF_ROOT}/.terraform
.terraform_prefab: &tf
variables:
CI_DEBUG_TRACE: "false"
before_script:
- cd ${TF_ROOT}
- export TF_VAR_integration_username=terraform
- export TF_VAR_integration_access_token=${TERRAFORM_API_TOKEN}
- export TF_VAR_integration_registry=${CI_REGISTRY}
- export TF_VAR_tls_key=${DOCKER_TLS_KEY}
- export TF_VAR_tls_cert=${DOCKER_TLS_CERT}
- export TF_VAR_tls_ca_cert=${DOCKER_TLS_CA}
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
variables:
TF_VAR_container_tag: $CI_REGISTRY_IMAGE:mr-master
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
variables:
TF_VAR_container_tag: $CI_REGISTRY_IMAGE:mr-develop
- if: $CI_COMMIT_BRANCH == "integration-test"
- if: $CI_COMMIT_BRANCH == "develop"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
init:
stage: .pre
script:
- gitlab-terraform init
<<: *tf
validate:
stage: test
script:
- gitlab-terraform validate
needs: ["init"]
<<: *tf
plan:
before_script:
- cd ${TF_ROOT}
stage: build
script:
- gitlab-terraform plan
- gitlab-terraform plan-json
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
needs: ["validate"]
<<: *tf
apply:
stage: apply
script:
- gitlab-terraform apply
dependencies:
- plan
<<: *tf
destroy:
stage: .post
script:
- gitlab-terraform destroy
<<: *tf
\ No newline at end of file
integration-test: unit-test-master:
image: golang:1.14 image: golang:1.14
stage: integration-test stage: test
rules: rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == "integration-test"
allow_failure: true
script: script:
- go test -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out - go test -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out
after_script: after_script:
- go tool cover -func=coverage.out - go tool cover -func=coverage.out
unit-test-merge-request:
image: golang:1.14
stage: integration-test
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
script:
- go test -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out
after_script:
- go tool cover -func=coverage.out
unit-test: unit-test:
image: golang:1.14 image: golang:1.14
stage: test stage: test
allow_failure: true allow_failure: true
rules: rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
script: script:
- go test -short -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out - go test -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out
after_script: after_script:
- go tool cover -func=coverage.out - go tool cover -func=coverage.out
\ No newline at end of file
package main
import (
"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
"context"
"fmt"
gpb "github.com/openconfig/gnmi/proto/gnmi"
log "github.com/sirupsen/logrus"
"strings"
)
func main() {
cfg := &gnmi.Config{
Addr: "[2003:e6:1722:fed0:0:242:ac11:5]:6030",
Username: "admin",
Password: "arista",
Encoding: gpb.Encoding_JSON_IETF,
}
transport, err := nucleus.NewGnmiTransport(cfg)
if err != nil {
log.Error(err)
}
resp, err := transport.Capabilities(context.Background())
if err != nil {
log.Error(err)
}
modelData := resp.(*gpb.CapabilityResponse).SupportedModels
b := strings.Builder{}
for _, elem := range modelData {
_, err := b.WriteString(elem.Name)
if err != nil {
log.Error(err)
}
_, err = b.WriteString("\n")
if err != nil {
log.Error(err)
}
}
fmt.Println(b.String())
}
...@@ -15,7 +15,7 @@ import ( ...@@ -15,7 +15,7 @@ import (
func main() { func main() {
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
sbi := &nucleus.OpenConfig{} sbi := &nucleus.AristaOC{}
device, err := nucleus.NewDevice("gnmi", sbi, device, err := nucleus.NewDevice("gnmi", sbi,
&nucleus.GnmiTransportOptions{ &nucleus.GnmiTransportOptions{
...@@ -29,24 +29,14 @@ func main() { ...@@ -29,24 +29,14 @@ func main() {
if err != nil { if err != nil {
log.Debug(err) log.Debug(err)
} }
pnd, err := nucleus.NewPND("openconfig", "a simple openconfig PND", uuid.New(), sbi) pnd, err := nucleus.NewPND("openconfig", "a simple openconfig PND", sbi)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if err := pnd.AddDevice(&device); err != nil { if err := pnd.AddDevice(device); err != nil {
log.Fatal(err) log.Fatal(err)
} }
cfg := &gnmi.Config{
Addr: "[2003:e6:1722:fed0:0:242:ac11:5]:6030",
Username: "admin",
Password: "arista",
Encoding: gpb.Encoding_JSON_IETF,
}
transport, _ := nucleus.NewGnmiTransport(cfg)
device.Transport = transport
paths := []string{"/interfaces/interface/name"} paths := []string{"/interfaces/interface/name"}
opts := &gnmi.SubscribeOptions{ opts := &gnmi.SubscribeOptions{
......
...@@ -13,15 +13,19 @@ import ( ...@@ -13,15 +13,19 @@ import (
func main() { func main() {
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
sbi := &nucleus.OpenConfig{} sbi := &nucleus.AristaOC{}
device := &nucleus.Device{ device, err := nucleus.NewDevice("gnmi", sbi,
GoStruct: sbi.Schema().Root, &nucleus.GnmiTransportOptions{
SBI: sbi, Addr: "portainer.danet.fbi.h-da.de:6030",
Config: nucleus.DeviceConfig{ Username: "admin",
Uuid: uuid.New(), Password: "arista",
}, SetNode: sbi.SetNode(),
Encoding: gpb.Encoding_JSON_IETF,
})
if err != nil {
log.Debug(err)
} }
pnd, err := nucleus.NewPND("openconfig", "test description", uuid.New(), sbi) pnd, err := nucleus.NewPND("openconfig", "test description", sbi)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
...@@ -29,22 +33,7 @@ func main() { ...@@ -29,22 +33,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
cfg := &gnmi.Config{ p := []string{"/interfaces/interface"}
Addr: "[2003:e6:1722:fed0:0:242:ac11:5]:6030",
Username: "admin",
Password: "arista",
Encoding: gpb.Encoding_JSON_IETF,
}
transport, err := nucleus.NewGnmiTransport(cfg)
if err != nil {
log.Fatal(err)
}
transport.SetNode = sbi.SetNode()
transport.Unmarshal = sbi.Unmarshal()
device.Transport = transport
p := []string{"/interfaces"}
errors := 0 errors := 0
for _, path := range p { for _, path := range p {
err := pnd.RequestAll(path) err := pnd.RequestAll(path)
......
...@@ -3,14 +3,10 @@ package main ...@@ -3,14 +3,10 @@ package main
import ( import (
"code.fbi.h-da.de/cocsn/gosdn/nucleus" "code.fbi.h-da.de/cocsn/gosdn/nucleus"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"os"
) )
func main() { func main() {
_, debug := os.LookupEnv("GOSDN_DEBUG") log.SetLevel(log.DebugLevel)
if debug {
log.SetLevel(log.DebugLevel)
}
// Setup a channel to communicate if goSDN should shutdown. // Setup a channel to communicate if goSDN should shutdown.
IsRunningChannel := make(chan bool) IsRunningChannel := make(chan bool)
......
...@@ -2,13 +2,13 @@ package main ...@@ -2,13 +2,13 @@ package main
import ( import (
"code.fbi.h-da.de/cocsn/gosdn/nucleus/util" "code.fbi.h-da.de/cocsn/gosdn/nucleus/util"
"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" "code.fbi.h-da.de/cocsn/yang-models/generated/arista"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
func main() { func main() {
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
schema, _ := openconfig.Schema() schema, _ := arista.Schema()
paths := util.NewPaths() paths := util.NewPaths()
paths.ParseSchema(schema, "device") paths.ParseSchema(schema, "device")
......
CliSocket = ":55055" CliSocket = "localhost:55055"
db.socket = "bolt://172.17.0.4:7687" db.socket = "bolt://172.17.0.4:7687"
db.user = "" db.user = ""
db.password = "" db.password = ""
......
documentation/architecture.png

162 KiB

...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
pb "github.com/openconfig/gnmi/proto/gnmi" pb "github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/gnmi/proto/gnmi_ext" "github.com/openconfig/gnmi/proto/gnmi_ext"
"google.golang.org/grpc/codes"
) )
// GetWithRequest takes a fully formed GetRequest, performs the Get, // GetWithRequest takes a fully formed GetRequest, performs the Get,
...@@ -53,6 +54,22 @@ func Get(ctx context.Context, client pb.GNMIClient, paths [][]string, ...@@ -53,6 +54,22 @@ func Get(ctx context.Context, client pb.GNMIClient, paths [][]string,
return GetWithRequest(ctx, client, req) return GetWithRequest(ctx, client, req)
} }
// Capabilities retuns the capabilities of the ciena.
func Capabilities(ctx context.Context, client pb.GNMIClient) error {
resp, err := client.Capabilities(ctx, &pb.CapabilityRequest{})
if err != nil {
return err
}
fmt.Printf("Version: %s\n", resp.GNMIVersion)
for _, mod := range resp.SupportedModels {
fmt.Printf("SupportedModel: %s\n", mod)
}
for _, enc := range resp.SupportedEncodings {
fmt.Printf("SupportedEncoding: %s\n", enc)
}
return nil
}
// val may be a path to a file or it may be json. First see if it is a // val may be a path to a file or it may be json. First see if it is a
// file, if so return its contents, otherwise return val // file, if so return its contents, otherwise return val
func extractJSON(val string) []byte { func extractJSON(val string) []byte {
...@@ -414,17 +431,24 @@ func newSetRequest(setOps []*Operation, exts ...*gnmi_ext.Extension) (*pb.SetReq ...@@ -414,17 +431,24 @@ func newSetRequest(setOps []*Operation, exts ...*gnmi_ext.Extension) (*pb.SetReq
return req, nil return req, nil
} }
// Set sends a SetRequest to the given client. // Set sends a SetRequest to the given ciena.
func Set(ctx context.Context, client pb.GNMIClient, setOps []*Operation, func Set(ctx context.Context, client pb.GNMIClient, setOps []*Operation,
exts ...*gnmi_ext.Extension) (*pb.SetResponse, error) { exts ...*gnmi_ext.Extension) error {
req, err := newSetRequest(setOps, exts...) req, err := newSetRequest(setOps, exts...)
if err != nil { if err != nil {
return nil, err return err
} }
return client.Set(ctx, req) resp, err := client.Set(ctx, req)
if err != nil {
return err
}
if resp.Message != nil && codes.Code(resp.Message.Code) != codes.OK {
return errors.New(resp.Message.Message)
}
return nil
} }
// Subscribe sends a SubscribeRequest to the given client. // Subscribe sends a SubscribeRequest to the given ciena.
// Deprecated: Use SubscribeErr instead. // Deprecated: Use SubscribeErr instead.
func Subscribe(ctx context.Context, client pb.GNMIClient, subscribeOptions *SubscribeOptions, func Subscribe(ctx context.Context, client pb.GNMIClient, subscribeOptions *SubscribeOptions,
respChan chan<- *pb.SubscribeResponse, errChan chan<- error) { respChan chan<- *pb.SubscribeResponse, errChan chan<- error) {
......
...@@ -76,14 +76,18 @@ func (_m *Transport) ProcessResponse(resp interface{}, root interface{}, models ...@@ -76,14 +76,18 @@ func (_m *Transport) ProcessResponse(resp interface{}, root interface{}, models
} }
// Set provides a mock function with given fields: ctx, params // Set provides a mock function with given fields: ctx, params
func (_m *Transport) Set(ctx context.Context, params ...interface{}) (interface{}, error) { func (_m *Transport) Set(ctx context.Context, params ...string) (interface{}, error) {
_va := make([]interface{}, len(params))
for _i := range params {
_va[_i] = params[_i]
}
var _ca []interface{} var _ca []interface{}
_ca = append(_ca, ctx) _ca = append(_ca, ctx)
_ca = append(_ca, params...) _ca = append(_ca, _va...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
var r0 interface{} var r0 interface{}
if rf, ok := ret.Get(0).(func(context.Context, ...interface{}) interface{}); ok { if rf, ok := ret.Get(0).(func(context.Context, ...string) interface{}); ok {
r0 = rf(ctx, params...) r0 = rf(ctx, params...)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
...@@ -92,7 +96,7 @@ func (_m *Transport) Set(ctx context.Context, params ...interface{}) (interface{ ...@@ -92,7 +96,7 @@ func (_m *Transport) Set(ctx context.Context, params ...interface{}) (interface{
} }
var r1 error var r1 error
if rf, ok := ret.Get(1).(func(context.Context, ...interface{}) error); ok { if rf, ok := ret.Get(1).(func(context.Context, ...string) error); ok {
r1 = rf(ctx, params...) r1 = rf(ctx, params...)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
......
...@@ -145,7 +145,7 @@ func (s *server) CreatePND(ctx context.Context, in *pb.CreatePNDRequest) (*pb.Cr ...@@ -145,7 +145,7 @@ func (s *server) CreatePND(ctx context.Context, in *pb.CreatePNDRequest) (*pb.Cr
return nil, err return nil, err
} }
id := uuid.New() id := uuid.New()
pnd, err := NewPND(in.GetName(), in.GetDescription(), id, sbi.(SouthboundInterface)) pnd, err := NewPNDwithId(in.GetName(), in.GetDescription(), id, sbi.(SouthboundInterface))
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return &pb.CreatePNDReply{Message: err.Error()}, err return &pb.CreatePNDReply{Message: err.Error()}, err
......
...@@ -374,4 +374,4 @@ func Test_server_Shutdown(t *testing.T) { ...@@ -374,4 +374,4 @@ func Test_server_Shutdown(t *testing.T) {
} }
}) })
} }
} }
\ No newline at end of file
package nucleus package nucleus
import ( import (
"github.com/google/uuid"
"os" "os"
"code.fbi.h-da.de/cocsn/gosdn/database" "code.fbi.h-da.de/cocsn/gosdn/database"
...@@ -29,7 +28,7 @@ func (c *Core) Initialize(IsRunningChannel chan bool) error { ...@@ -29,7 +28,7 @@ func (c *Core) Initialize(IsRunningChannel chan bool) error {
} }
// Set config defaults // Set config defaults
viper.SetDefault("socket", ":55055") viper.SetDefault("socket", "localhost:55055")
// Set config path and read config // Set config path and read config
viper.SetConfigName("gosdn") viper.SetConfigName("gosdn")
...@@ -57,10 +56,10 @@ func (c *Core) AttachDatabase() { ...@@ -57,10 +56,10 @@ func (c *Core) AttachDatabase() {
// CreateSouthboundInterfaces initializes the controller with its supported SBIs // CreateSouthboundInterfaces initializes the controller with its supported SBIs
func (c *Core) CreateSouthboundInterfaces() error { func (c *Core) CreateSouthboundInterfaces() error {
if err := c.sbic.add(&OpenConfig{id: uuid.New()}); err != nil { if err := c.sbic.add(&AristaOC{}); err != nil {
return err return err
} }
if err := c.sbic.add(&OpenConfig{id: uuid.New()}); err != nil { if err := c.sbic.add(&OpenConfig{}); err != nil {
return err return err
} }
return nil return nil
......
package nucleus package nucleus
import (
"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
"github.com/google/uuid"
"github.com/openconfig/ygot/ygot"
"reflect"
"testing"
)
func TestDevice_Id(t *testing.T) {
type fields struct {
GoStruct ygot.GoStruct
SBI SouthboundInterface
Config DeviceConfig
Transport Transport
}
tests := []struct {
name string
fields fields
want uuid.UUID
}{
{
name: "default",
fields: fields{
Config: DeviceConfig{
Uuid: did,
},
},
want: did,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := &Device{
GoStruct: tt.fields.GoStruct,
SBI: tt.fields.SBI,
Config: tt.fields.Config,
Transport: tt.fields.Transport,
}
if got := d.Id(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Id() = %v, want %v", got, tt.want)
}
})
}
}
func TestNewDevice(t *testing.T) {
sbi := &OpenConfig{}
type args struct {
sbi SouthboundInterface
addr string
username string
password string
transport Transport
}
tests := []struct {
name string
args args
want *Device
}{
{
name: "default",
args: args{
sbi: sbi,
addr: "testdevice",
username: "testuser",
password: "testpassword",
transport: &Gnmi{},
},
want: &Device{
GoStruct: &openconfig.Device{},
SBI: sbi,
Config: DeviceConfig{
Uuid: uuid.UUID{},
Address: "testdevice",
Username: "testuser",
Password: "testpassword",
},
Transport: &Gnmi{},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := NewDevice(tt.args.sbi, tt.args.addr, tt.args.username, tt.args.password, tt.args.transport)
tt.want.Config.Uuid = got.Id()
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewDevice() = %v, want %v", got, tt.want)
}
})
}
}
...@@ -33,26 +33,3 @@ type ErrInvalidTypeAssertion struct { ...@@ -33,26 +33,3 @@ type ErrInvalidTypeAssertion struct {
func (e ErrInvalidTypeAssertion) Error() string { func (e ErrInvalidTypeAssertion) Error() string {
return fmt.Sprintf("%v does not implement %v", e.v, e.t) return fmt.Sprintf("%v does not implement %v", e.v, e.t)
} }
type ErrUnsupportedPath struct {
p interface{}
}
func (e ErrUnsupportedPath) Error() string {
return fmt.Sprintf("path %v is not supported", e.p)
}
type ErrNotYetImplemented struct{}
func (e ErrNotYetImplemented) Error() string {
return fmt.Sprintf("function not yet implemented")
}
type ErrInvalidParameters struct {
f interface{}
r interface{}
}
func (e ErrInvalidParameters) Error() string {
return fmt.Sprintf("invalid parameters for %v: %v", e.f, e.r)
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment