Newer
Older
ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd"
spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
"code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain"
"github.com/google/uuid"
"github.com/openconfig/ygot/ygot"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
ppb.UnimplementedPndServiceServer
func (p pndServer) GetOnd(ctx context.Context, request *ppb.GetOndRequest) (*ppb.GetOndResponse, 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 {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
onds, err := fillOnds(pnd, false, request.Did...)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
func (p pndServer) GetOndList(ctx context.Context, request *ppb.GetOndListRequest) (*ppb.GetOndListResponse, 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)
}
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
func fillOnds(pnd networkdomain.NetworkDomain, all bool, did ...string) ([]*ppb.OrchestratedNetworkingDevice, error) {
var ondList []uuid.UUID
var onds []*ppb.OrchestratedNetworkingDevice
// all indicates if a client wants all devices or only a single one
switch all {
case true:
ondList = pnd.Devices()
onds = make([]*ppb.OrchestratedNetworkingDevice, len(ondList))
for _, id := range ondList {
did = append(did, id.String())
}
default:
if len(did) == 0 {
err := &errors.ErrInvalidParameters{
Func: fillOnds,
Param: "length of 'did' cannot be '0' when 'all' is set to 'false'",
}
log.Error(err)
return nil, err
}
onds = make([]*ppb.OrchestratedNetworkingDevice, 1)
}
for i, id := range did {
d, err := pnd.GetDevice(id)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
cfg := ygot.GNMINotificationsConfig{}
dev, err := ygot.TogNMINotifications(d.Model(), time.Now().UnixNano(), cfg)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
onds[i] = &ppb.OrchestratedNetworkingDevice{
Id: id,
Name: d.Name(),
Device: dev,
}
func (p pndServer) GetSbi(ctx context.Context, request *ppb.GetSbiRequest) (*ppb.GetSbiResponse, 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)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
sbis, err := fillSbis(pnd, false, request.Sid...)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
func (p pndServer) GetSbiList(ctx context.Context, request *ppb.GetSbiListRequest) (*ppb.GetSbiListResponse, 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)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
func fillSbis(pnd networkdomain.NetworkDomain, all bool, sid ...string) ([]*spb.SouthboundInterface, error) {
switch all {
case true:
sbiList = sbiStore.UUIDs()
default:
var err error
if len(sid) == 0 {
return nil, &errors.ErrInvalidParameters{
Func: fillSbis,
Param: "length of 'sid' cannot be '0' when 'all' is set to 'false'",
}
}
sbiList, err = stringToUUID(sid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
}
sbis := make([]*spb.SouthboundInterface, len(sbiList))
for i, id := range sbiList {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
func stringToUUID(sid []string) ([]uuid.UUID, error) {
UUIDs := make([]uuid.UUID, len(sid))
for i, id := range sid {
parsed, err := uuid.Parse(id)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
UUIDs[i] = parsed
}
return UUIDs, nil
}
func (p pndServer) GetPath(ctx context.Context, request *ppb.GetPathRequest) (*ppb.GetPathResponse, 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 := pndc.GetPND(pid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
duid, err := uuid.Parse(request.Did)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
_, err = pnd.Request(duid, request.Path)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
ond, err := fillOnds(pnd, false, request.Did)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
return &ppb.GetPathResponse{
Timestamp: time.Now().UnixNano(),
Device: ond[0].Device,
}, nil
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
}
func (p pndServer) GetChange(ctx context.Context, request *ppb.GetChangeRequest) (*ppb.GetChangeResponse, 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 := pndc.GetPND(pid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
changes, err := fillChanges(pnd, false, request.Cuid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
return &ppb.GetChangeResponse{
Timestamp: time.Now().UnixNano(),
Change: changes,
}, nil
}
func (p pndServer) GetChangeList(ctx context.Context, request *ppb.GetChangeListRequest) (*ppb.GetChangeListResponse, 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 := pndc.GetPND(pid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
changes, err := fillChanges(pnd, true, "")
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
return &ppb.GetChangeListResponse{
Timestamp: time.Now().UnixNano(),
Change: changes,
}, nil
func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]*ppb.Change, error) {
var changeList []uuid.UUID
switch all {
case true:
changeList = pnd.PendingChanges()
changeList = append(changeList, pnd.CommittedChanges()...)
default:
var err error
if len(cuid) == 0 {
return nil, &errors.ErrInvalidParameters{
Func: fillOnds,
Param: "length of 'did' cannot be '0' when 'all' is set to 'false'",
}
}
changeList, err = stringToUUID(cuid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
}
changes := make([]*ppb.Change, len(changeList))
for i, ch := range changeList {
c, err := pnd.GetChange(ch)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
changes[i] = &ppb.Change{
Id: ch.String(),
Age: c.Age().Microseconds(),
State: c.State(),
func (p pndServer) SetOndList(ctx context.Context, request *ppb.SetOndListRequest) (*ppb.SetOndListResponse, error) {
labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
start := metrics.StartHook(labels, grpcRequestsTotal)
defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
pid, err := uuid.Parse(request.Pid)
if err != nil {
sid, err := uuid.Parse(r.Sbi.Id)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
if err := pnd.AddDevice(r.DeviceName, r.TransportOption, sid); err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
Status: ppb.Status_STATUS_OK,
Responses: []*ppb.SetResponse{
&ppb.SetResponse{
Status: ppb.Status_STATUS_OK,
},
},
func (p pndServer) SetChangeList(ctx context.Context, request *ppb.SetChangeListRequest) (*ppb.SetChangeListResponse, error) {
labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
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 := pndc.GetPND(pid)
if err != nil {
return nil, handleRPCError(labels, err)
}
for _, r := range request.Change {
cuid, err := uuid.Parse(r.Cuid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
default:
return nil, &errors.ErrInvalidParameters{
Param: r.Op,
}
}
}
Status: ppb.Status_STATUS_OK,
Responses: []*ppb.SetResponse{
&ppb.SetResponse{
Status: ppb.Status_STATUS_OK,
},
},
func (p pndServer) SetPathList(ctx context.Context, request *ppb.SetPathListRequest) (*ppb.SetPathListResponse, error) {
labels := prometheus.Labels{"service": "pnd", "rpc": "set"}
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 := pndc.GetPND(pid)
if err != nil {
return nil, handleRPCError(labels, err)
}
for _, r := range request.ChangeRequest {
did, err := uuid.Parse(r.Did)
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
// TODO: Return CUID in API
_, err = pnd.ChangeOND(did, r.ApiOp, r.Path, r.Value)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
Status: ppb.Status_STATUS_OK,
Responses: []*ppb.SetResponse{
&ppb.SetResponse{
Status: ppb.Status_STATUS_OK,
},
},
func (p pndServer) DeleteOnd(ctx context.Context, request *ppb.DeleteOndRequest) (*ppb.DeleteOndResponse, error) {
pid, err := uuid.Parse(request.Pid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
pnd, err := pndc.GetPND(pid)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
if err := pnd.RemoveDevice(did); err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}