diff --git a/cmd/gnmi/gnmi.go b/cmd/gnmi/gnmi.go
new file mode 100644
index 0000000000000000000000000000000000000000..73ba7e4e742aedc38e7107843f35c13de303a127
--- /dev/null
+++ b/cmd/gnmi/gnmi.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
+	"context"
+	"fmt"
+	"github.com/google/uuid"
+	log "github.com/sirupsen/logrus"
+)
+
+func main() {
+	log.SetLevel(log.DebugLevel)
+	sbi := &nucleus.OpenConfig{}
+	device := nucleus.Device{
+		Device: &openconfig.Device{},
+		SBI:    sbi,
+		Config: nucleus.DeviceConfig{
+			Uuid:     uuid.New(),
+			Address:  "[fdfd::ce05]:6030",
+			Username: "admin",
+			Password: "arista",
+		},
+	}
+	pnd := nucleus.NewPND("openconfig", sbi)
+	if err := pnd.AddDevice(device); err != nil {
+		log.Fatal(err)
+	}
+
+	cfg := &gnmi.Config{
+		Addr:     device.Config.Address,
+		Password: device.Config.Password,
+		Username: device.Config.Username,
+	}
+	ctx := gnmi.NewContext(context.Background(), cfg)
+	ctx = context.WithValue(ctx, "config", cfg)
+
+	paths := []string{"/interfaces/interface[name=*]/name"}
+	req, err := gnmi.NewGetRequest(gnmi.SplitPaths(paths), "")
+	resp, err := nucleus.GetWithRequest(ctx, req)
+	if err != nil {
+		log.Fatal(err)
+	}
+	if err := device.Add(resp); err != nil {
+		panic(err)
+	}
+	fmt.Println(device.Config)
+}
diff --git a/go.mod b/go.mod
index 18a744f00851d8fb4d8938f5cdd25b0ab64c1367..6a938d1b029c2d5054851cf2f33fe3c59d5e2f4f 100644
--- a/go.mod
+++ b/go.mod
@@ -10,15 +10,17 @@ require (
 	github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591
 	github.com/go-openapi/runtime v0.19.22
 	github.com/go-openapi/strfmt v0.19.5
+	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
 	github.com/golang/protobuf v1.4.2
 	github.com/neo4j/neo4j-go-driver v1.8.3
-	github.com/onsi/ginkgo v1.13.0 // indirect
-	github.com/openconfig/goyang v0.2.2
+	github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802
+	github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696
 	github.com/openconfig/ygot v0.10.0
+	github.com/openconfig/goyang v0.2.2
 	github.com/rivo/tview v0.0.0-20201018122409-d551c850a743
 	github.com/sirupsen/logrus v1.4.2
 	github.com/tidwall/gjson v1.6.3
-	golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
+	golang.org/x/net v0.0.0-20200904194848-62affa334b73
 	google.golang.org/grpc v1.29.1
 	google.golang.org/protobuf v1.23.0
 )
diff --git a/go.sum b/go.sum
index 4859ca533eb6d8a4e14aa7435fc22ee7b5009841..c2fe06749f579f477b3461e16b0838a9fa9cdcfb 100644
--- a/go.sum
+++ b/go.sum
@@ -33,6 +33,11 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/frankban/quicktest v1.7.2 h1:2QxQoC1TS09S7fhCPsrvqYdvP1H5M1P1ih5ABm3BTYk=
+github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
@@ -222,16 +227,17 @@ github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapN
 github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be h1:VEK8utxoyZu/hkpjLxvuBmK5yW3NmBo/v/Wu5VQAJVs=
 github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A=
 github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU=
-github.com/openconfig/goyang v0.0.0-20200616001533-c0659aea65dd/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
-github.com/openconfig/goyang v0.0.0-20200917201611-633eccb6fa97 h1:TaCuNSX/fiTuky8ouzC+JaCJN+OSOpjtYlLrn/uXxxE=
-github.com/openconfig/goyang v0.0.0-20200917201611-633eccb6fa97/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
+github.com/openconfig/goyang v0.2.1/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
 github.com/openconfig/goyang v0.2.2 h1:J8hlJk1GSHrcr9vVI7dTvsThsKihWcNXRjWOkjRK0Cw=
 github.com/openconfig/goyang v0.2.2/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
+github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696 h1:yHCGAHg2zMaW8olLrqEt3SAHGcEx2aJPEQWMRCyravY=
+github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
 github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs=
-github.com/openconfig/ygot v0.8.7 h1:BKErV6vM15YGM1+XHDuLAQ938dYahzSgwlt9BIGFrdY=
-github.com/openconfig/ygot v0.8.7/go.mod h1:AqXe0HNEITTcmcYkr+yzDMY8ofitImUdfZV4IgRsJWU=
+github.com/openconfig/ygot v0.8.11/go.mod h1:Qh/F0ycMLXJlZn4cR+5iuefEMthLggO8KBq8wjXYPTY=
 github.com/openconfig/ygot v0.10.0 h1:EmgwLXbFiCBmEUlSI4/1fPuRzgf4EsD0sThmAmRqbYM=
 github.com/openconfig/ygot v0.10.0/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3 h1:YtFkrqsMEj7YqpIhRteVxJxCeC3jJBieuLr0d4C4rSA=
 github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
diff --git a/nucleus/device.go b/nucleus/device.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd3dcb722746e8f0b3c1379cc6daae99fbc40e4e
--- /dev/null
+++ b/nucleus/device.go
@@ -0,0 +1,46 @@
+package nucleus
+
+import (
+	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
+	"github.com/google/uuid"
+	pb "github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/openconfig/ygot/ygot"
+	"github.com/openconfig/ygot/ytypes"
+)
+
+type Device struct {
+	Device    ygot.GoStruct
+	SBI       SouthboundInterface
+	Config    DeviceConfig
+	Transport Transport
+}
+
+// Add adds a property to a device. Please
+// use better naming in further develop
+// Also all that Interface Call specific logic belongs to SBI!
+func (d Device) Add(resp interface{}) error {
+	s, err := openconfig.Schema()
+	if err != nil {
+		return err
+	}
+	models := s.SchemaTree
+	opts := []ytypes.SetNodeOpt{&ytypes.InitMissingElements{}, &ytypes.TolerateJSONInconsistencies{}}
+	r := resp.(*pb.GetResponse)
+	rn := r.Notification
+	for _, msg := range rn {
+		for _, val := range msg.Update {
+			schema := models["Device"]
+			if err := ytypes.SetNode(schema, d.Device.(*openconfig.Device), val.Path, val.Val, opts...); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+type DeviceConfig struct {
+	Uuid     uuid.UUID
+	Address  string
+	Username string
+	Password string
+}
diff --git a/nucleus/device_test.go b/nucleus/device_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f89d7d0fd7844082c76c530eed2d2acf4118007
--- /dev/null
+++ b/nucleus/device_test.go
@@ -0,0 +1,37 @@
+package nucleus
+
+import (
+	"github.com/openconfig/ygot/ygot"
+	log "github.com/sirupsen/logrus"
+	"testing"
+)
+
+func TestDevice_Add(t *testing.T) {
+	type fields struct {
+		Device    ygot.GoStruct
+		SBI       SouthboundInterface
+		Config    DeviceConfig
+		Transport Transport
+	}
+	type args struct {
+		resp interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := Device{
+				Device:    tt.fields.Device,
+				SBI:       tt.fields.SBI,
+				Config:    tt.fields.Config,
+				Transport: tt.fields.Transport,
+			}
+			log.Debug(d.SBI.SbiIdentifier())
+		})
+	}
+}
\ No newline at end of file
diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..24af7305c9a272af5d4cced6441d1994fb88ddd0
--- /dev/null
+++ b/nucleus/gnmi_transport_test.go
@@ -0,0 +1,194 @@
+package nucleus
+
+import (
+	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
+	"context"
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/openconfig/gnmi/proto/gnmi_ext"
+	"reflect"
+	"testing"
+)
+
+func TestGetWithRequest(t *testing.T) {
+	type args struct {
+		ctx context.Context
+		req *gpb.GetRequest
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetWithRequest(tt.args.ctx, tt.args.req)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetWithRequest() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetWithRequest() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_Capabilities(t *testing.T) {
+	type args struct {
+		ctx context.Context
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := tt.g.Capabilities(tt.args.ctx)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Capabilities() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_Close(t *testing.T) {
+	tests := []struct {
+		name    string
+		g       Gnmi
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.Close(); (err != nil) != tt.wantErr {
+				t.Errorf("Close() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGnmi_Get(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		paths  [][]string
+		origin string
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := tt.g.Get(tt.args.ctx, tt.args.paths, tt.args.origin)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Get() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_GetConfig(t *testing.T) {
+	tests := []struct {
+		name string
+		g    Gnmi
+		want interface{}
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := tt.g.GetConfig(); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetConfig() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_Set(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		setOps []*gnmi.Operation
+		exts   []*gnmi_ext.Extension
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.Set(tt.args.ctx, tt.args.setOps, tt.args.exts...); (err != nil) != tt.wantErr {
+				t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGnmi_SetConfig(t *testing.T) {
+	type args struct {
+		in0 interface{}
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.SetConfig(tt.args.in0); (err != nil) != tt.wantErr {
+				t.Errorf("SetConfig() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGnmi_Subscribe(t *testing.T) {
+	type args struct {
+		ctx              context.Context
+		subscribeOptions *gnmi.SubscribeOptions
+		respChan         chan<- *gpb.SubscribeResponse
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.Subscribe(tt.args.ctx, tt.args.subscribeOptions, tt.args.respChan); (err != nil) != tt.wantErr {
+				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/nucleus/interfaces/clientConfig.go b/nucleus/interfaces/clientConfig.go
index b90df804102925a958eea25977486e275ebd48c3..ccfbcd80a8e5bdc9a9cd406b1dc12640b6c9982d 100644
--- a/nucleus/interfaces/clientConfig.go
+++ b/nucleus/interfaces/clientConfig.go
@@ -2,6 +2,7 @@ package interfaces
 
 // ClientConfig contains SBI client
 // configuration parameters
+// Deprecated in favor of spf viper
 type ClientConfig struct {
 	Identifier           string `toml:"identifier"`
 	Endpoint             string `toml:"endpoint"`
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..133195a8d7e0cf2a3203c2c1bfc6aa4d74602a52
--- /dev/null
+++ b/nucleus/principalNetworkDomain_test.go
@@ -0,0 +1,281 @@
+package nucleus
+
+import (
+	"github.com/google/uuid"
+	"reflect"
+	"testing"
+)
+
+func TestNewPND(t *testing.T) {
+	type args struct {
+		name string
+		sbi  SouthboundInterface
+	}
+	tests := []struct {
+		name string
+		args args
+		want PrincipalNetworkDomain
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NewPND(tt.args.name, tt.args.sbi); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("NewPND() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_addSbi(t *testing.T) {
+	tests := []struct {
+		name    string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := addSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("addSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_destroy(t *testing.T) {
+	tests := []struct {
+		name    string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := destroy(); (err != nil) != tt.wantErr {
+				t.Errorf("destroy() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_AddDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		device Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.AddDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_AddSbi(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.AddSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("AddSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_Destroy(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.Destroy(); (err != nil) != tt.wantErr {
+				t.Errorf("Destroy() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_RemoveDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		uuid uuid.UUID
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.RemoveDevice(tt.args.uuid); (err != nil) != tt.wantErr {
+				t.Errorf("RemoveDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_RemoveSbi(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.RemoveSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_addDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		device Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.addDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("addDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_removeDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		uuid uuid.UUID
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.removeDevice(tt.args.uuid); (err != nil) != tt.wantErr {
+				t.Errorf("removeDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_removeSbi(t *testing.T) {
+	tests := []struct {
+		name    string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := removeSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("removeSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/nucleus/restconf_transport_test.go b/nucleus/restconf_transport_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..57fb9de6f74e08b09fd1a93e551286d87b4358aa
--- /dev/null
+++ b/nucleus/restconf_transport_test.go
@@ -0,0 +1,67 @@
+package nucleus
+
+import (
+	"context"
+	"reflect"
+	"testing"
+)
+
+func TestRestconf_GetConfig(t *testing.T) {
+	tests := []struct {
+		name string
+		want interface{}
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			rc := &Restconf{}
+			if got := rc.GetConfig(); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetConfig() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestRestconf_SetConfig(t *testing.T) {
+	type args struct {
+		in0 interface{}
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			rc := &Restconf{}
+			if err := rc.SetConfig(tt.args.in0); (err != nil) != tt.wantErr {
+				t.Errorf("SetConfig() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestRestconf_Subscribe(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		params []string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			rc := &Restconf{}
+			if err := rc.Subscribe(tt.args.ctx, tt.args.params...); (err != nil) != tt.wantErr {
+				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
new file mode 100644
index 0000000000000000000000000000000000000000..a3aa5af682a41581b53ce03e69526a5e34454349
--- /dev/null
+++ b/nucleus/southbound.go
@@ -0,0 +1,26 @@
+package nucleus
+
+// SouthboundInterface provides an
+// interface for SBI implementations
+type SouthboundInterface interface {
+	SbiIdentifier() string
+}
+
+type Tapi struct {
+}
+
+type OpenConfig struct {
+	transport Transport
+}
+
+func (oc *OpenConfig) SbiIdentifier() string {
+	return "openconfig"
+}
+
+func (oc *OpenConfig) OpenconfigInterfaces(device Device) {
+	resp, err := oc.transport.Get(nil, nil...)
+	if err != nil {
+
+	}
+	device.Add(resp)
+}
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..447696fa7cb6350f089bed728ea31b5ea01af477
--- /dev/null
+++ b/nucleus/southbound_test.go
@@ -0,0 +1,50 @@
+package nucleus
+
+import "testing"
+
+func TestOpenConfig_SbiIdentifier(t *testing.T) {
+	type fields struct {
+		transport Transport
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{name: "default", want: "openconfig"},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oc := &OpenConfig{
+				transport: tt.fields.transport,
+			}
+			if got := oc.SbiIdentifier(); got != tt.want {
+				t.Errorf("SbiIdentifier() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenConfig_OpenconfigInterfaces(t *testing.T) {
+	type fields struct {
+		transport Transport
+	}
+	type args struct {
+		device Device
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oc := &OpenConfig{
+				transport: tt.fields.transport,
+			}
+			oc.OpenconfigInterfaces(tt.args.device)
+		})
+	}
+}
\ No newline at end of file