diff --git a/cli/adapter/PndAdapter.go b/cli/adapter/PndAdapter.go index a02ac56ea36adfc4f457dd03484b76fbf1d8e8fa..a8dc29e8fd99f8bf7a6497b13582ea2c01fc4a1e 100644 --- a/cli/adapter/PndAdapter.go +++ b/cli/adapter/PndAdapter.go @@ -127,6 +127,14 @@ func (p *PndAdapter) Request(ctx context.Context, did uuid.UUID, path string) (* return resp, nil } +func (p *PndAdapter) SubscribeONDPath(ctx context.Context, did uuid.UUID, slist *ppb.SubscriptionList) (ppb.PndService_SubscribePathClient, error) { + resp, err := api.SubscribePath(ctx, p.endpoint, p.id.String(), did.String(), slist) + if err != nil { + return nil, err + } + return resp, nil +} + // RequestAll sends an API call to the controller requesting the specified path // for all registered devices. Not yet implemented. func (p *PndAdapter) RequestAll(ctx context.Context, path string) ([]proto.Message, error) { diff --git a/cli/cmd/deviceSubscribe.go b/cli/cmd/deviceSubscribe.go new file mode 100644 index 0000000000000000000000000000000000000000..63a3344f3ce7ce9ec8b2c9835306e735350f6712 --- /dev/null +++ b/cli/cmd/deviceSubscribe.go @@ -0,0 +1,103 @@ +/* +Copyright © 2021 da/net research group <danet.fbi.h-da.de> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +package cmd + +import ( + "io" + + "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" + "github.com/google/uuid" + "github.com/pterm/pterm" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +// deviceGetCmd represents the get command +var deviceSubscribeCmd = &cobra.Command{ + Use: "subscribe [uuid] [path]", + Args: cobra.ExactArgs(2), + Short: "do", + Long: `Requests a path from a specified orchestrated network device on the controller. +The device UUID and request path must be specified as a positional arguments.`, + + RunE: func(cmd *cobra.Command, args []string) error { + did, err := uuid.Parse(args[0]) + if err != nil { + pterm.Error.Println(err) + return err + } + + subClient, err := pndAdapter.SubscribeONDPath( + createContextWithAuthorization(), + did, + &pnd.SubscriptionList{ + Subscription: []*pnd.Subscription{ + { + Path: "system/config/hostname", + StreamMode: pnd.StreamMode_STREAM_MODE_TARGET_DEFINED, + SampleInterval: 1000000000, + }, + }, + Mode: pnd.SubscriptionMode_SUBSCRIPTION_MODE_ONCE, + }, + ) + if err != nil { + pterm.Error.Println(err) + return err + } + + for i := 0; i < 5; i++ { + subscribeResponse, err := subClient.Recv() + if err != nil { + if err != nil { + if err == io.EOF { + break + } + log.Error(err) + + closeErr := subClient.CloseSend() + if closeErr != nil { + log.Error(err) + } + } + } + + pterm.Println(subscribeResponse.String()) + } + + return nil + }, +} + +func init() { + deviceCmd.AddCommand(deviceSubscribeCmd) +} diff --git a/controller/api/device.go b/controller/api/device.go index 22f51cf7d71e4330fa9c4e061f19b74083dbdd44..d06e30c73a314e0ad963928d8e084fa49bf93684 100644 --- a/controller/api/device.go +++ b/controller/api/device.go @@ -152,6 +152,23 @@ func GetPath(ctx context.Context, addr, pid, did, path string) (*ppb.GetPathResp return pndClient.GetPath(ctx, req) } +func SubscribePath(ctx context.Context, addr, pid, did string, slist *ppb.SubscriptionList) (ppb.PndService_SubscribePathClient, error) { + log.Println("subscribePath called") + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + + req := &ppb.SubscribePathRequest{ + Timestamp: time.Now().UnixNano(), + Did: did, + Pid: pid, + Sublist: slist, + } + + return pndClient.SubscribePath(ctx, req) +} + // DeleteDevice deletes a device func DeleteDevice(ctx context.Context, addr, pid, did string) (*ppb.DeleteOndResponse, error) { pndClient, err := nbi.PndClient(addr, dialOptions...) diff --git a/controller/controller.go b/controller/controller.go index a1a8333c6a01fc30d5709ca918d05114423cbe0b..8f86f6ac6408f75f9ca41cfd8acaaaafe260a2e7 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -206,6 +206,7 @@ func ensureDefaultRoleExists() error { "/gosdn.pnd.PndService/SetPathList", "/gosdn.pnd.PndService/SetSbiList", "/gosdn.pnd.PndService/DeleteOnd", + "/gosdn.pnd.PndService/SubscribePath", "/gosdn.southbound.SbiService/GetSchema", })) if err != nil { diff --git a/controller/nucleus/principalNetworkDomain.go b/controller/nucleus/principalNetworkDomain.go index 92402279e93ba55b9357d370dd8268e2b2ba6700..fba9b0bb130c87d15c2fbb2d311bb27721df0bac 100644 --- a/controller/nucleus/principalNetworkDomain.go +++ b/controller/nucleus/principalNetworkDomain.go @@ -524,14 +524,15 @@ func (pnd *pndImplementation) SubscribePath(uuid uuid.UUID, subList *ppb.Subscri for _, sub := range subList.Subscription { opts := &gnmi.SubscribeOptions{ - Paths: [][]string{{sub.Path}}, - StreamMode: sub.GetStreamMode().String(), - SampleInterval: sub.SampleInterval, + Target: "172.100.0.12:6030", + Paths: [][]string{{"system", "config", "hostname"}}, } ctx := context.Background() ctx = context.WithValue(ctx, types.CtxKeyOpts, opts) + _ = sub + err := d.Transport().Subscribe(ctx) if err != nil { return err