diff --git a/cli/adapter/PndAdapter.go b/cli/adapter/PndAdapter.go index a02ac56ea36adfc4f457dd03484b76fbf1d8e8fa..949b6cb103bb13005d379fb74cc80502e6e85d9c 100644 --- a/cli/adapter/PndAdapter.go +++ b/cli/adapter/PndAdapter.go @@ -75,7 +75,8 @@ func (p *PndAdapter) GetDevice(ctx context.Context, identifier string) (*ppb.Get } // GetDevices requests all devices belonging to the PrincipalNetworkDomain -// attached to this adapter. +// attached to this adapter. The requested devices also contain their config +// information as gNMI notifications. func (p *PndAdapter) GetDevices(ctx context.Context) (*ppb.GetOndListResponse, error) { resp, err := api.GetDevices(ctx, p.endpoint, p.id.String()) if err != nil { @@ -84,6 +85,17 @@ func (p *PndAdapter) GetDevices(ctx context.Context) (*ppb.GetOndListResponse, e return resp, nil } +// GetFlattenedDevices requests all devices belonging to the PrincipalNetworkDomain +// attached to this adapter. The devices do not contain the config information +// as gNMI notifications. +func (p *PndAdapter) GetFlattenedDevices(ctx context.Context) (*ppb.GetFlattenedOndListResponse, error) { + resp, err := api.GetFlattenedDevices(ctx, p.endpoint, p.id.String()) + if err != nil { + return nil, err + } + return resp, nil +} + // RemoveDevice removes a device from the controller func (p *PndAdapter) RemoveDevice(ctx context.Context, did uuid.UUID) (*ppb.DeleteOndResponse, error) { resp, err := api.DeleteDevice(ctx, p.endpoint, p.id.String(), did.String()) diff --git a/cli/cmd/deviceList.go b/cli/cmd/deviceList.go index 9fc5247f3af6dff3d7df99c6021af666428aeaf3..d4ecad0441f06af0a7f15fb09cfe2a51f33c35be 100644 --- a/cli/cmd/deviceList.go +++ b/cli/cmd/deviceList.go @@ -47,7 +47,7 @@ var deviceListCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { spinner, _ := pterm.DefaultSpinner.Start("Fetching data from controller") - resp, err := pndAdapter.GetDevices(createContextWithAuthorization()) + resp, err := pndAdapter.GetFlattenedDevices(createContextWithAuthorization()) if err != nil { spinner.Fail(err) return err diff --git a/cli/cmd/prompt.go b/cli/cmd/prompt.go index 58246f531456468f0701cb1d1394891b63a4571f..7de142ae25eaca8154b097a1b6b4b040c7c1cfcb 100644 --- a/cli/cmd/prompt.go +++ b/cli/cmd/prompt.go @@ -240,7 +240,7 @@ func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []s // the result is converted into a prompt.Suggest slice. func getDevices() ([]prompt.Suggest, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching devices from controller.") - resp, err := pndAdapter.GetDevices(createContextWithAuthorization()) + resp, err := pndAdapter.GetFlattenedDevices(createContextWithAuthorization()) if err != nil { spinner.Fail(err) return []prompt.Suggest{}, err diff --git a/controller/api/device.go b/controller/api/device.go index 22f51cf7d71e4330fa9c4e061f19b74083dbdd44..7793186069db8814cd554502a46a529f11fca888 100644 --- a/controller/api/device.go +++ b/controller/api/device.go @@ -135,6 +135,22 @@ func GetDevices(ctx context.Context, addr, pid string) (*ppb.GetOndListResponse, return pndClient.GetOndList(ctx, req) } +// GetDevices requests all devices belonging to a given +// PrincipalNetworkDomain from the controller. +func GetFlattenedDevices(ctx context.Context, addr, pid string) (*ppb.GetFlattenedOndListResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + + req := &ppb.GetOndListRequest{ + Timestamp: time.Now().UnixNano(), + Pid: pid, + } + + return pndClient.GetFlattenedOndList(ctx, req) +} + // GetPath requests a specific path func GetPath(ctx context.Context, addr, pid, did, path string) (*ppb.GetPathResponse, error) { pndClient, err := nbi.PndClient(addr, dialOptions...) diff --git a/controller/controller.go b/controller/controller.go index a1a8333c6a01fc30d5709ca918d05114423cbe0b..d40ac00e67b896761d1e1b1653dd4e37ee51c82f 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -196,6 +196,7 @@ func ensureDefaultRoleExists() error { "/gosdn.rbac.RoleService/DeleteRoles", "/gosdn.pnd.PndService/GetOnd", "/gosdn.pnd.PndService/GetOndList", + "/gosdn.pnd.PndService/GetFlattenedOndList", "/gosdn.pnd.PndService/GetSbi", "/gosdn.pnd.PndService/GetSbiList", "/gosdn.pnd.PndService/GetPath", diff --git a/controller/northbound/server/pnd.go b/controller/northbound/server/pnd.go index 20133de7c4f2b1f85e454505b6c3825d251c2fbf..2876b063dc1d35294c9da704e88317ccb88dce0e 100644 --- a/controller/northbound/server/pnd.go +++ b/controller/northbound/server/pnd.go @@ -114,6 +114,47 @@ func (p PndServer) GetOndList(ctx context.Context, request *ppb.GetOndListReques }, nil } +// GetOndList returns a list of existing onds +func (p PndServer) GetFlattenedOndList(ctx context.Context, request *ppb.GetOndListRequest) (*ppb.GetFlattenedOndListResponse, error) { + labels := prometheus.Labels{"service": "pnd", "rpc": "get"} + start := metrics.StartHook(labels, grpcRequestsTotal) + defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) + pid, err := uuid.Parse(request.Pid) + if err != nil { + return nil, handleRPCError(labels, err) + } + + pnd, err := p.pndStore.Get(store.Query{ID: pid}) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + + onds := pnd.Devices() + ondsBySpecificPath := make([]*ppb.FlattenedOrchestratedNetworkingDevice, len(onds)) + for i, ond := range onds { + ondFlattened := &ppb.FlattenedOrchestratedNetworkingDevice{ + Id: ond.ID().String(), + Name: ond.Name(), + Sbi: &spb.SouthboundInterface{ + Id: ond.SBI().ID().String(), + Type: ond.SBI().Type(), + }, + } + ondsBySpecificPath[i] = ondFlattened + } + + return &ppb.GetFlattenedOndListResponse{ + Timestamp: time.Now().UnixNano(), + Pnd: &ppb.PrincipalNetworkDomain{ + Id: pnd.ID().String(), + Name: pnd.GetName(), + Description: pnd.GetDescription(), + }, + Ond: ondsBySpecificPath, + }, nil +} + func fillOndBySpecificPath(pnd networkdomain.NetworkDomain, d device.Device, path string) (*ppb.OrchestratedNetworkingDevice, error) { gnmiPath, err := ygot.StringToStructuredPath(path) if err != nil {