diff --git a/cli/cmd/networkElementList.go b/cli/cmd/networkElementList.go index 7f5f1efd31f69823a37e4d54ca7601b9e62f92ea..d61c2ea781f82ac1c3c393c99bdf000ee30cd39f 100644 --- a/cli/cmd/networkElementList.go +++ b/cli/cmd/networkElementList.go @@ -55,7 +55,7 @@ var networkElementListCmd = &cobra.Command{ data := pterm.TableData{[]string{"UUID", "Name", "Plugin-UUID"}} for _, mne := range resp.GetMne() { - data = append(data, []string{mne.GetId(), mne.GetName(), mne.GetPid()}) + data = append(data, []string{mne.GetId(), mne.GetName(), mne.GetPluginid()}) } spinner.Success() diff --git a/cli/cmd/pndUse.go b/cli/cmd/pndUse.go index 6812edbd1a1a66972a84332dd4e8767735991342..5e849e2b31367fa8982966ec246bff953c486f54 100644 --- a/cli/cmd/pndUse.go +++ b/cli/cmd/pndUse.go @@ -62,7 +62,6 @@ var pndUseCmd = &cobra.Command{ } viper.Set("CLI_PND", newPND) - //viper.Set("CLI_SBI", sbi.GetSbi()[0].GetId()) err = viper.WriteConfig() if err != nil { diff --git a/controller/northbound/server/configurationmanagement.go b/controller/northbound/server/configurationmanagement.go index f6a86f4892c1db95ed062b39498a3ec384c566ca..fc616f2e925035791934eb4ac3da843ac5d8c127 100644 --- a/controller/northbound/server/configurationmanagement.go +++ b/controller/northbound/server/configurationmanagement.go @@ -229,19 +229,6 @@ func (c ConfigurationManagementServer) createElementsFromSDNConfig(sdnConfig *lo return nil } -//func (c ConfigurationManagementServer) createPlugins(sdnConfig *loadedSDNConfig) error { -// for _, inputPlugin := range sdnConfig.Plugins { -// plugin, err := nucleus.NewPluginThroughReattachConfig(inputPlugin) -// if err != nil { -// return err -// } -// if err := c.pluginService.Add(plugin); err != nil { -// return err -// } -// } -// return nil -//} - func (c ConfigurationManagementServer) createTopology(sdnConfig *loadedSDNConfig) error { for _, inputNode := range sdnConfig.Nodes { node := nodes.Node{ diff --git a/controller/nucleus/databasePluginStore.go b/controller/nucleus/databasePluginStore.go index b1f9a65c6b50a6442eaccb4080db1d44ab3d8c83..8c98e5a15e2750852815b2f0ae4d3527d0ebfeda 100644 --- a/controller/nucleus/databasePluginStore.go +++ b/controller/nucleus/databasePluginStore.go @@ -15,7 +15,7 @@ import ( log "github.com/sirupsen/logrus" ) -// DatabasePluginStore is used to store SouthboundInterfaces. +// DatabasePluginStore is used to store Plugins. type DatabasePluginStore struct { pluginStoreName string } @@ -45,7 +45,7 @@ func (s *DatabasePluginStore) Add(pluginToAdd plugin.Plugin) (err error) { return nil } -// Update updates a existing network element. +// Update updates an existing plugin. func (s *DatabasePluginStore) Update(pluginToUpdate plugin.Plugin) (err error) { var updatedLoadedPlugin plugin.LoadedPlugin diff --git a/controller/nucleus/gnmi_transport.go b/controller/nucleus/gnmi_transport.go index 46788363e701e9194450e7962a440fac94c6050d..20176b1f1027addcecaa42b6c3348a5b6a0d4d46 100644 --- a/controller/nucleus/gnmi_transport.go +++ b/controller/nucleus/gnmi_transport.go @@ -223,17 +223,14 @@ func (g *Gnmi) processResponseUpdates(updates []*gpb.Update) error { path := update.Path switch val := update.Val.Value.(type) { case *gpb.TypedValue_JsonVal: - //opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}} if err := g.Unmarshal(val.JsonVal, path); err != nil { errs = append(errs, err) } case *gpb.TypedValue_JsonIetfVal: - //opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}} if err := g.Unmarshal(val.JsonIetfVal, path); err != nil { errs = append(errs, err) } default: - //opts := []ytypes.SetNodeOpt{&ytypes.InitMissingElements{}, &ytypes.TolerateJSONInconsistencies{}} if err := g.SetNode(update.Path, update.Val); err != nil { errs = append(errs, err) } diff --git a/controller/nucleus/pluginFilesystemStore.go b/controller/nucleus/pluginFilesystemStore.go index d2ffc54e3203c58318e050f9cddb878cd214b0c1..cc48af4a242bbac3001ae6e668ec58fb6a82f658 100644 --- a/controller/nucleus/pluginFilesystemStore.go +++ b/controller/nucleus/pluginFilesystemStore.go @@ -12,13 +12,13 @@ import ( log "github.com/sirupsen/logrus" ) -// FilesystemPluginStore is used to store SouthboundInterfaces. +// FilesystemPluginStore is used to store Plugins. type FilesystemPluginStore struct { fileMutex sync.Mutex pathToPluginFile string } -// NewFilesystemPluginStore returns a filesystem implementation for a pnd store. +// NewFilesystemPluginStore returns a filesystem implementation for a plugin store. func NewFilesystemPluginStore() plugin.Store { if err := store.EnsureFilesystemStorePathExists(store.PluginFilenameSuffix); err != nil { log.Error(err) @@ -84,7 +84,7 @@ func (s *FilesystemPluginStore) Add(pluginToAdd plugin.Plugin) error { return nil } -// Update updates a existing network element. +// Update updates an existing plugin. func (s *FilesystemPluginStore) Update(pluginToUpdate plugin.Plugin) error { s.fileMutex.Lock() defer s.fileMutex.Unlock() @@ -140,8 +140,8 @@ func (s *FilesystemPluginStore) Delete(pluginToDelete plugin.Plugin) error { return &customerrs.CouldNotDeleteError{Identifier: pluginToDelete.ID(), Type: pluginToDelete, Err: err} } -// Get takes a SouthboundInterface's UUID or name and returns the SouthboundInterface. If the requested -// SouthboundInterface does not exist an error is returned. +// Get takes a Plugin's UUID or name and returns the Plugin. If the requested +// Plugin does not exist an error is returned. func (s *FilesystemPluginStore) Get(query store.Query) (plugin.LoadedPlugin, error) { s.fileMutex.Lock() defer s.fileMutex.Unlock() diff --git a/controller/nucleus/pluginStore.go b/controller/nucleus/pluginStore.go index fd424ddc3eefc00d8c0a0d139cd3803dcd4f3b88..cc68ab041fe7c22541a5f3a42cacd556b326310a 100644 --- a/controller/nucleus/pluginStore.go +++ b/controller/nucleus/pluginStore.go @@ -5,7 +5,7 @@ import ( "code.fbi.h-da.de/danet/gosdn/controller/store" ) -// NewPluginStore returns a sbiStore. +// NewPluginStore returns a pluginStore. func NewPluginStore() plugin.Store { storeMode := store.GetStoreMode() diff --git a/controller/plugin/shared/client.go b/controller/plugin/shared/client.go new file mode 100644 index 0000000000000000000000000000000000000000..fa9b0a030238254eab7e8c3dfe393bac43d2911a --- /dev/null +++ b/controller/plugin/shared/client.go @@ -0,0 +1,105 @@ +package shared + +import ( + "errors" + "io" + + "golang.org/x/net/context" + + pb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin" + ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" + gpb "github.com/openconfig/gnmi/proto/gnmi" + "github.com/sirupsen/logrus" +) + +type DeviceModelClient struct{ client pb.PluginClient } + +func (m *DeviceModelClient) Unmarshal(json []byte, path *gpb.Path) error { + _, err := m.client.Unmarshal(context.Background(), &pb.UnmarshalRequest{ + Json: json, + Path: path, + }) + return err +} + +func (m *DeviceModelClient) SetNode(path *gpb.Path, value *gpb.TypedValue) error { + _, err := m.client.SetNode(context.Background(), &pb.SetNodeRequest{ + Path: path, + Value: value, + }) + return err +} + +func (m *DeviceModelClient) GetNode(path *gpb.Path) ([]*gpb.Notification, error) { + resp, err := m.client.GetNode(context.Background(), &pb.GetNodeRequest{ + Path: path, + }) + return resp.GetNodes(), err +} + +func (m *DeviceModelClient) DeleteNode(path *gpb.Path) error { + _, err := m.client.DeleteNode(context.Background(), &pb.DeleteNodeRequest{ + Path: path, + }) + return err +} + +func (m *DeviceModelClient) Model(filterReadOnly bool) ([]byte, error) { + resp, err := m.client.Model(context.Background(), &pb.ModelRequest{ + FilterReadOnly: filterReadOnly, + }) + return resp.Json, err +} + +func (m *DeviceModelClient) Diff(original, modified []byte) (*gpb.Notification, error) { + resp, err := m.client.Diff(context.Background(), &pb.DiffRequest{ + Original: original, + Modified: modified, + }) + return resp.GetNotification(), err +} + +func (m *DeviceModelClient) ValidateChange(operation ppb.ApiOperation, path *gpb.Path, value []byte) ([]byte, error) { + resp, err := m.client.ValidateChange(context.Background(), &pb.ValidateChangeRequest{ + Operation: operation, + Path: path, + Value: value, + }) + return resp.GetModel(), err +} + +func (m *DeviceModelClient) PruneConfigFalse(value []byte) ([]byte, error) { + resp, err := m.client.PruneConfigFalse(context.Background(), &pb.PruneConfigFalseRequest{ + Value: value, + }) + return resp.GetModel(), err +} + +func (m *DeviceModelClient) SchemaTreeGzip() ([]byte, error) { + schemaTreeGzipClient, err := m.client.SchemaTreeGzip(context.Background(), &pb.SchemaTreeGzipRequest{}) + if err != nil { + return nil, err + } + + sTreeBytes := []byte{} + + for { + payload, err := schemaTreeGzipClient.Recv() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + logrus.Error(err) + + closeErr := schemaTreeGzipClient.CloseSend() + if closeErr != nil { + return nil, err + } + + return nil, err + } + sTreeBytes = append(sTreeBytes, payload.Chunk...) + } + + return sTreeBytes, nil +} diff --git a/controller/plugin/shared/grpc.go b/controller/plugin/shared/grpc.go deleted file mode 100644 index f0cd4e684037f0015f2b759a01cde0235b4d1941..0000000000000000000000000000000000000000 --- a/controller/plugin/shared/grpc.go +++ /dev/null @@ -1,209 +0,0 @@ -package shared - -import ( - "bytes" - "errors" - "io" - - "golang.org/x/net/context" - - pb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin" - ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" - gpb "github.com/openconfig/gnmi/proto/gnmi" - "github.com/sirupsen/logrus" -) - -type byteSize float64 - -// constants representing human friendly data sizes as per https://www.socketloop.com/tutorials/golang-how-to-declare-kilobyte-megabyte-gigabyte-terabyte-and-so-on -const ( - _ = iota // ignore first value by assigning to blank identifier - KB byteSize = 1 << (10 * iota) - MB -) - -type DeviceModelClient struct{ client pb.PluginClient } - -func (m *DeviceModelClient) Unmarshal(json []byte, path *gpb.Path) error { - _, err := m.client.Unmarshal(context.Background(), &pb.UnmarshalRequest{ - Json: json, - Path: path, - }) - return err -} - -func (m *DeviceModelClient) SetNode(path *gpb.Path, value *gpb.TypedValue) error { - _, err := m.client.SetNode(context.Background(), &pb.SetNodeRequest{ - Path: path, - Value: value, - }) - return err -} - -func (m *DeviceModelClient) GetNode(path *gpb.Path) ([]*gpb.Notification, error) { - resp, err := m.client.GetNode(context.Background(), &pb.GetNodeRequest{ - Path: path, - }) - return resp.GetNodes(), err -} - -func (m *DeviceModelClient) DeleteNode(path *gpb.Path) error { - _, err := m.client.DeleteNode(context.Background(), &pb.DeleteNodeRequest{ - Path: path, - }) - return err -} - -func (m *DeviceModelClient) Model(filterReadOnly bool) ([]byte, error) { - resp, err := m.client.Model(context.Background(), &pb.ModelRequest{ - FilterReadOnly: filterReadOnly, - }) - return resp.Json, err -} - -func (m *DeviceModelClient) Diff(original, modified []byte) (*gpb.Notification, error) { - resp, err := m.client.Diff(context.Background(), &pb.DiffRequest{ - Original: original, - Modified: modified, - }) - return resp.GetNotification(), err -} - -func (m *DeviceModelClient) ValidateChange(operation ppb.ApiOperation, path *gpb.Path, value []byte) ([]byte, error) { - resp, err := m.client.ValidateChange(context.Background(), &pb.ValidateChangeRequest{ - Operation: operation, - Path: path, - Value: value, - }) - return resp.GetModel(), err -} - -func (m *DeviceModelClient) PruneConfigFalse(value []byte) ([]byte, error) { - resp, err := m.client.PruneConfigFalse(context.Background(), &pb.PruneConfigFalseRequest{ - Value: value, - }) - return resp.GetModel(), err -} - -func (m *DeviceModelClient) SchemaTreeGzip() ([]byte, error) { - schemaTreeGzipClient, err := m.client.SchemaTreeGzip(context.Background(), &pb.SchemaTreeGzipRequest{}) - if err != nil { - return nil, err - } - - sTreeBytes := []byte{} - - for { - payload, err := schemaTreeGzipClient.Recv() - if err != nil { - if errors.Is(err, io.EOF) { - break - } - logrus.Error(err) - - closeErr := schemaTreeGzipClient.CloseSend() - if closeErr != nil { - return nil, err - } - - return nil, err - } - sTreeBytes = append(sTreeBytes, payload.Chunk...) - } - - return sTreeBytes, nil -} - -type DeviceModelServer struct { - Impl DeviceModel - pb.UnimplementedPluginServer -} - -func (m *DeviceModelServer) Unmarshal( - ctx context.Context, - req *pb.UnmarshalRequest) (*pb.UnmarshalResponse, error) { - err := m.Impl.Unmarshal(req.GetJson(), req.GetPath()) - if err != nil { - return &pb.UnmarshalResponse{Valid: false}, err - } - return &pb.UnmarshalResponse{Valid: true}, err -} - -func (m *DeviceModelServer) SetNode( - ctx context.Context, - req *pb.SetNodeRequest) (*pb.SetNodeResponse, error) { - err := m.Impl.SetNode(req.GetPath(), req.GetValue()) - return &pb.SetNodeResponse{Valid: true}, err -} - -func (m *DeviceModelServer) GetNode( - ctx context.Context, - req *pb.GetNodeRequest) (*pb.GetNodeResponse, error) { - nodes, err := m.Impl.GetNode(req.GetPath()) - return &pb.GetNodeResponse{Nodes: nodes}, err -} - -func (m *DeviceModelServer) DeleteNode( - ctx context.Context, - req *pb.DeleteNodeRequest) (*pb.DeleteNodeResponse, error) { - err := m.Impl.DeleteNode(req.GetPath()) - return &pb.DeleteNodeResponse{Valid: true}, err -} - -func (m *DeviceModelServer) Model( - ctx context.Context, - req *pb.ModelRequest) (*pb.ModelResponse, error) { - model, err := m.Impl.Model(req.GetFilterReadOnly()) - return &pb.ModelResponse{Json: model}, err -} - -func (m *DeviceModelServer) Diff( - ctx context.Context, - req *pb.DiffRequest) (*pb.DiffResponse, error) { - notification, err := m.Impl.Diff(req.GetOriginal(), req.GetModified()) - return &pb.DiffResponse{Notification: notification}, err -} - -func (m *DeviceModelServer) ValidateChange( - ctx context.Context, - req *pb.ValidateChangeRequest) (*pb.ValidateChangeResponse, error) { - model, err := m.Impl.ValidateChange(req.GetOperation(), req.GetPath(), req.GetValue()) - return &pb.ValidateChangeResponse{Model: model}, err -} - -func (m *DeviceModelServer) PruneConfigFalse( - ctx context.Context, - req *pb.PruneConfigFalseRequest) (*pb.PruneConfigFalseResponse, error) { - model, err := m.Impl.PruneConfigFalse(req.GetValue()) - return &pb.PruneConfigFalseResponse{Model: model}, err -} - -func (m *DeviceModelServer) SchemaTreeGzip( - req *pb.SchemaTreeGzipRequest, - stream pb.Plugin_SchemaTreeGzipServer) error { - buffer := make([]byte, int(MB)) - schema, err := m.Impl.SchemaTreeGzip() - if err != nil { - return err - } - - schemaReader := bytes.NewReader(schema) - - for { - n, err := schemaReader.Read(buffer) - if err != nil { - if errors.Is(err, io.EOF) { - logrus.Println(err) - } - break - } - logrus.WithField("n", n).Trace("read bytes") - payload := &pb.Payload{Chunk: buffer[:n]} - err = stream.Send(payload) - if err != nil { - return err - } - } - - return nil -} diff --git a/controller/plugin/shared/server.go b/controller/plugin/shared/server.go new file mode 100644 index 0000000000000000000000000000000000000000..1f863b09118fbbb94ed27582b30b8ee60c2fa3fc --- /dev/null +++ b/controller/plugin/shared/server.go @@ -0,0 +1,106 @@ +package shared + +import ( + "bytes" + "errors" + "io" + + "golang.org/x/net/context" + + pb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin" + "github.com/sirupsen/logrus" +) + +type DeviceModelServer struct { + Impl DeviceModel + pb.UnimplementedPluginServer +} + +func (m *DeviceModelServer) Unmarshal( + ctx context.Context, + req *pb.UnmarshalRequest) (*pb.UnmarshalResponse, error) { + err := m.Impl.Unmarshal(req.GetJson(), req.GetPath()) + if err != nil { + return &pb.UnmarshalResponse{Valid: false}, err + } + return &pb.UnmarshalResponse{Valid: true}, err +} + +func (m *DeviceModelServer) SetNode( + ctx context.Context, + req *pb.SetNodeRequest) (*pb.SetNodeResponse, error) { + err := m.Impl.SetNode(req.GetPath(), req.GetValue()) + return &pb.SetNodeResponse{Valid: true}, err +} + +func (m *DeviceModelServer) GetNode( + ctx context.Context, + req *pb.GetNodeRequest) (*pb.GetNodeResponse, error) { + nodes, err := m.Impl.GetNode(req.GetPath()) + return &pb.GetNodeResponse{Nodes: nodes}, err +} + +func (m *DeviceModelServer) DeleteNode( + ctx context.Context, + req *pb.DeleteNodeRequest) (*pb.DeleteNodeResponse, error) { + err := m.Impl.DeleteNode(req.GetPath()) + return &pb.DeleteNodeResponse{Valid: true}, err +} + +func (m *DeviceModelServer) Model( + ctx context.Context, + req *pb.ModelRequest) (*pb.ModelResponse, error) { + model, err := m.Impl.Model(req.GetFilterReadOnly()) + return &pb.ModelResponse{Json: model}, err +} + +func (m *DeviceModelServer) Diff( + ctx context.Context, + req *pb.DiffRequest) (*pb.DiffResponse, error) { + notification, err := m.Impl.Diff(req.GetOriginal(), req.GetModified()) + return &pb.DiffResponse{Notification: notification}, err +} + +func (m *DeviceModelServer) ValidateChange( + ctx context.Context, + req *pb.ValidateChangeRequest) (*pb.ValidateChangeResponse, error) { + model, err := m.Impl.ValidateChange(req.GetOperation(), req.GetPath(), req.GetValue()) + return &pb.ValidateChangeResponse{Model: model}, err +} + +func (m *DeviceModelServer) PruneConfigFalse( + ctx context.Context, + req *pb.PruneConfigFalseRequest) (*pb.PruneConfigFalseResponse, error) { + model, err := m.Impl.PruneConfigFalse(req.GetValue()) + return &pb.PruneConfigFalseResponse{Model: model}, err +} + +func (m *DeviceModelServer) SchemaTreeGzip( + req *pb.SchemaTreeGzipRequest, + stream pb.Plugin_SchemaTreeGzipServer) error { + buffer := make([]byte, int(MB)) + schema, err := m.Impl.SchemaTreeGzip() + if err != nil { + return err + } + + schemaReader := bytes.NewReader(schema) + + for { + n, err := schemaReader.Read(buffer) + if err != nil { + if errors.Is(err, io.EOF) { + logrus.Println(err) + } + break + } + logrus.WithField("n", n).Trace("read bytes") + payload := &pb.Payload{Chunk: buffer[:n]} + err = stream.Send(payload) + if err != nil { + return err + } + } + + return nil +} diff --git a/controller/plugin/shared/util.go b/controller/plugin/shared/util.go new file mode 100644 index 0000000000000000000000000000000000000000..94577930618a01910212f49b328787c311e19490 --- /dev/null +++ b/controller/plugin/shared/util.go @@ -0,0 +1,10 @@ +package shared + +type byteSize float64 + +// constants representing human friendly data sizes as per https://www.socketloop.com/tutorials/golang-how-to-declare-kilobyte-megabyte-gigabyte-terabyte-and-so-on +const ( + _ = iota // ignore first value by assigning to blank identifier + KB byteSize = 1 << (10 * iota) + MB +) diff --git a/controller/store/filesystem-settings.go b/controller/store/filesystem-settings.go index 3db8c454a912f7eac4bd81ff762b002ea390e34d..d294018d2ec3a2a9dcfda769c926c3675048a3e6 100644 --- a/controller/store/filesystem-settings.go +++ b/controller/store/filesystem-settings.go @@ -3,9 +3,11 @@ package store const ( // PndFilename is the name of the file where the pnds are stored. PndFilename string = "pndStore.json" - // NetworkElementFilenameSuffix is the suffix of the file where the network elements are stored. + // NetworkElementFilenameSuffix is the suffix of the file where the network + // elements are stored. NetworkElementFilenameSuffix string = "networkElementStore.json" - // PluginFilenameSuffix is the suffix of the file where the sbis are stored. + // PluginFilenameSuffix is the suffix of the file where the plugins are + // stored. PluginFilenameSuffix string = "pluginStore.json" // UserFilename is the name of the file where the users are stored. UserFilename string = "userStore.json"