diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go index d626a94b8ad0623248b9f1cbb2eac9634a216c35..870af9eaeb787c8cbf6cb7de90bf2d9ea40e4870 100644 --- a/nucleus/gnmi_transport.go +++ b/nucleus/gnmi_transport.go @@ -23,14 +23,15 @@ const ( // CtxKeyOpts context key for gnmi.SubscribeOptions CtxKeyOpts CtxKeyType = "opts" // CtxKeyConfig is a context key for gnmi.Config - CtxKeyConfig = "config" + CtxKeyConfig = "config" + // CtxKeyOperation is a context key for a gNMI operation (update, replace, delete) CtxKeyOperation = "op" ) var opmap = map[Operation]string{ - TRANSPORT_UPDATE: "update", - TRANSPORT_REPLACE: "replace", - TRANSPORT_DELETE: "delete", + TransportUpdate: "update", + TransportReplace: "replace", + TransportDelete: "delete", } // Gnmi implements the Transport interface and provides an SBI with the @@ -114,8 +115,8 @@ func (g *Gnmi) Set(ctx context.Context, args ...interface{}) error { } } opts = append(opts, &gnmi.Operation{ - // Hardcoded TRANSPORT_UPDATE until multiple operations are supported - Type: opmap[TRANSPORT_UPDATE], + // Hardcoded TransportUpdate until multiple operations are supported + Type: opmap[TransportUpdate], Origin: "", Target: "", Path: gnmi.SplitPath(attrs[0]), @@ -185,9 +186,9 @@ func (g *Gnmi) applyDiff(ctx context.Context, payload ...interface{}) error { req := &gpb.SetRequest{} if diff.Update != nil { switch op { - case TRANSPORT_UPDATE: + case TransportUpdate: req.Update = diff.Update - case TRANSPORT_REPLACE: + case TransportReplace: req.Replace = diff.Update default: return &ErrOperationNotSupported{} diff --git a/nucleus/http.go b/nucleus/http.go index 887fa10175b02bfabf8a36e6bb4d844535adff6e..ee0590e4e5645ff665417c9be7ec3d6b1542d220 100644 --- a/nucleus/http.go +++ b/nucleus/http.go @@ -14,9 +14,9 @@ import ( ) var apiOpmap = map[string]Operation{ - "update": TRANSPORT_UPDATE, - "replace": TRANSPORT_REPLACE, - "delete": TRANSPORT_DELETE, + "update": TransportUpdate, + "replace": TransportReplace, + "delete": TransportDelete, } func stopHttpServer() error { @@ -190,7 +190,7 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) { } writer.WriteHeader(http.StatusOK) case "delete": - if err := pnd.ChangeOND(id, TRANSPORT_DELETE, query.Get("path")); err != nil { + if err := pnd.ChangeOND(id, TransportDelete, query.Get("path")); err != nil { handleServerError(writer, err) return } diff --git a/nucleus/pnd/change.go b/nucleus/pnd/change.go index bc5a34bd446ec93d77c33e0ec8f367072f4c7a51..55c7fc539f515d4383a6e9b5783986ed6feac270 100644 --- a/nucleus/pnd/change.go +++ b/nucleus/pnd/change.go @@ -30,6 +30,10 @@ func init() { log.Debugf("change timeout set to %v", changeTimeout) } +// NewChange takes a Device UUID, a pair GoStructs (current and intended state) +// a callback function and a channel for errors and returns a *Change +// The callback function is used by the Commit() and Confirm() functions. It +// must define how the change is carried out. func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruct, callback func(ygot.GoStruct, ygot.GoStruct) error, errChan chan error) *Change { return &Change{ cuid: uuid.New(), @@ -66,10 +70,14 @@ type Change struct { Done chan int } +// ID returns the Change's UUID func (c *Change) ID() uuid.UUID { return c.cuid } +// Commit pushes the cange to the OND using the callback() function +// and starts the timeout-timer for the Change. If the timer expires +// the change is rolled back. func (c *Change) Commit() error { if err := c.callback(c.intendedState, c.previousState); err != nil { return err @@ -102,6 +110,7 @@ func (c *Change) rollbackHandler(ctx context.Context) { } } +// Confirm confirms a committed Change and stops the rollback timer. func (c *Change) Confirm() error { c.lock.RLock() if !c.committed { diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go index c7248c322f203c19173af3d97976c4b9cec865a6..6a2da78f52ea9322b8290d5aa6d4d6261fe59def 100644 --- a/nucleus/principalNetworkDomain.go +++ b/nucleus/principalNetworkDomain.go @@ -2,7 +2,7 @@ package nucleus import ( "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - . "code.fbi.h-da.de/cocsn/gosdn/nucleus/pnd" + . "code.fbi.h-da.de/cocsn/gosdn/nucleus/pnd" //nolint "context" "github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ytypes" @@ -288,12 +288,12 @@ func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation interface{}, p } switch operation { - case TRANSPORT_UPDATE, TRANSPORT_REPLACE: + case TransportUpdate, TransportReplace: typedValue := gnmi.TypedValue(value[0]) if err := ytypes.SetNode(d.SBI.Schema().RootSchema(), cpy, p, typedValue); err != nil { return err } - case TRANSPORT_DELETE: + case TransportDelete: if err := ytypes.DeleteNode(d.SBI.Schema().RootSchema(), cpy, p); err != nil { return err } diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go index b5e274353e535894ba131ab799042f5a07ba2add..8b4ff39d341034c9a38379884b29bfb50dfd5b04 100644 --- a/nucleus/principalNetworkDomain_test.go +++ b/nucleus/principalNetworkDomain_test.go @@ -543,7 +543,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { fields: fields{}, args: args{ uuid: mdid, - operation: TRANSPORT_UPDATE, + operation: TransportUpdate, path: "/system/config/hostname", value: []string{"ceos3000"}, }, @@ -554,7 +554,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { fields: fields{}, args: args{ uuid: mdid, - operation: TRANSPORT_REPLACE, + operation: TransportReplace, path: "/system/config/hostname", value: []string{"ceos3000"}, }, @@ -565,7 +565,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { fields: fields{}, args: args{ uuid: mdid, - operation: TRANSPORT_DELETE, + operation: TransportDelete, path: "/system/config/hostname", }, wantErr: false, @@ -575,7 +575,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { fields: fields{}, args: args{ uuid: mdid, - operation: TRANSPORT_DELETE, + operation: TransportDelete, path: "/system/config/hostname", value: []string{"ceos3000"}, }, @@ -597,7 +597,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { fields: fields{}, args: args{ uuid: mdid, - operation: TRANSPORT_UPDATE, + operation: TransportUpdate, path: "/system/config/hostname", value: []string{"ceos3000", "ceos3001"}, }, @@ -608,7 +608,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { fields: fields{}, args: args{ uuid: did, - operation: TRANSPORT_UPDATE, + operation: TransportUpdate, }, wantErr: true, }, diff --git a/nucleus/store.go b/nucleus/store.go index aeed8cb8f11e176d75878c1657e3f1c83f9f388a..7f6b98fed1ed15b2e23a4c3efb9ed2dce25d83e7 100644 --- a/nucleus/store.go +++ b/nucleus/store.go @@ -1,7 +1,7 @@ package nucleus import ( - . "code.fbi.h-da.de/cocsn/gosdn/nucleus/pnd" + p "code.fbi.h-da.de/cocsn/gosdn/nucleus/pnd" "github.com/google/uuid" log "github.com/sirupsen/logrus" "reflect" @@ -145,16 +145,16 @@ type changeStore struct { store } -func (s changeStore) get(id uuid.UUID) (*Change, error) { +func (s changeStore) get(id uuid.UUID) (*p.Change, error) { item, err := s.store.get(id) if err != nil { return nil, err } - change, ok := item.(*Change) + change, ok := item.(*p.Change) if !ok { return nil, &ErrInvalidTypeAssertion{ v: change, - t: reflect.TypeOf(&Change{}), + t: reflect.TypeOf(&p.Change{}), } } log.WithFields(log.Fields{ diff --git a/nucleus/transport.go b/nucleus/transport.go index 2d9313d591acb6e66667d20f1abf81deca3daeaf..6df6e6b7de23206a7b8e1c692d897cfe5fbb9e0b 100644 --- a/nucleus/transport.go +++ b/nucleus/transport.go @@ -7,17 +7,22 @@ import ( "io" ) +// Operation codes numerous operations used to change the state of remote resources. +// It is used as a unified code. Each Transport implementation needs to map these +// accordingly to its specification. type Operation int const ( - TRANSPORT_UPDATE Operation = iota - TRANSPORT_REPLACE - TRANSPORT_DELETE + // TransportUpdate codes an update operation + TransportUpdate Operation = iota + // TransportReplace codes a replace operation + TransportReplace + // TransportDelete codes a delete operation + TransportDelete ) -// Transport provides an interface for -// Transport implementations like RESTCONF -// or gnmi +// Transport provides an interface for Transport implementations +// like RESTCONF or gnmi type Transport interface { Get(ctx context.Context, params ...string) (interface{}, error) Set(ctx context.Context, params ...interface{}) error diff --git a/nucleus/util/path/translate.go b/nucleus/util/path/translate.go index 383abc80c0a9fa1ff5431acc01fe09fe89084363..e245344085d02130b5277334df9546aab98bc197 100644 --- a/nucleus/util/path/translate.go +++ b/nucleus/util/path/translate.go @@ -5,23 +5,7 @@ import ( "strings" ) -func FromString(path string) *gpb.Path { - elements := strings.Split(path, delim) - elem := make([]*gpb.PathElem, len(elements)) - for i, e := range elements { - elem[i] = &gpb.PathElem{ - Name: e, - Key: nil, - } - } - return &gpb.Path{ - Element: nil, - Origin: "", - Elem: elem, - Target: "", - } -} - +// ToStrings translates a gNMI path to a slice of strings func ToStrings(path *gpb.Path) []string { elems := make([]string, len(path.Elem)) for i, e := range path.Elem {