Newer
Older
pb "code.fbi.h-da.de/danet/api/go/gosdn/core"
ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd"
spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport"
nbi "code.fbi.h-da.de/danet/gosdn/northbound/client"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"google.golang.org/grpc"
)
var dialOptions []grpc.DialOption
func init() {
dialOptions = []grpc.DialOption{
}
}
// Init initialises the CLI client.
func Init(addr string) error {
ctx := context.Background()
resp, err := getAllCore(ctx, addr)
if err != nil {
return err
}
if len(resp.Pnd) > 0 {
pid := resp.Pnd[0].Id
viper.Set("CLI_PND", pid)
log.Infof("PND: %v", pid)
// if len(resp.Pnd[0].Sbi) != 0 {
// sbi := resp.Pnd[0].Sbi[0].Id
// viper.Set("CLI_SBI", sbi)
// log.Infof("SBI: %v", sbi)
// }
}
// GetIds requests all UUID information from the controller
func GetIds(addr string) ([]*ppb.PrincipalNetworkDomain, error) {
ctx := context.Background()
resp, err := getAllCore(ctx, addr)
if err != nil {
return nil, err
}
return resp.Pnd, nil
}
func getAllCore(ctx context.Context, addr string) (*pb.GetPndListResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &pb.GetPndListRequest{
return coreClient.GetPndList(ctx, req)
}
// AddPnd takes a name, description and SBI UUID to create a new
// PrincipalNetworkDomain on the controller
func AddPnd(addr, name, description, sbi string) (*pb.CreatePndListResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
ctx := context.Background()
req := &pb.CreatePndListRequest{
Pnd: []*pb.PndCreateProperties{
{
Name: name,
Description: description,
Sbi: sbi,
},
},
}
return coreClient.CreatePndList(ctx, req)
// GetPnd requests one PrincipalNetworkDomain from the
// controller.
func GetPnd(addr string, args ...string) (*pb.GetPndResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
if len(args) <= 0 {
return nil, errors.New("not enough arguments")
}
ctx := context.Background()
req := &pb.GetPndRequest{
Timestamp: time.Now().UnixNano(),
Pid: args,
}
return coreClient.GetPnd(ctx, req)
}
// GetPnds requests all PrincipalNetworkDomains from the
// controller.
func GetPnds(addr string, args ...string) (*pb.GetPndListResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
if len(args) <= 0 {
return nil, errors.New("not enough arguments")
}
ctx := context.Background()
req := &pb.GetPndListRequest{
Timestamp: time.Now().UnixNano(),
}
return coreClient.GetPndList(ctx, req)
// getChanges requests all pending and unconfirmed changes from the controller
func getChanges(addr, pnd string) (*ppb.GetChangeListResponse, error) {
ctx := context.Background()
client, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.GetChangeListRequest{
return client.GetChangeList(ctx, req)
// commit sends a commit request for one or multiple changes to the
func commit(addr, pnd string, cuids ...string) (*ppb.SetChangeListResponse, error) {
changes := make([]*ppb.SetChange, len(cuids))
for i, arg := range cuids {
changes[i] = &ppb.SetChange{
Cuid: arg,
Op: ppb.Operation_OPERATION_COMMIT,
}
}
return commitConfirm(addr, pnd, changes)
}
// confirm sends a confirm request for one or multiple changes to the
func confirm(addr, pnd string, cuids ...string) (*ppb.SetChangeListResponse, error) {
changes := make([]*ppb.SetChange, len(cuids))
for i, arg := range cuids {
changes[i] = &ppb.SetChange{
Cuid: arg,
Op: ppb.Operation_OPERATION_CONFIRM,
}
}
return commitConfirm(addr, pnd, changes)
}
func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetChangeListResponse, error) {
ctx := context.Background()
client, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetChangeListRequest{
Timestamp: time.Now().UnixNano(),
Change: changes,
Pid: pnd,
}
return client.SetChangeList(ctx, req)
// addDevice adds a new device to the controller. The device name is optional.
// If no name is provided a name will be generated upon device creation.
func addDevice(addr, deviceName string, opt *tpb.TransportOption, sid, pid uuid.UUID) (*ppb.SetOndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetOndListRequest{
Timestamp: time.Now().UnixNano(),
Ond: []*ppb.SetOnd{
{
case spb.Type_TYPE_CONTAINERISED, spb.Type_TYPE_PLUGIN:
req.Ond[0].Sbi.Type = t
req.Ond[0].TransportOption.Type = t
default:
return pndClient.SetOndList(ctx, req)
// getDevice requests one device belonging to a given
// PrincipalNetworkDomain from the controller. If no device identifier
// is provided, an error is thrown.
func getDevice(addr, pid string, did ...string) (*ppb.GetOndResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
if len(did) == 0 {
req := &ppb.GetOndRequest{
return pndClient.GetOnd(ctx, req)
//nolint
// NOTE: currently not in use, but could be of value later
// getDevice requests all devices belonging to a given
// PrincipalNetworkDomain from the controller.
func getDevices(addr, pid string) (*ppb.GetOndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
req := &ppb.GetOndListRequest{
Pid: pid,
}
ctx := context.Background()
return pndClient.GetOndList(ctx, req)
}
func getPath(addr, pid, did, path string) (*ppb.GetPathResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.GetPathRequest{
Timestamp: time.Now().UnixNano(),
Did: did,
Pid: pid,
Path: path,
return pndClient.GetPath(ctx, req)
func deleteDevice(addr, pid, did string) (*ppb.DeleteOndResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
req := &ppb.DeleteOndRequest{
return pndClient.DeleteOnd(ctx, req)
// change creates a ChangeRequest for the specified OND. ApiOperations are
// used to specify the type of the change (update, replace, delete as specified
// in https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#34-modifying-state)
// For delete operations the value field needs to contain an empty string.
func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetPathListResponse, error) {
}
return sendChangeRequest(addr, pid, req)
}
func sendChangeRequest(addr, pid string, req *ppb.ChangeRequest) (*ppb.SetPathListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
ctx := context.Background()
r := &ppb.SetPathListRequest{
Timestamp: time.Now().UnixNano(),
ChangeRequest: []*ppb.ChangeRequest{req},
Pid: pid,
}
return pndClient.SetPathList(ctx, r)