From d3aeea569adcbdb09ca5edfbafce3d7a39dfff19 Mon Sep 17 00:00:00 2001 From: Malte Bauch <malte.bauch@tbnet.works> Date: Fri, 6 May 2022 12:19:00 +0000 Subject: [PATCH] Improve usability and better output formatting for gosndc See merge request danet/gosdn!284 Co-authored-by: Malte Bauch <malte.bauch@extern.h-da.de> --- .golangci.yml | 1 + api/go/gosdn/pnd/pnd.pb.go | 653 +++++++++--------- api/go/gosdn/pnd/pnd.pb.gw.go | 4 +- api/openapiv2/gosdn_northbound.swagger.json | 23 +- api/proto/buf.lock | 6 + api/proto/gosdn/pnd/pnd.proto | 27 +- cli/adapter/OndAdapter.go | 1 - cli/adapter/PndAdapter.go | 84 +-- cli/adapter/PndAdapter_test.go | 12 +- cli/cmd/changeCommit.go | 12 +- cli/cmd/changeConfirm.go | 13 +- cli/cmd/{init.go => changeGet.go} | 55 +- cli/cmd/changeList.go | 36 +- cli/cmd/deviceCreate.go | 12 +- cli/cmd/deviceDelete.go | 20 +- cli/cmd/deviceGet.go | 27 +- cli/cmd/deviceList.go | 26 +- cli/cmd/deviceRemove.go | 9 +- cli/cmd/deviceSet.go | 25 +- cli/cmd/deviceShow.go | 15 +- cli/cmd/login.go | 34 +- cli/cmd/pndCreate.go | 21 +- cli/cmd/pndGet.go | 12 +- cli/cmd/pndList.go | 17 +- cli/cmd/pndRemove.go | 13 +- cli/cmd/pndUse.go | 17 +- cli/cmd/prompt.go | 281 ++++++-- cli/cmd/root.go | 3 +- cli/cmd/utils.go | 48 +- controller/api/change.go | 25 +- controller/api/initialise_test.go | 19 +- controller/api/pnd.go | 3 - controller/interfaces/change/change.go | 2 + controller/interfaces/networkdomain/pnd.go | 2 +- controller/mocks/Change.go | 49 +- controller/mocks/Device.go | 33 +- controller/mocks/NetworkDomain.go | 32 +- controller/mocks/Plugin.go | 16 +- controller/mocks/SouthboundInterface.go | 13 +- controller/mocks/Storable.go | 13 +- controller/mocks/Transport.go | 13 +- controller/northbound/server/pnd.go | 26 +- controller/nucleus/change.go | 12 + controller/nucleus/principalNetworkDomain.go | 58 +- .../nucleus/principalNetworkDomain_test.go | 35 +- .../integration/nucleusIntegration_test.go | 3 +- go.mod | 13 +- go.sum | 42 +- 48 files changed, 1210 insertions(+), 706 deletions(-) delete mode 100644 cli/adapter/OndAdapter.go rename cli/cmd/{init.go => changeGet.go} (57%) diff --git a/.golangci.yml b/.golangci.yml index 894ea22bf..cccc94d98 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,6 +5,7 @@ run: issues-exit-code: 1 # directories to be ignored by linters skip-dirs: + - artifacts - controller/forks - controller/test - controller/mocks diff --git a/api/go/gosdn/pnd/pnd.pb.go b/api/go/gosdn/pnd/pnd.pb.go index 3738f74a0..9c8932f78 100644 --- a/api/go/gosdn/pnd/pnd.pb.go +++ b/api/go/gosdn/pnd/pnd.pb.go @@ -292,7 +292,7 @@ type GetOndListRequest struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` + Pid string `protobuf:"bytes,2,opt,name=pid,proto3" json:"pid,omitempty"` } func (x *GetOndListRequest) Reset() { @@ -347,8 +347,8 @@ type GetOndRequest struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Did []string `protobuf:"bytes,3,rep,name=did,proto3" json:"did,omitempty"` - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` + Did []string `protobuf:"bytes,2,rep,name=did,proto3" json:"did,omitempty"` + Pid string `protobuf:"bytes,3,opt,name=pid,proto3" json:"pid,omitempty"` } func (x *GetOndRequest) Reset() { @@ -410,7 +410,7 @@ type GetSbiListRequest struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` + Pid string `protobuf:"bytes,2,opt,name=pid,proto3" json:"pid,omitempty"` } func (x *GetSbiListRequest) Reset() { @@ -465,8 +465,8 @@ type GetSbiRequest struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Sid []string `protobuf:"bytes,3,rep,name=sid,proto3" json:"sid,omitempty"` - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` + Sid []string `protobuf:"bytes,2,rep,name=sid,proto3" json:"sid,omitempty"` + Pid string `protobuf:"bytes,3,opt,name=pid,proto3" json:"pid,omitempty"` } func (x *GetSbiRequest) Reset() { @@ -528,7 +528,7 @@ type GetChangeListRequest struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` + Pid string `protobuf:"bytes,2,opt,name=pid,proto3" json:"pid,omitempty"` } func (x *GetChangeListRequest) Reset() { @@ -582,9 +582,9 @@ type GetChangeRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Cuid string `protobuf:"bytes,3,opt,name=cuid,proto3" json:"cuid,omitempty"` - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. + Cuid []string `protobuf:"bytes,2,rep,name=cuid,proto3" json:"cuid,omitempty"` + Pid string `protobuf:"bytes,3,opt,name=pid,proto3" json:"pid,omitempty"` } func (x *GetChangeRequest) Reset() { @@ -626,11 +626,11 @@ func (x *GetChangeRequest) GetTimestamp() int64 { return 0 } -func (x *GetChangeRequest) GetCuid() string { +func (x *GetChangeRequest) GetCuid() []string { if x != nil { return x.Cuid } - return "" + return nil } func (x *GetChangeRequest) GetPid() string { @@ -1305,9 +1305,10 @@ type Change struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Age int64 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"` - State ChangeState `protobuf:"varint,3,opt,name=state,proto3,enum=gosdn.pnd.ChangeState" json:"state,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Age int64 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"` + State ChangeState `protobuf:"varint,3,opt,name=state,proto3,enum=gosdn.pnd.ChangeState" json:"state,omitempty"` + Diff *gnmi.Notification `protobuf:"bytes,4,opt,name=diff,proto3" json:"diff,omitempty"` } func (x *Change) Reset() { @@ -1363,6 +1364,13 @@ func (x *Change) GetState() ChangeState { return ChangeState_CHANGE_STATE_UNSPECIFIED } +func (x *Change) GetDiff() *gnmi.Notification { + if x != nil { + return x.Diff + } + return nil +} + type SetOndListRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1866,7 +1874,8 @@ type SetResponse struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Status Status `protobuf:"varint,2,opt,name=status,proto3,enum=gosdn.pnd.Status" json:"status,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Status Status `protobuf:"varint,3,opt,name=status,proto3,enum=gosdn.pnd.Status" json:"status,omitempty"` } func (x *SetResponse) Reset() { @@ -1908,6 +1917,13 @@ func (x *SetResponse) GetTimestamp() int64 { return 0 } +func (x *SetResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + func (x *SetResponse) GetStatus() Status { if x != nil { return x.Status @@ -2228,8 +2244,8 @@ type DeleteOndRequest struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Timestamp in nanoseconds since Epoch. - Pid string `protobuf:"bytes,4,opt,name=pid,proto3" json:"pid,omitempty"` - Did string `protobuf:"bytes,5,opt,name=did,proto3" json:"did,omitempty"` + Pid string `protobuf:"bytes,2,opt,name=pid,proto3" json:"pid,omitempty"` + Did string `protobuf:"bytes,3,opt,name=did,proto3" json:"did,omitempty"` } func (x *DeleteOndRequest) Reset() { @@ -2363,31 +2379,31 @@ var file_gosdn_pnd_pnd_proto_rawDesc = []byte{ 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x0d, 0x47, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, - 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x43, + 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, + 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x43, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x70, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x03, 0x73, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x03, 0x73, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x46, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, - 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x56, + 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x56, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x63, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x66, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, @@ -2480,85 +2496,79 @@ var file_gosdn_pnd_pnd_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x03, 0x73, 0x62, 0x69, 0x22, - 0x58, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, - 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x53, 0x65, 0x74, - 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, + 0x80, 0x01, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x67, 0x6f, + 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x69, + 0x66, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6e, 0x6d, 0x69, 0x2e, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x64, 0x69, + 0x66, 0x66, 0x22, 0x68, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x03, 0x6f, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, + 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, 0x03, 0x6f, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x68, 0x0a, 0x11, + 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x23, 0x0a, 0x03, 0x73, 0x62, 0x69, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, + 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x52, + 0x03, 0x73, 0x62, 0x69, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x03, - 0x6f, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, - 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, 0x03, 0x6f, 0x6e, - 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x70, 0x69, 0x64, 0x22, 0x68, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x03, 0x73, 0x62, 0x69, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, - 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x52, 0x03, 0x73, 0x62, 0x69, 0x12, 0x10, 0x0a, 0x03, 0x70, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x74, 0x0a, - 0x14, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, - 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x70, 0x69, 0x64, 0x22, 0x85, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3f, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x7b, 0x0a, 0x0d, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x70, 0x69, 0x5f, - 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, - 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x41, 0x70, 0x69, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x05, 0x61, 0x70, 0x69, 0x4f, 0x70, 0x22, 0xc9, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x74, - 0x4f, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, - 0x03, 0x73, 0x62, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x73, - 0x64, 0x6e, 0x2e, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x53, 0x6f, - 0x75, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x52, 0x03, 0x73, 0x62, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x37, 0x0a, 0x06, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x12, 0x2d, - 0x0a, 0x08, 0x73, 0x62, 0x69, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x62, 0x69, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x73, 0x62, 0x69, 0x54, 0x79, 0x70, 0x65, 0x22, 0x45, 0x0a, - 0x09, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x75, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x75, 0x69, 0x64, 0x12, 0x24, - 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x73, - 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x02, 0x6f, 0x70, 0x22, 0x56, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x93, 0x01, 0x0a, - 0x12, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x06, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x85, 0x01, 0x0a, + 0x12, 0x53, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x09, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x70, 0x12, 0x3f, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x73, 0x64, + 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x70, 0x69, 0x64, 0x22, 0x7b, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x70, 0x69, 0x5f, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x41, 0x70, + 0x69, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x61, 0x70, 0x69, 0x4f, + 0x70, 0x22, 0xc9, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x03, 0x73, 0x62, 0x69, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x73, 0x6f, 0x75, 0x74, + 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x03, 0x73, 0x62, 0x69, 0x12, + 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x4b, 0x0a, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x73, + 0x64, 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x37, 0x0a, + 0x06, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x12, 0x2d, 0x0a, 0x08, 0x73, 0x62, 0x69, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, + 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x62, 0x69, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x73, + 0x62, 0x69, 0x54, 0x79, 0x70, 0x65, 0x22, 0x45, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x63, 0x75, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x6f, 0x70, 0x22, 0x66, 0x0a, + 0x0b, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, + 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, @@ -2567,14 +2577,33 @@ var file_gosdn_pnd_pnd_proto_rawDesc = []byte{ 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x5c, 0x0a, 0x11, 0x53, - 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, - 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x12, 0x53, 0x65, - 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x15, + 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, + 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x73, 0x22, 0x5c, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, + 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, + 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, + 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, + 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, @@ -2583,162 +2612,153 @@ var file_gosdn_pnd_pnd_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, - 0x94, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, - 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, - 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x54, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0x5c, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, + 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0x5c, 0x0a, 0x11, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0x9c, 0x01, 0x0a, 0x0b, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x48, - 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x48, 0x41, 0x4e, - 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, - 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x1a, - 0x0a, 0x16, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, - 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x48, - 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4e, - 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x04, 0x2a, 0x7c, 0x0a, 0x0c, 0x41, 0x70, 0x69, - 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x50, 0x49, - 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x50, 0x49, 0x5f, - 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, - 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x50, 0x49, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, - 0x14, 0x41, 0x50, 0x49, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x2a, 0x6d, 0x0a, 0x07, 0x53, 0x62, 0x69, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, - 0x53, 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x43, 0x4f, 0x4e, - 0x46, 0x49, 0x47, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x49, 0x53, 0x45, 0x44, 0x10, - 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x4c, - 0x55, 0x47, 0x49, 0x4e, 0x10, 0x03, 0x2a, 0x69, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, - 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, - 0x54, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x50, - 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x10, - 0x03, 0x2a, 0x41, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, - 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x02, 0x32, 0xfc, 0x09, 0x0a, 0x0a, 0x50, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, - 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, - 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, - 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x5c, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4f, - 0x6e, 0x64, 0x12, 0x18, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, - 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, - 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, - 0x15, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, - 0x2f, 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x12, 0x66, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, - 0x2e, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, - 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x70, - 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x63, - 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x67, - 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x73, - 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x12, 0x12, 0x10, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x73, - 0x62, 0x69, 0x73, 0x12, 0x5d, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x12, 0x18, 0x2e, - 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, - 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x70, 0x6e, 0x64, - 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x62, 0x69, 0x73, 0x2f, 0x7b, 0x73, 0x69, - 0x64, 0x7d, 0x12, 0x66, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, - 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x62, - 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, - 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x62, 0x69, 0x73, 0x12, 0x6f, 0x0a, 0x0d, 0x47, 0x65, - 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, - 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, - 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, - 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x09, 0x47, - 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, - 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, - 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x70, 0x6e, - 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, - 0x2f, 0x7b, 0x63, 0x75, 0x69, 0x64, 0x7d, 0x12, 0x72, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, - 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x6f, 0x73, 0x64, - 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, - 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x6d, 0x0a, 0x07, 0x47, - 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, - 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, - 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, - 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x61, - 0x74, 0x68, 0x73, 0x2f, 0x7b, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x12, 0x6f, 0x0a, 0x0b, 0x53, 0x65, - 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, - 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, - 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, - 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, - 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x66, 0x0a, 0x09, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x64, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, - 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, - 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x70, 0x6e, - 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x64, - 0x69, 0x64, 0x7d, 0x42, 0xae, 0x02, 0x5a, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, - 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x67, - 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x6f, 0x73, 0x64, - 0x6e, 0x2f, 0x70, 0x6e, 0x64, 0x92, 0x41, 0xfb, 0x01, 0x12, 0xf8, 0x01, 0x0a, 0x10, 0x67, 0x6f, - 0x53, 0x44, 0x4e, 0x20, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x4d, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, - 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x47, 0x6f, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x67, 0x6f, 0x53, 0x44, 0x4e, 0x20, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x22, 0x3e, 0x0a, - 0x18, 0x67, 0x6f, 0x53, 0x44, 0x4e, 0x20, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, - 0x3a, 0x2f, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, - 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2a, 0x50, 0x0a, - 0x14, 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x4c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, - 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, - 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x2d, 0x2f, 0x62, 0x6c, 0x6f, 0x62, - 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, - 0x03, 0x30, 0x2e, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, + 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x2a, 0x9c, 0x01, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, + 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, + 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x4e, 0x47, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, + 0x44, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, + 0x10, 0x04, 0x2a, 0x7c, 0x0a, 0x0c, 0x41, 0x70, 0x69, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x50, 0x49, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x50, 0x49, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, + 0x50, 0x49, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x50, + 0x4c, 0x41, 0x43, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x50, 0x49, 0x5f, 0x4f, 0x50, + 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, + 0x2a, 0x6d, 0x0a, 0x07, 0x53, 0x62, 0x69, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x53, + 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01, 0x12, 0x1a, + 0x0a, 0x16, 0x53, 0x42, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, + 0x49, 0x4e, 0x45, 0x52, 0x49, 0x53, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x42, + 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x10, 0x03, 0x2a, + 0x69, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, + 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, + 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, + 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x10, 0x03, 0x2a, 0x41, 0x0a, 0x06, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x32, 0xfc, 0x09, + 0x0a, 0x0a, 0x50, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x0a, + 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x73, + 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, + 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, + 0x10, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, + 0x73, 0x12, 0x5c, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x12, 0x18, 0x2e, 0x67, 0x6f, + 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, + 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, + 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x2f, 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x12, + 0x66, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, + 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, + 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x4f, 0x6e, 0x64, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, + 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x63, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x62, + 0x69, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, + 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x70, 0x6e, 0x64, + 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x62, 0x69, 0x73, 0x12, 0x5d, 0x0a, 0x06, + 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x12, 0x18, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, + 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x62, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x19, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x62, 0x69, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, + 0x2f, 0x73, 0x62, 0x69, 0x73, 0x2f, 0x7b, 0x73, 0x69, 0x64, 0x7d, 0x12, 0x66, 0x0a, 0x0a, 0x53, + 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, + 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, + 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x62, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, + 0x2a, 0x22, 0x10, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x73, + 0x62, 0x69, 0x73, 0x12, 0x6f, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, + 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, + 0x13, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, + 0x7d, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x75, 0x69, 0x64, 0x7d, + 0x12, 0x72, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, + 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, + 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, + 0x13, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x12, 0x6d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x19, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x73, + 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, + 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, + 0x2f, 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x2f, 0x7b, 0x70, 0x61, + 0x74, 0x68, 0x7d, 0x12, 0x6f, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, + 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x53, 0x65, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x70, + 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x2f, 0x70, + 0x61, 0x74, 0x68, 0x73, 0x12, 0x66, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, + 0x64, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x70, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x4f, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x70, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x70, 0x69, 0x64, + 0x7d, 0x2f, 0x6f, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x42, 0xae, 0x02, 0x5a, + 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, + 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x70, 0x6e, 0x64, 0x92, 0x41, + 0xfb, 0x01, 0x12, 0xf8, 0x01, 0x0a, 0x10, 0x67, 0x6f, 0x53, 0x44, 0x4e, 0x20, 0x4e, 0x6f, 0x72, + 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x4d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x20, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x6f, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x6f, 0x53, 0x44, + 0x4e, 0x20, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x22, 0x3e, 0x0a, 0x18, 0x67, 0x6f, 0x53, 0x44, 0x4e, 0x20, + 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x6f, 0x64, 0x65, + 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, + 0x65, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2a, 0x50, 0x0a, 0x14, 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, + 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x38, + 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, + 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x2d, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x03, 0x30, 0x2e, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2816,55 +2836,56 @@ var file_gosdn_pnd_pnd_proto_depIdxs = []int32{ 39, // 14: gosdn.pnd.OrchestratedNetworkingDevice.device:type_name -> gnmi.Notification 38, // 15: gosdn.pnd.OrchestratedNetworkingDevice.sbi:type_name -> gosdn.southbound.SouthboundInterface 0, // 16: gosdn.pnd.Change.state:type_name -> gosdn.pnd.ChangeState - 27, // 17: gosdn.pnd.SetOndListRequest.ond:type_name -> gosdn.pnd.SetOnd - 28, // 18: gosdn.pnd.SetSbiListRequest.sbi:type_name -> gosdn.pnd.SetSbi - 29, // 19: gosdn.pnd.SetChangeListRequest.change:type_name -> gosdn.pnd.SetChange - 26, // 20: gosdn.pnd.SetPathListRequest.change_request:type_name -> gosdn.pnd.ChangeRequest - 1, // 21: gosdn.pnd.ChangeRequest.api_op:type_name -> gosdn.pnd.ApiOperation - 38, // 22: gosdn.pnd.SetOnd.sbi:type_name -> gosdn.southbound.SouthboundInterface - 40, // 23: gosdn.pnd.SetOnd.transport_option:type_name -> gosdn.transport.TransportOption - 2, // 24: gosdn.pnd.SetSbi.sbi_type:type_name -> gosdn.pnd.SbiType - 3, // 25: gosdn.pnd.SetChange.op:type_name -> gosdn.pnd.Operation - 4, // 26: gosdn.pnd.SetResponse.status:type_name -> gosdn.pnd.Status - 4, // 27: gosdn.pnd.SetOndListResponse.status:type_name -> gosdn.pnd.Status - 30, // 28: gosdn.pnd.SetOndListResponse.responses:type_name -> gosdn.pnd.SetResponse - 4, // 29: gosdn.pnd.SetChangeListResponse.status:type_name -> gosdn.pnd.Status - 30, // 30: gosdn.pnd.SetChangeListResponse.responses:type_name -> gosdn.pnd.SetResponse - 4, // 31: gosdn.pnd.SetChangeResponse.status:type_name -> gosdn.pnd.Status - 4, // 32: gosdn.pnd.SetSbiListResponse.status:type_name -> gosdn.pnd.Status - 30, // 33: gosdn.pnd.SetSbiListResponse.responses:type_name -> gosdn.pnd.SetResponse - 4, // 34: gosdn.pnd.SetPathListResponse.status:type_name -> gosdn.pnd.Status - 30, // 35: gosdn.pnd.SetPathListResponse.responses:type_name -> gosdn.pnd.SetResponse - 4, // 36: gosdn.pnd.DeleteOndResponse.status:type_name -> gosdn.pnd.Status - 5, // 37: gosdn.pnd.PndService.GetOndList:input_type -> gosdn.pnd.GetOndListRequest - 6, // 38: gosdn.pnd.PndService.GetOnd:input_type -> gosdn.pnd.GetOndRequest - 22, // 39: gosdn.pnd.PndService.SetOndList:input_type -> gosdn.pnd.SetOndListRequest - 7, // 40: gosdn.pnd.PndService.GetSbiList:input_type -> gosdn.pnd.GetSbiListRequest - 8, // 41: gosdn.pnd.PndService.GetSbi:input_type -> gosdn.pnd.GetSbiRequest - 23, // 42: gosdn.pnd.PndService.SetSbiList:input_type -> gosdn.pnd.SetSbiListRequest - 9, // 43: gosdn.pnd.PndService.GetChangeList:input_type -> gosdn.pnd.GetChangeListRequest - 10, // 44: gosdn.pnd.PndService.GetChange:input_type -> gosdn.pnd.GetChangeRequest - 24, // 45: gosdn.pnd.PndService.SetChangeList:input_type -> gosdn.pnd.SetChangeListRequest - 11, // 46: gosdn.pnd.PndService.GetPath:input_type -> gosdn.pnd.GetPathRequest - 25, // 47: gosdn.pnd.PndService.SetPathList:input_type -> gosdn.pnd.SetPathListRequest - 36, // 48: gosdn.pnd.PndService.DeleteOnd:input_type -> gosdn.pnd.DeleteOndRequest - 13, // 49: gosdn.pnd.PndService.GetOndList:output_type -> gosdn.pnd.GetOndListResponse - 12, // 50: gosdn.pnd.PndService.GetOnd:output_type -> gosdn.pnd.GetOndResponse - 31, // 51: gosdn.pnd.PndService.SetOndList:output_type -> gosdn.pnd.SetOndListResponse - 15, // 52: gosdn.pnd.PndService.GetSbiList:output_type -> gosdn.pnd.GetSbiListResponse - 14, // 53: gosdn.pnd.PndService.GetSbi:output_type -> gosdn.pnd.GetSbiResponse - 34, // 54: gosdn.pnd.PndService.SetSbiList:output_type -> gosdn.pnd.SetSbiListResponse - 18, // 55: gosdn.pnd.PndService.GetChangeList:output_type -> gosdn.pnd.GetChangeListResponse - 17, // 56: gosdn.pnd.PndService.GetChange:output_type -> gosdn.pnd.GetChangeResponse - 32, // 57: gosdn.pnd.PndService.SetChangeList:output_type -> gosdn.pnd.SetChangeListResponse - 16, // 58: gosdn.pnd.PndService.GetPath:output_type -> gosdn.pnd.GetPathResponse - 35, // 59: gosdn.pnd.PndService.SetPathList:output_type -> gosdn.pnd.SetPathListResponse - 37, // 60: gosdn.pnd.PndService.DeleteOnd:output_type -> gosdn.pnd.DeleteOndResponse - 49, // [49:61] is the sub-list for method output_type - 37, // [37:49] is the sub-list for method input_type - 37, // [37:37] is the sub-list for extension type_name - 37, // [37:37] is the sub-list for extension extendee - 0, // [0:37] is the sub-list for field type_name + 39, // 17: gosdn.pnd.Change.diff:type_name -> gnmi.Notification + 27, // 18: gosdn.pnd.SetOndListRequest.ond:type_name -> gosdn.pnd.SetOnd + 28, // 19: gosdn.pnd.SetSbiListRequest.sbi:type_name -> gosdn.pnd.SetSbi + 29, // 20: gosdn.pnd.SetChangeListRequest.change:type_name -> gosdn.pnd.SetChange + 26, // 21: gosdn.pnd.SetPathListRequest.change_request:type_name -> gosdn.pnd.ChangeRequest + 1, // 22: gosdn.pnd.ChangeRequest.api_op:type_name -> gosdn.pnd.ApiOperation + 38, // 23: gosdn.pnd.SetOnd.sbi:type_name -> gosdn.southbound.SouthboundInterface + 40, // 24: gosdn.pnd.SetOnd.transport_option:type_name -> gosdn.transport.TransportOption + 2, // 25: gosdn.pnd.SetSbi.sbi_type:type_name -> gosdn.pnd.SbiType + 3, // 26: gosdn.pnd.SetChange.op:type_name -> gosdn.pnd.Operation + 4, // 27: gosdn.pnd.SetResponse.status:type_name -> gosdn.pnd.Status + 4, // 28: gosdn.pnd.SetOndListResponse.status:type_name -> gosdn.pnd.Status + 30, // 29: gosdn.pnd.SetOndListResponse.responses:type_name -> gosdn.pnd.SetResponse + 4, // 30: gosdn.pnd.SetChangeListResponse.status:type_name -> gosdn.pnd.Status + 30, // 31: gosdn.pnd.SetChangeListResponse.responses:type_name -> gosdn.pnd.SetResponse + 4, // 32: gosdn.pnd.SetChangeResponse.status:type_name -> gosdn.pnd.Status + 4, // 33: gosdn.pnd.SetSbiListResponse.status:type_name -> gosdn.pnd.Status + 30, // 34: gosdn.pnd.SetSbiListResponse.responses:type_name -> gosdn.pnd.SetResponse + 4, // 35: gosdn.pnd.SetPathListResponse.status:type_name -> gosdn.pnd.Status + 30, // 36: gosdn.pnd.SetPathListResponse.responses:type_name -> gosdn.pnd.SetResponse + 4, // 37: gosdn.pnd.DeleteOndResponse.status:type_name -> gosdn.pnd.Status + 5, // 38: gosdn.pnd.PndService.GetOndList:input_type -> gosdn.pnd.GetOndListRequest + 6, // 39: gosdn.pnd.PndService.GetOnd:input_type -> gosdn.pnd.GetOndRequest + 22, // 40: gosdn.pnd.PndService.SetOndList:input_type -> gosdn.pnd.SetOndListRequest + 7, // 41: gosdn.pnd.PndService.GetSbiList:input_type -> gosdn.pnd.GetSbiListRequest + 8, // 42: gosdn.pnd.PndService.GetSbi:input_type -> gosdn.pnd.GetSbiRequest + 23, // 43: gosdn.pnd.PndService.SetSbiList:input_type -> gosdn.pnd.SetSbiListRequest + 9, // 44: gosdn.pnd.PndService.GetChangeList:input_type -> gosdn.pnd.GetChangeListRequest + 10, // 45: gosdn.pnd.PndService.GetChange:input_type -> gosdn.pnd.GetChangeRequest + 24, // 46: gosdn.pnd.PndService.SetChangeList:input_type -> gosdn.pnd.SetChangeListRequest + 11, // 47: gosdn.pnd.PndService.GetPath:input_type -> gosdn.pnd.GetPathRequest + 25, // 48: gosdn.pnd.PndService.SetPathList:input_type -> gosdn.pnd.SetPathListRequest + 36, // 49: gosdn.pnd.PndService.DeleteOnd:input_type -> gosdn.pnd.DeleteOndRequest + 13, // 50: gosdn.pnd.PndService.GetOndList:output_type -> gosdn.pnd.GetOndListResponse + 12, // 51: gosdn.pnd.PndService.GetOnd:output_type -> gosdn.pnd.GetOndResponse + 31, // 52: gosdn.pnd.PndService.SetOndList:output_type -> gosdn.pnd.SetOndListResponse + 15, // 53: gosdn.pnd.PndService.GetSbiList:output_type -> gosdn.pnd.GetSbiListResponse + 14, // 54: gosdn.pnd.PndService.GetSbi:output_type -> gosdn.pnd.GetSbiResponse + 34, // 55: gosdn.pnd.PndService.SetSbiList:output_type -> gosdn.pnd.SetSbiListResponse + 18, // 56: gosdn.pnd.PndService.GetChangeList:output_type -> gosdn.pnd.GetChangeListResponse + 17, // 57: gosdn.pnd.PndService.GetChange:output_type -> gosdn.pnd.GetChangeResponse + 32, // 58: gosdn.pnd.PndService.SetChangeList:output_type -> gosdn.pnd.SetChangeListResponse + 16, // 59: gosdn.pnd.PndService.GetPath:output_type -> gosdn.pnd.GetPathResponse + 35, // 60: gosdn.pnd.PndService.SetPathList:output_type -> gosdn.pnd.SetPathListResponse + 37, // 61: gosdn.pnd.PndService.DeleteOnd:output_type -> gosdn.pnd.DeleteOndResponse + 50, // [50:62] is the sub-list for method output_type + 38, // [38:50] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_gosdn_pnd_pnd_proto_init() } diff --git a/api/go/gosdn/pnd/pnd.pb.gw.go b/api/go/gosdn/pnd/pnd.pb.gw.go index 2b75200c8..61782289d 100644 --- a/api/go/gosdn/pnd/pnd.pb.gw.go +++ b/api/go/gosdn/pnd/pnd.pb.gw.go @@ -587,7 +587,7 @@ func request_PndService_GetChange_0(ctx context.Context, marshaler runtime.Marsh return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "cuid") } - protoReq.Cuid, err = runtime.String(val) + protoReq.Cuid, err = runtime.StringSlice(val, ",") if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "cuid", err) } @@ -630,7 +630,7 @@ func local_request_PndService_GetChange_0(ctx context.Context, marshaler runtime return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "cuid") } - protoReq.Cuid, err = runtime.String(val) + protoReq.Cuid, err = runtime.StringSlice(val, ",") if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "cuid", err) } diff --git a/api/openapiv2/gosdn_northbound.swagger.json b/api/openapiv2/gosdn_northbound.swagger.json index 4a016bc2c..17faac28f 100644 --- a/api/openapiv2/gosdn_northbound.swagger.json +++ b/api/openapiv2/gosdn_northbound.swagger.json @@ -18,13 +18,13 @@ "name": "PndService" }, { - "name": "Collector" + "name": "gNMI" }, { - "name": "gNMI" + "name": "AuthService" }, { - "name": "AgentManager" + "name": "UserService" }, { "name": "SbiService" @@ -36,13 +36,13 @@ "name": "CsbiService" }, { - "name": "AuthService" + "name": "AgentManager" }, { "name": "RoleService" }, { - "name": "UserService" + "name": "Collector" } ], "consumes": [ @@ -383,7 +383,12 @@ "name": "cuid", "in": "path", "required": true, - "type": "string" + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "minItems": 1 }, { "name": "timestamp", @@ -2479,6 +2484,9 @@ "type": "string", "format": "int64" }, + "id": { + "type": "string" + }, "status": { "$ref": "#/definitions/gosdnpndStatus" } @@ -2564,6 +2572,9 @@ }, "state": { "$ref": "#/definitions/pndChangeState" + }, + "diff": { + "$ref": "#/definitions/gnmiNotification" } } }, diff --git a/api/proto/buf.lock b/api/proto/buf.lock index 60d8de11d..ffdb2e279 100644 --- a/api/proto/buf.lock +++ b/api/proto/buf.lock @@ -4,8 +4,14 @@ deps: - remote: buf.build owner: googleapis repository: googleapis + branch: main commit: f3590c56d388417ebbedefae77ac12bf + digest: b1-nbZ1ZLsYdwXyEysqVWKYATvTXYr_alNRBebrjXpIv6k= + create_time: 2022-04-23T15:03:48.462865Z - remote: buf.build owner: grpc-ecosystem repository: grpc-gateway + branch: main commit: febd9e8be39b4f4b878b9c64bcc203fd + digest: b1-K5jSHBrJ24jZXRgQgkmphZuP-cAL2b90ssKrgvDK2hU= + create_time: 2022-04-17T01:28:07.574665Z diff --git a/api/proto/gosdn/pnd/pnd.proto b/api/proto/gosdn/pnd/pnd.proto index 11bed8ef5..927c0cd89 100644 --- a/api/proto/gosdn/pnd/pnd.proto +++ b/api/proto/gosdn/pnd/pnd.proto @@ -118,34 +118,34 @@ service PndService { message GetOndListRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - string pid = 4; + string pid = 2; } message GetOndRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - repeated string did = 3; - string pid = 4; + repeated string did = 2; + string pid = 3; } message GetSbiListRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - string pid = 4; + string pid = 2; } message GetSbiRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - repeated string sid = 3; - string pid = 4; + repeated string sid = 2; + string pid = 3; } message GetChangeListRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - string pid = 4; + string pid = 2; } message GetChangeRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - string cuid = 3; - string pid = 4; + repeated string cuid = 2; + string pid = 3; } message GetPathRequest { @@ -235,8 +235,8 @@ enum ChangeState { message Change { string id = 1; int64 age = 2; - ChangeState state = 3; + gnmi.Notification diff = 4; } message SetOndListRequest { @@ -310,7 +310,8 @@ message SetChange { message SetResponse{ int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - Status status = 2; + string id = 2; + Status status = 3; } message SetOndListResponse{ @@ -344,8 +345,8 @@ message SetPathListResponse{ message DeleteOndRequest { int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - string pid = 4; - string did = 5; + string pid = 2; + string did = 3; } message DeleteOndResponse { diff --git a/cli/adapter/OndAdapter.go b/cli/adapter/OndAdapter.go deleted file mode 100644 index b8e8da308..000000000 --- a/cli/adapter/OndAdapter.go +++ /dev/null @@ -1 +0,0 @@ -package adapter diff --git a/cli/adapter/PndAdapter.go b/cli/adapter/PndAdapter.go index a03b5480b..53339e847 100644 --- a/cli/adapter/PndAdapter.go +++ b/cli/adapter/PndAdapter.go @@ -5,15 +5,12 @@ import ( "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/core" ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" - spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound" tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport" "code.fbi.h-da.de/danet/gosdn/controller/api" - "code.fbi.h-da.de/danet/gosdn/controller/interfaces/change" "code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound" "code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors" "github.com/google/uuid" "github.com/openconfig/goyang/pkg/yang" - log "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/proto" ) @@ -69,22 +66,22 @@ func (p *PndAdapter) GetSbiSchemaTree(ctx context.Context, sid uuid.UUID) (map[s // GetDevice requests one or multiple devices belonging to a given // PrincipalNetworkDomain from the controller. -func (p *PndAdapter) GetDevice(ctx context.Context, identifier ...string) ([]*ppb.OrchestratedNetworkingDevice, error) { +func (p *PndAdapter) GetDevice(ctx context.Context, identifier ...string) (*ppb.GetOndResponse, error) { resp, err := api.GetDevice(ctx, p.endpoint, p.id.String(), identifier...) if err != nil { return nil, err } - return resp.Ond, nil + return resp, nil } // GetDevices requests all devices belonging to the PrincipalNetworkDomain // attached to this adapter. -func (p *PndAdapter) GetDevices(ctx context.Context) ([]*ppb.OrchestratedNetworkingDevice, error) { +func (p *PndAdapter) GetDevices(ctx context.Context) (*ppb.GetOndListResponse, error) { resp, err := api.GetDevices(ctx, p.endpoint, p.id.String()) if err != nil { return nil, err } - return resp.Ond, nil + return resp, nil } // RemoveDevice removes a device from the controller @@ -108,22 +105,21 @@ func (p *PndAdapter) RemovePnd(ctx context.Context, pid uuid.UUID) (*core.Delete // ChangeOND sends an API call to the controller requesting the creation of // a change from the provided Operation, path and value. The Change is marked // as Pending and times out after the specified timeout period -func (p *PndAdapter) ChangeOND(ctx context.Context, duid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) (uuid.UUID, error) { +func (p *PndAdapter) ChangeOND(ctx context.Context, duid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) (*ppb.SetPathListResponse, error) { var v string if len(value) != 0 { v = value[0] } resp, err := api.ChangeRequest(ctx, p.endpoint, duid.String(), p.id.String(), path, v, operation) if err != nil { - return uuid.Nil, err + return nil, err } - log.Info(resp) - return uuid.Nil, err + return resp, err } // Request sends an API call to the controller requesting the specified path // for the specified device -func (p *PndAdapter) Request(ctx context.Context, did uuid.UUID, path string) (proto.Message, error) { +func (p *PndAdapter) Request(ctx context.Context, did uuid.UUID, path string) (*ppb.GetPathResponse, error) { resp, err := api.GetPath(ctx, p.endpoint, p.id.String(), did.String(), path) if err != nil { return nil, err @@ -169,22 +165,22 @@ func (p *PndAdapter) ContainsDevice(uuid.UUID) bool { // GetSbi sends an API call to the controller requesting the // registered SBI with the provided ID. -func (p *PndAdapter) GetSbi(ctx context.Context, sid ...string) ([]*spb.SouthboundInterface, error) { +func (p *PndAdapter) GetSbi(ctx context.Context, sid ...string) (*ppb.GetSbiResponse, error) { resp, err := api.GetSbi(ctx, p.endpoint, p.id.String(), sid...) if err != nil { return nil, err } - return resp.Sbi, nil + return resp, nil } // GetSBIs sends an API call to the controller requesting the // registered SBIs. Not implemented, always returns nil -func (p *PndAdapter) GetSBIs(ctx context.Context) ([]*spb.SouthboundInterface, error) { +func (p *PndAdapter) GetSBIs(ctx context.Context) (*ppb.GetSbiListResponse, error) { resp, err := api.GetSBIs(ctx, p.endpoint, p.id.String()) if err != nil { return nil, err } - return resp.Sbi, nil + return resp, nil } // ID returns the PND Adapter's UUID @@ -199,57 +195,67 @@ func (p *PndAdapter) Endpoint() string { // PendingChanges sends an API call to the controller requesting // the UUIDs of all pending changes -func (p *PndAdapter) PendingChanges(ctx context.Context) []uuid.UUID { +func (p *PndAdapter) PendingChanges(ctx context.Context) ([]*ppb.Change, error) { resp, err := api.GetChanges(ctx, p.endpoint, p.id.String()) if err != nil { - log.Error(err) - return nil + return nil, err } - return filterChanges(ppb.ChangeState_CHANGE_STATE_PENDING, resp) + return filterChanges(ppb.ChangeState_CHANGE_STATE_PENDING, resp), nil } // CommittedChanges sends an API call to the controller requesting // the UUIDs of all committed changes -func (p *PndAdapter) CommittedChanges(ctx context.Context) []uuid.UUID { +func (p *PndAdapter) CommittedChanges(ctx context.Context) ([]*ppb.Change, error) { resp, err := api.GetChanges(ctx, p.endpoint, p.id.String()) if err != nil { - log.Error(err) - return nil + return nil, err } - return filterChanges(ppb.ChangeState_CHANGE_STATE_COMMITTED, resp) + return filterChanges(ppb.ChangeState_CHANGE_STATE_COMMITTED, resp), nil } -// GetChange sends an API call to the controller requesting the specified change -func (p *PndAdapter) GetChange(uuid.UUID) (change.Change, error) { - return nil, &errors.ErrNotYetImplemented{} +// ConfirmedChanges sends an API call to the controller requesting +// the UUIDs of all confirmed changes +func (p *PndAdapter) ConfirmedChanges(ctx context.Context) ([]*ppb.Change, error) { + resp, err := api.GetChanges(ctx, p.endpoint, p.id.String()) + if err != nil { + return nil, err + } + return filterChanges(ppb.ChangeState_CHANGE_STATE_CONFIRMED, resp), nil +} + +// GetChange sends an API call to the controller requesting one or more changes +// for the specific PND +func (p *PndAdapter) GetChange(ctx context.Context, identifier ...string) (*ppb.GetChangeResponse, error) { + resp, err := api.GetChange(ctx, p.endpoint, p.id.String(), identifier...) + if err != nil { + return nil, err + } + return resp, nil } // Commit sends an API call to the controller committing the specified change -func (p *PndAdapter) Commit(ctx context.Context, cuid uuid.UUID) error { +func (p *PndAdapter) Commit(ctx context.Context, cuid uuid.UUID) (*ppb.SetChangeListResponse, error) { resp, err := api.Commit(ctx, p.endpoint, p.id.String(), cuid.String()) if err != nil { - return err + return nil, err } - log.Info(resp) - return nil + return resp, nil } // Confirm sends an API call to the controller confirming the specified change -func (p *PndAdapter) Confirm(ctx context.Context, cuid uuid.UUID) error { +func (p *PndAdapter) Confirm(ctx context.Context, cuid uuid.UUID) (*ppb.SetChangeListResponse, error) { resp, err := api.Confirm(ctx, p.endpoint, p.id.String(), cuid.String()) if err != nil { - return err + return nil, err } - log.Info(resp) - return nil + return resp, nil } -func filterChanges(state ppb.ChangeState, resp *ppb.GetChangeListResponse) []uuid.UUID { - changes := make([]uuid.UUID, 0) +func filterChanges(state ppb.ChangeState, resp *ppb.GetChangeListResponse) []*ppb.Change { + changes := make([]*ppb.Change, 0) for _, ch := range resp.Change { if ch.State == state { - id, _ := uuid.Parse(ch.Id) - changes = append(changes, id) + changes = append(changes, ch) } } return changes diff --git a/cli/adapter/PndAdapter_test.go b/cli/adapter/PndAdapter_test.go index 2f5b1612a..2c49e7804 100644 --- a/cli/adapter/PndAdapter_test.go +++ b/cli/adapter/PndAdapter_test.go @@ -385,7 +385,7 @@ func TestPndAdapter_PendingChanges(t *testing.T) { id: tt.fields.id, endpoint: tt.fields.endpoint, } - if got := p.PendingChanges(context.TODO()); !reflect.DeepEqual(got, tt.want) { + if got, _ := p.PendingChanges(context.TODO()); !reflect.DeepEqual(got, tt.want) { t.Errorf("PndAdapter.PendingChanges() = %v, want %v", got, tt.want) } }) @@ -410,7 +410,7 @@ func TestPndAdapter_CommittedChanges(t *testing.T) { id: tt.fields.id, endpoint: tt.fields.endpoint, } - if got := p.CommittedChanges(context.TODO()); !reflect.DeepEqual(got, tt.want) { + if got, _ := p.CommittedChanges(context.TODO()); !reflect.DeepEqual(got, tt.want) { t.Errorf("PndAdapter.CommittedChanges() = %v, want %v", got, tt.want) } }) @@ -423,7 +423,7 @@ func TestPndAdapter_GetChange(t *testing.T) { endpoint string } type args struct { - in uuid.UUID + in []string } tests := []struct { name string @@ -440,7 +440,7 @@ func TestPndAdapter_GetChange(t *testing.T) { id: tt.fields.id, endpoint: tt.fields.endpoint, } - got, err := p.GetChange(tt.args.in) + got, err := p.GetChange(context.TODO(), tt.args.in...) if (err != nil) != tt.wantErr { t.Errorf("PndAdapter.GetChange() error = %v, wantErr %v", err, tt.wantErr) return @@ -474,7 +474,7 @@ func TestPndAdapter_Commit(t *testing.T) { id: tt.fields.id, endpoint: tt.fields.endpoint, } - if err := p.Commit(context.TODO(), tt.args.cuid); (err != nil) != tt.wantErr { + if _, err := p.Commit(context.TODO(), tt.args.cuid); (err != nil) != tt.wantErr { t.Errorf("PndAdapter.Commit() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -503,7 +503,7 @@ func TestPndAdapter_Confirm(t *testing.T) { id: tt.fields.id, endpoint: tt.fields.endpoint, } - if err := p.Confirm(context.TODO(), tt.args.cuid); (err != nil) != tt.wantErr { + if _, err := p.Confirm(context.TODO(), tt.args.cuid); (err != nil) != tt.wantErr { t.Errorf("PndAdapter.Confirm() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/cli/cmd/changeCommit.go b/cli/cmd/changeCommit.go index 8bdc0ea41..0994ee2f6 100644 --- a/cli/cmd/changeCommit.go +++ b/cli/cmd/changeCommit.go @@ -33,7 +33,7 @@ package cmd import ( "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -48,10 +48,14 @@ Change UUID must be specified as positional argument.`, Run: func(cmd *cobra.Command, args []string) { cuid, err := uuid.Parse(args[0]) if err != nil { - log.Fatal(err) + pterm.Error.Println(err) } - if err := pndAdapter.Commit(createContextWithAuthorization(), cuid); err != nil { - log.Fatal(err) + resp, err := pndAdapter.Commit(createContextWithAuthorization(), cuid) + if err != nil { + pterm.Error.Println(err) + } + for _, r := range resp.GetResponses() { + pterm.Info.Println(r.String()) } }, } diff --git a/cli/cmd/changeConfirm.go b/cli/cmd/changeConfirm.go index 4fa511580..20a49e536 100644 --- a/cli/cmd/changeConfirm.go +++ b/cli/cmd/changeConfirm.go @@ -33,7 +33,7 @@ package cmd import ( "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -48,10 +48,15 @@ Change UUID must be specified as positional argument`, Run: func(cmd *cobra.Command, args []string) { cuid, err := uuid.Parse(args[0]) if err != nil { - log.Fatal(err) + pterm.Error.Println(err) } - if err := pndAdapter.Confirm(createContextWithAuthorization(), cuid); err != nil { - log.Fatal(err) + + resp, err := pndAdapter.Confirm(createContextWithAuthorization(), cuid) + if err != nil { + pterm.Error.Println(err) + } + for _, r := range resp.GetResponses() { + pterm.Info.Println(r.String()) } }, } diff --git a/cli/cmd/init.go b/cli/cmd/changeGet.go similarity index 57% rename from cli/cmd/init.go rename to cli/cmd/changeGet.go index f2d809e87..6495b1e3f 100644 --- a/cli/cmd/init.go +++ b/cli/cmd/changeGet.go @@ -32,44 +32,41 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - "fmt" - "os" - - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" - "github.com/spf13/viper" + "google.golang.org/protobuf/encoding/protojson" ) -var controllerAPIEndpoint string +// confirmCmd represents the confirm command +var getCmd = &cobra.Command{ + Use: "get [uuid]", + Args: cobra.ExactArgs(1), + Short: "returns information about the requested change", + Long: `Returns detailed information about a specific change. The + changes UUID has to be specified via a positional argument.`, -// initCmd represents the init command -var initCmd = &cobra.Command{ - Use: "init", - Short: "initialise controller", - Long: `Initialise PND and SBI and saves values to config file on controller. -The --controller flag is required to change the controller address`, + Run: func(cmd *cobra.Command, args []string) { + changes, err := pndAdapter.GetChange(createContextWithAuthorization(), args[0]) + if err != nil { + pterm.Error.Println(err) + } + for _, c := range changes.GetChange() { + title := pterm.Sprintf("Change with ID: %s", c.GetId()) + panel1 := pterm.DefaultBox.WithTitle("Age:").Sprint(c.GetAge()) + panel2 := pterm.DefaultBox.WithTitle("State:").Sprint(c.GetState()) + panel3 := pterm.DefaultBox.WithTitle("Diff:").Sprint(protojson.Format(c.GetDiff())) - RunE: func(cmd *cobra.Command, args []string) error { - log.Infof("New controller address: %v", viper.GetString("controllerAPIEndpoint")) + panels, _ := pterm.DefaultPanel.WithPanels(pterm.Panels{ + {{Data: panel1}}, + {{Data: panel2}}, + {{Data: panel3}}, + }).Srender() - if err := viper.WriteConfig(); err != nil { - fmt.Fprintln(os.Stderr, "Could not write config:", err) + pterm.DefaultBox.WithTitle(title).WithTitleTopCenter().WithRightPadding(0).WithBottomPadding(0).Println(panels) } - return nil }, } func init() { - rootCmd.AddCommand(initCmd) - - initCmd.Flags().StringVar(&controllerAPIEndpoint, "controller", "gosdn-develop.apps.ocp.fbi.h-da.de:55055", "address of the controller") - err := viper.BindPFlag("controllerAPIEndpoint", initCmd.Flags().Lookup("controller")) - if err != nil { - fmt.Fprintln(os.Stderr, "Could not bind controllerAPIEndpoint:", err) - } - - // Set controller flag as required (possibly not?) - //if err := initCmd.MarkFlagRequired("controller"); err != nil { - // fmt.Fprintln(os.Stderr, "Could not mark controller flag as required:", err) - //} + changeCmd.AddCommand(getCmd) } diff --git a/cli/cmd/changeList.go b/cli/cmd/changeList.go index dcd3dc4f4..af5224133 100644 --- a/cli/cmd/changeList.go +++ b/cli/cmd/changeList.go @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -43,17 +43,33 @@ var changeListCmd = &cobra.Command{ Short: "list all changes", Long: `Lists all configuration changes with their UUIDs.`, - Run: func(cmd *cobra.Command, args []string) { - committed := pndAdapter.CommittedChanges(createContextWithAuthorization()) - log.Info("committed changes:") - for i, ch := range committed { - log.Infof(" Change %v: %v", i+1, ch.String()) + RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Process change list request") + committed, err := pndAdapter.CommittedChanges(createContextWithAuthorization()) + if err != nil { + spinner.Fail(err) + return err } - pending := pndAdapter.PendingChanges(createContextWithAuthorization()) - log.Info("pending changes:") - for i, ch := range pending { - log.Infof(" Change %v: %v", i+1, ch.String()) + pending, err := pndAdapter.PendingChanges(createContextWithAuthorization()) + if err != nil { + spinner.Fail(err) + return err } + + // TODO: maybe we want to return more information about changes? E.g., + // the diff of the change (probably only for a single get of a change). + // This would require us to change pndAdapter methods. + data := pterm.TableData{[]string{"UUID", "Status"}} + for _, ch := range pending { + data = append(data, []string{ch.String(), "pending"}) + } + for _, ch := range committed { + data = append(data, []string{ch.String(), "commited"}) + } + + spinner.Success() + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + return nil }, } diff --git a/cli/cmd/deviceCreate.go b/cli/cmd/deviceCreate.go index 56781bf23..efd182a0d 100644 --- a/cli/cmd/deviceCreate.go +++ b/cli/cmd/deviceCreate.go @@ -33,9 +33,8 @@ package cmd import ( "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" - "google.golang.org/protobuf/encoding/protojson" spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound" tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport" @@ -50,8 +49,10 @@ Device address must be provided with IP and port,e.g., 192.168.1.1:6030. User cr if they diverge from the default credentials (user:'admin' and pw:'arista').`, RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Creating new device") err := checkIPPort(address) if err != nil { + spinner.Fail(err) return err } @@ -73,16 +74,19 @@ if they diverge from the default credentials (user:'admin' and pw:'arista').`, } sid, err := uuid.Parse(cliSbi) if err != nil { + spinner.Fail(err) return err } resp, err := pndAdapter.AddDevice(createContextWithAuthorization(), deviceName, opt, sid) if err != nil { + spinner.Fail(err) return err } - log.Info(protojson.Format(resp)) - + for _, r := range resp.GetResponses() { + spinner.Success("Device has been created with ID: ", r.GetId()) + } return nil }, } diff --git a/cli/cmd/deviceDelete.go b/cli/cmd/deviceDelete.go index 82769ea90..c354ccc2c 100644 --- a/cli/cmd/deviceDelete.go +++ b/cli/cmd/deviceDelete.go @@ -34,7 +34,7 @@ package cmd import ( ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -46,17 +46,27 @@ var deviceDeleteCmd = &cobra.Command{ Long: `Delete a path for a given orchestrated network device. The device UUID and request path must be specified as a positional arguments.`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Create a path deletion request.") did, err := uuid.Parse(args[0]) if err != nil { - log.Fatal(err) + spinner.Fail(err) + return err } - log.Info(pndAdapter.ChangeOND( + resp, err := pndAdapter.ChangeOND( createContextWithAuthorization(), did, ppb.ApiOperation_API_OPERATION_DELETE, args[1], - )) + ) + for _, r := range resp.Responses { + if r.Status == ppb.Status_STATUS_OK { + spinner.Success("A change for path deletion for Device: ", did.String(), "has been created -> Change ID: ", r.GetId()) + } else { + spinner.Fail("An error occured while creating a path deletion request for Device with ID: ", r.GetId(), r.GetStatus()) + } + } + return nil }, } diff --git a/cli/cmd/deviceGet.go b/cli/cmd/deviceGet.go index 0bbaaff0b..271eeca4a 100644 --- a/cli/cmd/deviceGet.go +++ b/cli/cmd/deviceGet.go @@ -33,7 +33,7 @@ package cmd import ( "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" "google.golang.org/protobuf/encoding/protojson" ) @@ -46,22 +46,37 @@ var deviceGetCmd = &cobra.Command{ 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.`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { did, err := uuid.Parse(args[0]) if err != nil { - log.Fatal(err) + pterm.Error.Println(err) + return err } - message, err := pndAdapter.Request( + res, err := pndAdapter.Request( createContextWithAuthorization(), did, args[1], ) if err != nil { - log.Error(err) + pterm.Error.Println(err) + return err } - log.Info(protojson.Format(message)) + for _, n := range res.Device { + panel1 := pterm.DefaultBox.WithTitle("Timestamp:").Sprint(n.GetTimestamp()) + panel2 := pterm.DefaultBox.WithTitle("Requested Path:").Sprint(args[1]) + panel3 := pterm.DefaultBox.WithTitle("Update:").Sprint(protojson.Format(n.Update[0])) + + panels, _ := pterm.DefaultPanel.WithPanels(pterm.Panels{ + {{Data: panel1}}, + {{Data: panel2}}, + {{Data: panel3}}, + }).Srender() + + pterm.DefaultBox.WithRightPadding(0).WithBottomPadding(0).Println(panels) + } + return nil }, } diff --git a/cli/cmd/deviceList.go b/cli/cmd/deviceList.go index 3e0d7408f..c74939942 100644 --- a/cli/cmd/deviceList.go +++ b/cli/cmd/deviceList.go @@ -32,8 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -46,23 +45,22 @@ var deviceListCmd = &cobra.Command{ Long: "List all orchestrated network devices within the current PND.", RunE: func(cmd *cobra.Command, args []string) error { - respONDs, err := pndAdapter.GetDevices(createContextWithAuthorization()) + spinner, _ := pterm.DefaultSpinner.Start("Fetching data from controller") + + resp, err := pndAdapter.GetDevices(createContextWithAuthorization()) if err != nil { + spinner.Fail(err) return err } - for i, dev := range respONDs { - log.Infof("OND %v: name: %v, uuid: %v", i+1, dev.Name, dev.Id) - sid, err := uuid.Parse(dev.GetSbi().GetId()) - if err != nil { - return err - } - tree, err := pndAdapter.GetSbiSchemaTree(createContextWithAuthorization(), sid) - if err != nil { - return err - } - log.Infof(" SchemaTree: %v", tree) + data := pterm.TableData{[]string{"UUID", "Name", "SBI-UUID", "SBI-Type"}} + for _, dev := range resp.GetOnd() { + data = append(data, []string{dev.GetId(), dev.GetName(), dev.GetSbi().GetId(), dev.GetSbi().GetType().String()}) } + + spinner.Success() + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() return nil }, } diff --git a/cli/cmd/deviceRemove.go b/cli/cmd/deviceRemove.go index 37170c2de..6cbdf8125 100644 --- a/cli/cmd/deviceRemove.go +++ b/cli/cmd/deviceRemove.go @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/google/uuid" "github.com/spf13/cobra" @@ -48,15 +48,18 @@ var deviceRemoveCmd = &cobra.Command{ The device UUID must be specified as a positional argument.`, RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Removing device with ID: ", args[0]) did, err := uuid.Parse(args[0]) if err != nil { + spinner.Fail(err) return err } - resp, err := pndAdapter.RemoveDevice(createContextWithAuthorization(), did) + _, err = pndAdapter.RemoveDevice(createContextWithAuthorization(), did) if err != nil { + spinner.Fail(err) return err } - log.Infof("Deletion of OND with ID %v: %s", did, resp.GetStatus().String()) + spinner.Success("PND has been deleted, ID: ", did.String()) return nil }, } diff --git a/cli/cmd/deviceSet.go b/cli/cmd/deviceSet.go index a8088d34a..8cd63cb2a 100644 --- a/cli/cmd/deviceSet.go +++ b/cli/cmd/deviceSet.go @@ -34,7 +34,7 @@ package cmd import ( ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" "github.com/google/uuid" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -52,25 +52,38 @@ The device UUID, request path and value must be specified as positional argument To enable replacing behaviour (destructive!), set the --replace flag."`, Run: func(cmd *cobra.Command, args []string) { + spinner, _ := pterm.DefaultSpinner.Start("Create a path set request.") did, err := uuid.Parse(args[0]) if err != nil { - log.Fatal(err) + spinner.Fail(err) } var operation ppb.ApiOperation if replace { operation = ppb.ApiOperation_API_OPERATION_REPLACE - log.Info("Replace") + spinner.UpdateText("Replace generated and sent") } else { operation = ppb.ApiOperation_API_OPERATION_UPDATE - log.Info("Update") + spinner.UpdateText("Update generated and sent") } - log.Info(pndAdapter.ChangeOND( + + resp, err := pndAdapter.ChangeOND( createContextWithAuthorization(), did, operation, args[1], args[2], - )) + ) + if err != nil { + spinner.Fail(err) + } + + for _, r := range resp.GetResponses() { + if r.Status == ppb.Status_STATUS_OK { + spinner.Success("A change for Device: ", did.String(), "has been created -> Change ID: ", r.GetId()) + } else { + spinner.Fail("An error occured while creating a path set request for Device with ID: ", r.GetId(), r.GetStatus()) + } + } }, } diff --git a/cli/cmd/deviceShow.go b/cli/cmd/deviceShow.go index 7fb419883..1e1536825 100644 --- a/cli/cmd/deviceShow.go +++ b/cli/cmd/deviceShow.go @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -46,8 +46,17 @@ Device UUID or name must be specified as a positional argument. The device information returned is the information as currently stored in the controller. The actual device is not queried directly.`, - Run: func(cmd *cobra.Command, args []string) { - log.Info(pndAdapter.GetDevice(createContextWithAuthorization(), args[0])) + RunE: func(cmd *cobra.Command, args []string) error { + resp, err := pndAdapter.GetDevice(createContextWithAuthorization(), args[0]) + if err != nil { + pterm.Error.Println(err) + return err + } + data := pterm.TableData{[]string{"UUID", "Name", "SBI-UUID", "SBI-Type"}} + for _, dev := range resp.GetOnd() { + data = append(data, []string{dev.GetId(), dev.GetName(), dev.GetSbi().GetId(), dev.GetSbi().GetType().String()}) + } + return nil }, } diff --git a/cli/cmd/login.go b/cli/cmd/login.go index 3d9aba572..e1c8fdeb4 100644 --- a/cli/cmd/login.go +++ b/cli/cmd/login.go @@ -35,7 +35,7 @@ import ( "context" "code.fbi.h-da.de/danet/gosdn/controller/api" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -48,25 +48,26 @@ var loginCmd = &cobra.Command{ User credentials need to be provided in the body`, RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Login attempt for user: ", nbUserName) + + if controllerAPIEndpoint != "" { + if err := viper.WriteConfig(); err != nil { + pterm.Error.Println("Could not write config:", err) + } + pterm.Info.Println("New controller address: ", viper.GetString("controllerAPIEndpoint")) + } + // TODO: maybe add credentials in context instead of context.TODO() resp, err := api.Login(context.TODO(), viper.GetString("controllerAPIEndpoint"), nbUserName, nbUserPwd) if err != nil { + spinner.Fail("Login failed: ", err) return err } - userToken = resp.Token - - if err := api.Init(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint")); err != nil { - return err - } + spinner.Success("Authentication for ", nbUserName, " was successful.") - sbiResp, err := api.GetSBIs(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), viper.GetString("CLI_PND")) - if err != nil { - return err - } - sid := sbiResp.Sbi[0].GetId() - viper.Set("CLI_SBI", sid) - log.Infof("SBI: %v", sid) + userToken = resp.Token + pterm.Info.Println("Authentication-User-Token:", userToken) return nil }, @@ -74,10 +75,17 @@ var loginCmd = &cobra.Command{ var nbUserName string var nbUserPwd string +var controllerAPIEndpoint string func init() { rootCmd.AddCommand(loginCmd) loginCmd.Flags().StringVar(&nbUserName, "u", "", "username for login") loginCmd.Flags().StringVar(&nbUserPwd, "p", "", "pwd for login") + loginCmd.Flags().StringVar(&controllerAPIEndpoint, "controller", viper.GetString("controllerAPIEndpoint"), "address of the controller") + + err := viper.BindPFlag("controllerAPIEndpoint", loginCmd.Flags().Lookup("controller")) + if err != nil { + pterm.Error.Println("Could not bind controllerAPIEndpoint:", err) + } } diff --git a/cli/cmd/pndCreate.go b/cli/cmd/pndCreate.go index f08d429d2..a2859604d 100644 --- a/cli/cmd/pndCreate.go +++ b/cli/cmd/pndCreate.go @@ -32,18 +32,17 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( + "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/core" "code.fbi.h-da.de/danet/gosdn/controller/api" + "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/viper" - "google.golang.org/protobuf/encoding/protojson" - - log "github.com/sirupsen/logrus" ) // pndCreateCmd represents the create command var pndCreateCmd = &cobra.Command{ Use: "create [description]", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(0), Short: "creates a new principal network domain to the controller", Long: `A principal network domain is a main networking entity. This can be a campus building or site. @@ -52,21 +51,31 @@ A description must be passed as positional argument. A name and default SBI can passed using parameters.`, RunE: func(cmd *cobra.Command, args []string) error { - resp, err := api.AddPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, args[0], pndDefaultSbi) + spinner, _ := pterm.DefaultSpinner.Start("Creating new PND") + resp, err := api.AddPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription, pndDefaultSbi) if err != nil { + spinner.Fail(err) return err } - log.Info(protojson.Format(resp)) + + if resp.Status == core.Status_STATUS_OK { + spinner.Success("PND has been created with name: ", pndName) + } else { + spinner.Fail("Failed creating the PND with name: ", pndName) + } + return nil }, } var pndName string var pndDefaultSbi string +var pndDescription string func init() { pndCmd.AddCommand(pndCreateCmd) pndCreateCmd.Flags().StringVar(&pndName, "name", "", "the name of the pnd") + pndCreateCmd.Flags().StringVar(&pndDescription, "description", "", "description of the pnd") pndCreateCmd.Flags().StringVar(&pndDefaultSbi, "sbi", "openconfig", "the default SBI of the pnd") } diff --git a/cli/cmd/pndGet.go b/cli/cmd/pndGet.go index ef5e36a32..7fa6c956f 100644 --- a/cli/cmd/pndGet.go +++ b/cli/cmd/pndGet.go @@ -32,7 +32,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -44,13 +44,19 @@ var pndGetCmd = &cobra.Command{ Long: `Get one or multiple PNDs by uuid or name and print them to stdout.`, RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Fetching requested PNDs from controller.") resp, err := api.GetPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), args...) if err != nil { + spinner.Fail(err) return err } - for i, pnd := range resp.Pnd { - log.Infof("PND %v: %v\n\tuuid: %v", i+1, pnd.Name, pnd.Id) + data := pterm.TableData{[]string{"UUID", "Name", "Description"}} + for _, pnd := range resp.Pnd { + data = append(data, []string{pnd.GetId(), pnd.GetName(), pnd.GetDescription()}) + } + spinner.Success() + pterm.DefaultTable.WithHasHeader().WithData(data).Render() return nil }, } diff --git a/cli/cmd/pndList.go b/cli/cmd/pndList.go index 2f44d74b6..65006b0c7 100644 --- a/cli/cmd/pndList.go +++ b/cli/cmd/pndList.go @@ -33,7 +33,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -46,14 +46,21 @@ var pndListCmd = &cobra.Command{ Long: `List all information about the current PND.`, RunE: func(cmd *cobra.Command, args []string) error { - - resp, err := api.GetPnd(createContextWithAuthorization(), pndAdapter.Endpoint(), pndAdapter.ID().String()) + spinner, _ := pterm.DefaultSpinner.Start("Fetching PND list from controller") + resp, err := api.GetPnds(createContextWithAuthorization(), pndAdapter.Endpoint()) if err != nil { + spinner.Fail(err) return err } - for i, pnd := range resp.Pnd { - log.Infof("PND %v: name: %v, uuid: %v", i+1, pnd.Name, pnd.Id) + + data := pterm.TableData{[]string{"UUID", "Name", "Description"}} + for _, pnd := range resp.Pnd { + data = append(data, []string{pnd.GetId(), pnd.GetName(), pnd.GetDescription()}) } + + spinner.Success() + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() return nil }, } diff --git a/cli/cmd/pndRemove.go b/cli/cmd/pndRemove.go index ed4890a75..98fb573ee 100644 --- a/cli/cmd/pndRemove.go +++ b/cli/cmd/pndRemove.go @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/google/uuid" "github.com/spf13/cobra" @@ -42,19 +42,22 @@ import ( var pndRemoveCmd = &cobra.Command{ Use: "remove", Aliases: []string{"rm"}, - Short: "TODO - not yet implemented", - Long: `TODO - not yet implemented`, + Short: "Removes the PND with the provided ID", + Long: "Removes the PND with the provided ID", RunE: func(cmd *cobra.Command, args []string) error { + spinner, _ := pterm.DefaultSpinner.Start("Removing PND with ID: ", args[0]) pid, err := uuid.Parse(args[0]) if err != nil { + spinner.Fail(err) return err } - resp, err := pndAdapter.RemovePnd(createContextWithAuthorization(), pid) + _, err = pndAdapter.RemovePnd(createContextWithAuthorization(), pid) if err != nil { + spinner.Fail(err) return err } - log.Infof("Deletion of PND with ID %v: %s", pid, resp.GetStatus().String()) + spinner.Success("PND has been deleted, ID: ", pid.String()) return nil }, } diff --git a/cli/cmd/pndUse.go b/cli/cmd/pndUse.go index 22be64cab..f3f77d797 100644 --- a/cli/cmd/pndUse.go +++ b/cli/cmd/pndUse.go @@ -34,7 +34,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/cli/adapter" "code.fbi.h-da.de/danet/gosdn/controller/api" - log "github.com/sirupsen/logrus" + "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -51,25 +51,32 @@ var pndUseCmd = &cobra.Command{ newPndAdapter, err := adapter.NewPndAdapter(newPND, viper.GetString("controllerAPIEndpoint")) if err != nil { - log.Fatal(err) + pterm.Error.Println(err) return err } _, err = api.GetPnd(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), newPND) if err != nil { - log.Fatal(err) + pterm.Error.Println(err) + return err + } + + sbi, err := api.GetSBIs(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), newPND) + if err != nil { + pterm.Error.Println(err) return err } viper.Set("CLI_PND", newPND) + viper.Set("CLI_SBI", sbi.GetSbi()[0].GetId()) err = viper.WriteConfig() if err != nil { - log.Fatal(err) + pterm.Error.Println(err) return err } pndAdapter = newPndAdapter - log.Infof("PND with ID: %s set for usage", pndAdapter.ID().String()) + pterm.Info.Printf("PND with ID: %s has been set for usage.\n", pndAdapter.ID().String()) return nil }, } diff --git a/cli/cmd/prompt.go b/cli/cmd/prompt.go index e9704be94..ecbb6f12a 100644 --- a/cli/cmd/prompt.go +++ b/cli/cmd/prompt.go @@ -36,21 +36,23 @@ import ( "os" "strings" - "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" "code.fbi.h-da.de/danet/gosdn/cli/completer" + "code.fbi.h-da.de/danet/gosdn/controller/api" "github.com/c-bata/go-prompt" "github.com/google/uuid" + "github.com/openconfig/goyang/pkg/yang" + "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/pflag" + "github.com/spf13/viper" ) -var suggestions []prompt.Suggest - // PromptCompleter provides completion for a device type PromptCompleter struct { - //NOTE: not too sure about this but for now it should be sufficient - deviceID uuid.UUID yangSchemaCompleterMap map[uuid.UUID]*completer.YangSchemaCompleter + currentSuggestions []prompt.Suggest + document *prompt.Document + history []string } // NewPromptCompleter returns a new promptCompleter @@ -62,25 +64,35 @@ func NewPromptCompleter() *PromptCompleter { // Run starts the interactive completion func (pc *PromptCompleter) Run() { - fmt.Println("Welcome to the interactive mode of gosdnc.") - defer fmt.Println("Bye!") + title, _ := pterm.DefaultBigText.WithLetters( + pterm.NewLettersFromString("go"), + pterm.NewLettersFromStringWithStyle("SDN", pterm.NewStyle(pterm.FgCyan)), + pterm.NewLettersFromString("c"), + ).Srender() + description := pterm.DefaultBasicText.Sprint("Control your goSDN controller like you've never done it before!") + pterm.DefaultCenter.Println(title) + pterm.DefaultCenter.Println(description) p := prompt.New( executeFunc, pc.cstmCompleter, prompt.OptionTitle("gosdnc-prompt: interactive gosdn CLI"), prompt.OptionPrefix(">>> "), + prompt.OptionPrefixTextColor(prompt.Cyan), prompt.OptionCompletionWordSeparator(completer.YangSchemaCompletionSeperator), prompt.OptionShowCompletionAtStart(), - prompt.OptionSuggestionBGColor(prompt.DarkBlue), - prompt.OptionSuggestionTextColor(prompt.DarkGray), - prompt.OptionDescriptionTextColor(prompt.White), - prompt.OptionDescriptionBGColor(prompt.DarkGray), - prompt.OptionSelectedSuggestionBGColor(prompt.DarkRed), + prompt.OptionCompletionOnDown(), + prompt.OptionHistory(pc.history), + prompt.OptionSuggestionBGColor(prompt.DarkGray), + prompt.OptionSuggestionTextColor(prompt.LightGray), + prompt.OptionDescriptionTextColor(prompt.DarkGray), + prompt.OptionDescriptionBGColor(prompt.LightGray), + prompt.OptionSelectedSuggestionBGColor(prompt.Cyan), prompt.OptionSelectedSuggestionTextColor(prompt.DarkGray), - prompt.OptionSelectedDescriptionBGColor(prompt.DarkGray), - prompt.OptionSelectedDescriptionTextColor(prompt.White), + prompt.OptionSelectedDescriptionBGColor(prompt.LightGray), + prompt.OptionSelectedDescriptionTextColor(prompt.DarkGray), ) + p.Run() } @@ -96,106 +108,231 @@ func executeFunc(s string) { } } -func flagVisitor(f *pflag.Flag) { - if !f.Hidden { - suggestions = append(suggestions, prompt.Suggest{Text: "--" + f.Name, Description: f.Usage}) - } -} - func (pc *PromptCompleter) cstmCompleter(d prompt.Document) []prompt.Suggest { // Start with the cobra 'rootCmd' and walk through it // Reference: https://github.com/stromland/cobra-prompt currCmd := rootCmd - inputSplit := removeFlagsFromInputSlice(strings.Fields(d.CurrentLine())) - if c, _, err := currCmd.Find(inputSplit); err == nil { + inputSplit := strings.Fields(d.CurrentLine()) + inputSplitFiltered, inputFlags := filterFlagSlice(inputSplit) + if c, _, err := currCmd.Find(inputSplitFiltered); err == nil { currCmd = c } - return completionBasedOnCmd(pc, currCmd, inputSplit, d) + return completionBasedOnCmd(pc, currCmd, inputSplitFiltered, inputFlags, d) } -func removeFlagsFromInputSlice(input []string) []string { - r := []string{} +func filterFlagSlice(input []string) (commandSlice []string, flagSlice []string) { for _, in := range input { if !strings.HasPrefix(in, "--") { - r = append(r, in) + commandSlice = append(commandSlice, in) + } else { + flagSlice = append(flagSlice, strings.Split(in, "=")[0]) } } - return r + return commandSlice, flagSlice } func deviceGetCompletion(c *PromptCompleter, d prompt.Document, inputSplit []string) []prompt.Suggest { - inputLen := len(inputSplit) - if inputLen == 2 || inputLen == 3 { - if id, err := uuid.Parse(inputSplit[inputLen-1]); err == nil { - if c, ok := c.yangSchemaCompleterMap[id]; ok { - return c.Complete(d) - } - dev, err := pndAdapter.GetDevice(createContextWithAuthorization(), id.String()) - if err != nil { - return []prompt.Suggest{} - } - sid, err := uuid.Parse(dev[0].GetSbi().GetId()) - if err != nil { - return []prompt.Suggest{} - } - schemaTree, err := pndAdapter.GetSbiSchemaTree(createContextWithAuthorization(), sid) - if err != nil { - return []prompt.Suggest{} - } - c.yangSchemaCompleterMap[id] = completer.NewYangSchemaCompleter(schemaTree["Device"], true) - if yc, ok := c.yangSchemaCompleterMap[id]; ok { - c.deviceID = id - return yc.Complete(d) - } - + switch inputLen := len(inputSplit); inputLen { + case 2: + return c.updateSuggestionsThroughFunc(d, getDevices) + case 3: + id, err := uuid.Parse(inputSplit[inputLen-1]) + if err != nil { + return c.updateSuggestionsThroughFunc(d, getDevices) + } + if c, ok := c.yangSchemaCompleterMap[id]; ok { + return c.Complete(d) + } + schemaTree, err := getSchemaTreeForDeviceID(id.String()) + if err != nil { return []prompt.Suggest{} } - if inputLen == 2 || (inputLen == 3 && !(d.GetWordBeforeCursor() == "")) { - return prompt.FilterHasPrefix(getDevices(), d.GetWordBeforeCursor(), true) + c.yangSchemaCompleterMap[id] = completer.NewYangSchemaCompleter(schemaTree["Device"], true) + if yc, ok := c.yangSchemaCompleterMap[id]; ok { + return yc.Complete(d) + } + case 4: + if d.GetWordBeforeCursor() == "" || d.GetWordAfterCursor() != "" { + return []prompt.Suggest{} + } + id, err := uuid.Parse(inputSplit[inputLen-2]) + if err != nil { + return c.updateSuggestionsThroughFunc(d, getDevices) } - } else { - if yc, ok := c.yangSchemaCompleterMap[c.deviceID]; ok { + if yc, ok := c.yangSchemaCompleterMap[id]; ok { return yc.Complete(d) } + default: return []prompt.Suggest{} } return []prompt.Suggest{} } -func cobraCommandCompletion(currCmd *cobra.Command, d prompt.Document, loaded []prompt.Suggest) []prompt.Suggest { - suggestions = []prompt.Suggest{} - if len(loaded) > 0 { - suggestions = append(suggestions, loaded...) +func (pc *PromptCompleter) updateSuggestionsThroughFunc(d prompt.Document, fn func() ([]prompt.Suggest, error)) []prompt.Suggest { + if pc.currentSuggestions == nil { + var err error + pc.currentSuggestions, err = fn() + if err != nil { + return prompt.FilterHasPrefix(pc.currentSuggestions, d.GetWordBeforeCursor(), true) + } } + return prompt.FilterHasPrefix(pc.currentSuggestions, d.GetWordBeforeCursor(), true) +} + +func cobraCommandCompletion(currCmd *cobra.Command, d prompt.Document, inputFlags []string, loaded []prompt.Suggest) []prompt.Suggest { if currCmd.HasAvailableFlags() { - // it would be possible to always show the inherited flags, but i think - // this is currently not necessary. - // currCmd.InheritedFlags().VisitAll(flagVisitor) - currCmd.LocalFlags().VisitAll(flagVisitor) + currCmd.LocalFlags().VisitAll( + func(f *pflag.Flag) { + if !f.Hidden && !sliceContains(inputFlags, "--"+f.Name) { + loaded = append(loaded, prompt.Suggest{Text: "--" + f.Name, Description: f.Usage}) + } + }, + ) } for _, cmd := range currCmd.Commands() { - suggestions = append(suggestions, prompt.Suggest{Text: cmd.Name(), Description: cmd.Short}) + loaded = append(loaded, prompt.Suggest{Text: cmd.Name(), Description: cmd.Short}) } - return prompt.FilterHasPrefix(suggestions, d.GetWordBeforeCursor(), true) + + return prompt.FilterHasPrefix(loaded, d.GetWordBeforeCursor(), true) } -func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []string, d prompt.Document) []prompt.Suggest { +//nolint +func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []string, inputFlags []string, d prompt.Document) []prompt.Suggest { switch cmd { - case pndUseCmd, pndGetCmd: - return cobraCommandCompletion(cmd, d, getPnds()) + case pndUseCmd, pndGetCmd, pndRemoveCmd: + if len(inputSplit) < 3 || (len(inputSplit) == 3 && d.GetWordBeforeCursor() != "") { + suggestions := c.updateSuggestionsThroughFunc(d, getPnds) + return cobraCommandCompletion(cmd, d, inputFlags, suggestions) + } case commitCmd: - return getChangesByType(pnd.ChangeState_CHANGE_STATE_PENDING) + if len(inputSplit) < 3 || (len(inputSplit) == 3 && d.GetWordBeforeCursor() != "") { + return c.updateSuggestionsThroughFunc(d, getCommitedChanges) + } case confirmCmd: - return getChangesByType(pnd.ChangeState_CHANGE_STATE_COMMITTED) + if len(inputSplit) < 3 || (len(inputSplit) == 3 && d.GetWordBeforeCursor() != "") { + return c.updateSuggestionsThroughFunc(d, getConfirmedChanges) + } + case deviceRemoveCmd: + if len(inputSplit) < 3 || (len(inputSplit) == 3 && d.GetWordBeforeCursor() != "") { + return c.updateSuggestionsThroughFunc(d, getDevices) + } case deviceGetCmd, deviceSetCmd: return deviceGetCompletion(c, d, inputSplit) case deviceShowCmd: - return getDevices() + devices, err := getDevices() + if err != nil { + return []prompt.Suggest{} + } + return devices + case deviceCmd, pndCmd, changeCmd: + c.currentSuggestions = nil + return cobraCommandCompletion(cmd, d, inputFlags, []prompt.Suggest{}) default: - return cobraCommandCompletion(cmd, d, []prompt.Suggest{}) + return cobraCommandCompletion(cmd, d, inputFlags, []prompt.Suggest{}) + } + + return []prompt.Suggest{} +} + +// getDevices is a helper function which requests devices from the controller +// and gives feedback about the current pulling status with the help of pterm +// 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()) + if err != nil { + spinner.Fail(err) + return []prompt.Suggest{}, err + } + + s := []prompt.Suggest{} + for _, ond := range resp.Ond { + s = append(s, prompt.Suggest{Text: ond.GetId(), Description: ond.GetName()}) + } + spinner.Success() + return completer.SortSuggestionByText(s), nil +} + +// getSchemaTreeForDeviceID is a helper function which requests the SBI's +// schema tree of a specific device. The function gives feedback about the +// current pulling status with the help of pterm. +func getSchemaTreeForDeviceID(id string) (map[string]*yang.Entry, error) { + spinner, _ := pterm.DefaultSpinner.Start("Fetching schema tree for Device with ID: ", id) + dev, err := pndAdapter.GetDevice(createContextWithAuthorization(), id) + if err != nil { + spinner.Fail(err) + return nil, err + } + sid, err := uuid.Parse(dev.GetOnd()[0].GetSbi().GetId()) + if err != nil { + spinner.Fail(err) + return nil, err + } + spinner.Success() + return pndAdapter.GetSbiSchemaTree(createContextWithAuthorization(), sid) +} + +// getPnds is a helper function which requests pnds from the controller and +// gives feedback about the current pulling status with the help of pterm the +// result is converted into a prompt.Suggest slice. +func getPnds() ([]prompt.Suggest, error) { + spinner, _ := pterm.DefaultSpinner.Start("Fetching PNDs from controller.") + resp, err := api.GetIds(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint")) + if err != nil { + spinner.Fail(err) + return []prompt.Suggest{}, err + } + + s := []prompt.Suggest{} + for _, pnd := range resp { + s = append(s, prompt.Suggest{Text: pnd.GetId(), Description: pnd.GetDescription()}) + } + spinner.Success() + return completer.SortSuggestionByText(s), nil +} + +// getCommitedChanges is a helper function which requests all the commited +// changes from the controller and gives feedback about the current pulling +// status with the help of pterm the result is converted into a prompt.Suggest +// slice. +func getCommitedChanges() ([]prompt.Suggest, error) { + spinner, _ := pterm.DefaultSpinner.Start("Fetching commited changes.") + + resp, err := pndAdapter.CommittedChanges(createContextWithAuthorization()) + if err != nil { + spinner.Fail(err) + return []prompt.Suggest{}, err + } + + s := []prompt.Suggest{} + for _, change := range resp { + s = append(s, prompt.Suggest{Text: change.GetId(), Description: change.State.String()}) + } + spinner.Success() + return completer.SortSuggestionByText(s), nil +} + +// getConfirmedChanges is a helper function which requests all the confirmed +// changes from the controller and gives feedback about the current pulling +// status with the help of pterm the result is converted into a prompt.Suggest +// slice. +func getConfirmedChanges() ([]prompt.Suggest, error) { + spinner, _ := pterm.DefaultSpinner.Start("Fetching confirmed changes.") + + resp, err := pndAdapter.ConfirmedChanges(createContextWithAuthorization()) + if err != nil { + spinner.Fail(err) + return []prompt.Suggest{}, err + } + + s := []prompt.Suggest{} + for _, change := range resp { + s = append(s, prompt.Suggest{Text: change.GetId(), Description: change.State.String()}) } + spinner.Success() + return completer.SortSuggestionByText(s), nil } var exitCmd = &cobra.Command{ diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 3fdfffe20..bf5c80408 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -67,7 +67,8 @@ The login command must be called for authorization. // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - cobra.CheckErr(rootCmd.Execute()) + rootCmd.Execute() + //cobra.CheckErr(rootCmd.Execute()) } func init() { diff --git a/cli/cmd/utils.go b/cli/cmd/utils.go index cf6a03780..0e5df4a66 100644 --- a/cli/cmd/utils.go +++ b/cli/cmd/utils.go @@ -36,11 +36,6 @@ import ( "errors" "net" - "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" - "code.fbi.h-da.de/danet/gosdn/cli/completer" - "code.fbi.h-da.de/danet/gosdn/controller/api" - "github.com/c-bata/go-prompt" - "github.com/spf13/viper" "google.golang.org/grpc/metadata" ) @@ -60,45 +55,14 @@ func checkIPPort(string) error { return nil } -func getDevices() []prompt.Suggest { - resp, err := api.GetDevices(createContextWithAuthorization(), pndAdapter.Endpoint(), pndAdapter.ID().String()) - if err != nil { - return []prompt.Suggest{} - } - - s := []prompt.Suggest{} - for _, ond := range resp.Ond { - s = append(s, prompt.Suggest{Text: ond.GetId(), Description: ond.GetName()}) - } - return completer.SortSuggestionByText(s) -} - -func getPnds() []prompt.Suggest { - resp, err := api.GetIds(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint")) - if err != nil { - return []prompt.Suggest{} - } - - s := []prompt.Suggest{} - for _, pnd := range resp { - s = append(s, prompt.Suggest{Text: pnd.GetId(), Description: pnd.GetDescription()}) - } - return completer.SortSuggestionByText(s) -} - -func getChangesByType(cType pnd.ChangeState) []prompt.Suggest { - resp, err := api.GetChanges(createContextWithAuthorization(), pndAdapter.Endpoint(), pndAdapter.ID().String()) - if err != nil { - return []prompt.Suggest{} - } - - s := []prompt.Suggest{} - for _, change := range resp.GetChange() { - if change.GetState() == cType { - s = append(s, prompt.Suggest{Text: change.GetId(), Description: change.State.String()}) +// sliceContains checks if a slice contains the given item +func sliceContains[T comparable](slice []T, toCompare T) bool { + for _, sliceEntry := range slice { + if sliceEntry == toCompare { + return true } } - return completer.SortSuggestionByText(s) + return false } func createContextWithAuthorization() context.Context { diff --git a/controller/api/change.go b/controller/api/change.go index e469db6c1..57b826085 100644 --- a/controller/api/change.go +++ b/controller/api/change.go @@ -2,6 +2,7 @@ package api import ( "context" + "errors" "time" ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" @@ -21,6 +22,23 @@ func GetChanges(ctx context.Context, addr, pnd string) (*ppb.GetChangeListRespon return client.GetChangeList(ctx, req) } +// GetChange requests one or more changes from the controller +func GetChange(ctx context.Context, addr string, pnd string, args ...string) (*ppb.GetChangeResponse, error) { + client, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + if len(args) <= 0 { + return nil, errors.New("not enough arguments") + } + req := &ppb.GetChangeRequest{ + Timestamp: time.Now().UnixNano(), + Pid: pnd, + Cuid: args, + } + return client.GetChange(ctx, req) +} + // Commit sends a Commit request for one or multiple changes to the // controller. func Commit(ctx context.Context, addr, pnd string, cuids ...string) (*ppb.SetChangeListResponse, error) { @@ -61,9 +79,10 @@ func CommitConfirm(ctx context.Context, addr, pnd string, changes []*ppb.SetChan return client.SetChangeList(ctx, req) } -// ChangeRequest 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) +// ChangeRequest 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(ctx context.Context, addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetPathListResponse, error) { req := &ppb.ChangeRequest{ diff --git a/controller/api/initialise_test.go b/controller/api/initialise_test.go index efcc249ed..a1c317e32 100644 --- a/controller/api/initialise_test.go +++ b/controller/api/initialise_test.go @@ -85,9 +85,26 @@ func bootstrapUnitTest() { userService = rbacImpl.NewUserService(rbacImpl.NewMemoryUserStore()) roleService = rbacImpl.NewRoleService(rbacImpl.NewMemoryRoleStore()) + previousHostname := "previousHostname" + intendedHostname := "intendedHostname" + mockChange := &mocks.Change{} mockChange.On("Age").Return(time.Hour) mockChange.On("State").Return(ppb.ChangeState_CHANGE_STATE_INCONSISTENT) + mockChange.On("PreviousState").Return(&openconfig.Device{ + System: &openconfig.OpenconfigSystem_System{ + Config: &openconfig.OpenconfigSystem_System_Config{ + Hostname: &previousHostname, + }, + }, + }) + mockChange.On("IntendedState").Return(&openconfig.Device{ + System: &openconfig.OpenconfigSystem_System{ + Config: &openconfig.OpenconfigSystem_System_Config{ + Hostname: &intendedHostname, + }, + }, + }) mockPnd := mocks.NetworkDomain{} mockPnd.On("ID").Return(pndUUID) @@ -96,7 +113,7 @@ func bootstrapUnitTest() { mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID}) mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID}) mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil) - mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil) mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{ UUID: deviceUUID, Model: &openconfig.Device{}, diff --git a/controller/api/pnd.go b/controller/api/pnd.go index 791ebefc6..01957053a 100644 --- a/controller/api/pnd.go +++ b/controller/api/pnd.go @@ -56,9 +56,6 @@ func GetPnds(ctx context.Context, addr string, args ...string) (*pb.GetPndListRe if err != nil { return nil, err } - if len(args) <= 0 { - return nil, errors.New("not enough arguments") - } req := &pb.GetPndListRequest{ Timestamp: time.Now().UnixNano(), diff --git a/controller/interfaces/change/change.go b/controller/interfaces/change/change.go index ba8075db9..40e8cc90e 100644 --- a/controller/interfaces/change/change.go +++ b/controller/interfaces/change/change.go @@ -18,6 +18,8 @@ type Change interface { Confirm() error State() ppb.ChangeState Age() time.Duration + PreviousState() ygot.GoStruct + IntendedState() ygot.GoStruct } // Payload contains two ygot.GoStructs, the first represents the original state diff --git a/controller/interfaces/networkdomain/pnd.go b/controller/interfaces/networkdomain/pnd.go index 2c86f6260..fc9dec411 100644 --- a/controller/interfaces/networkdomain/pnd.go +++ b/controller/interfaces/networkdomain/pnd.go @@ -16,7 +16,7 @@ type NetworkDomain interface { Destroy() error AddSbi(s southbound.SouthboundInterface) error RemoveSbi(uuid.UUID) error - AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error + AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) (uuid.UUID, error) GetDevice(identifier string) (device.Device, error) RemoveDevice(uuid.UUID) error Devices() []device.Device diff --git a/controller/mocks/Change.go b/controller/mocks/Change.go index 9c3e9b9f2..fb370384e 100644 --- a/controller/mocks/Change.go +++ b/controller/mocks/Change.go @@ -1,14 +1,18 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks import ( - time "time" + testing "testing" pnd "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd" mock "github.com/stretchr/testify/mock" + time "time" + uuid "github.com/google/uuid" + + ygot "github.com/openconfig/ygot/ygot" ) // Change is an autogenerated mock type for the Change type @@ -74,6 +78,38 @@ func (_m *Change) ID() uuid.UUID { return r0 } +// IntendedState provides a mock function with given fields: +func (_m *Change) IntendedState() ygot.GoStruct { + ret := _m.Called() + + var r0 ygot.GoStruct + if rf, ok := ret.Get(0).(func() ygot.GoStruct); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ygot.GoStruct) + } + } + + return r0 +} + +// PreviousState provides a mock function with given fields: +func (_m *Change) PreviousState() ygot.GoStruct { + ret := _m.Called() + + var r0 ygot.GoStruct + if rf, ok := ret.Get(0).(func() ygot.GoStruct); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ygot.GoStruct) + } + } + + return r0 +} + // State provides a mock function with given fields: func (_m *Change) State() pnd.ChangeState { ret := _m.Called() @@ -87,3 +123,12 @@ func (_m *Change) State() pnd.ChangeState { return r0 } + +// NewChange creates a new instance of Change. It also registers a cleanup function to assert the mocks expectations. +func NewChange(t testing.TB) *Change { + mock := &Change{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/mocks/Device.go b/controller/mocks/Device.go index 5004309d1..4b42cddd7 100644 --- a/controller/mocks/Device.go +++ b/controller/mocks/Device.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks @@ -7,6 +7,8 @@ import ( mock "github.com/stretchr/testify/mock" protoreflect "google.golang.org/protobuf/reflect/protoreflect" + testing "testing" + transport "code.fbi.h-da.de/danet/gosdn/controller/interfaces/transport" uuid "github.com/google/uuid" @@ -19,32 +21,32 @@ type Device struct { mock.Mock } -// ID provides a mock function with given fields: -func (_m *Device) ID() uuid.UUID { +// GetModel provides a mock function with given fields: +func (_m *Device) GetModel() ygot.ValidatedGoStruct { ret := _m.Called() - var r0 uuid.UUID - if rf, ok := ret.Get(0).(func() uuid.UUID); ok { + var r0 ygot.ValidatedGoStruct + if rf, ok := ret.Get(0).(func() ygot.ValidatedGoStruct); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(uuid.UUID) + r0 = ret.Get(0).(ygot.ValidatedGoStruct) } } return r0 } -// Model provides a mock function with given fields: -func (_m *Device) Model() ygot.GoStruct { +// ID provides a mock function with given fields: +func (_m *Device) ID() uuid.UUID { ret := _m.Called() - var r0 ygot.GoStruct - if rf, ok := ret.Get(0).(func() ygot.GoStruct); ok { + var r0 uuid.UUID + if rf, ok := ret.Get(0).(func() uuid.UUID); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(ygot.GoStruct) + r0 = ret.Get(0).(uuid.UUID) } } @@ -110,3 +112,12 @@ func (_m *Device) Transport() transport.Transport { return r0 } + +// NewDevice creates a new instance of Device. It also registers a cleanup function to assert the mocks expectations. +func NewDevice(t testing.TB) *Device { + mock := &Device{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/mocks/NetworkDomain.go b/controller/mocks/NetworkDomain.go index 607db2834..22e6e7bfc 100644 --- a/controller/mocks/NetworkDomain.go +++ b/controller/mocks/NetworkDomain.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks @@ -14,6 +14,8 @@ import ( southbound "code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound" + testing "testing" + transport "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport" uuid "github.com/google/uuid" @@ -25,17 +27,26 @@ type NetworkDomain struct { } // AddDevice provides a mock function with given fields: name, opts, sid -func (_m *NetworkDomain) AddDevice(name string, opts *transport.TransportOption, sid uuid.UUID) error { +func (_m *NetworkDomain) AddDevice(name string, opts *transport.TransportOption, sid uuid.UUID) (uuid.UUID, error) { ret := _m.Called(name, opts, sid) - var r0 error - if rf, ok := ret.Get(0).(func(string, *transport.TransportOption, uuid.UUID) error); ok { + var r0 uuid.UUID + if rf, ok := ret.Get(0).(func(string, *transport.TransportOption, uuid.UUID) uuid.UUID); ok { r0 = rf(name, opts, sid) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(uuid.UUID) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(string, *transport.TransportOption, uuid.UUID) error); ok { + r1 = rf(name, opts, sid) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // AddSbi provides a mock function with given fields: s @@ -393,3 +404,12 @@ func (_m *NetworkDomain) RequestAll(_a0 string) error { return r0 } + +// NewNetworkDomain creates a new instance of NetworkDomain. It also registers a cleanup function to assert the mocks expectations. +func NewNetworkDomain(t testing.TB) *NetworkDomain { + mock := &NetworkDomain{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/mocks/Plugin.go b/controller/mocks/Plugin.go index f69729e0c..b6d86b916 100644 --- a/controller/mocks/Plugin.go +++ b/controller/mocks/Plugin.go @@ -1,11 +1,14 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks import ( + testing "testing" + plugin "code.fbi.h-da.de/danet/gosdn/controller/interfaces/plugin" - uuid "github.com/google/uuid" mock "github.com/stretchr/testify/mock" + + uuid "github.com/google/uuid" ) // Plugin is an autogenerated mock type for the Plugin type @@ -86,3 +89,12 @@ func (_m *Plugin) Update() error { return r0 } + +// NewPlugin creates a new instance of Plugin. It also registers a cleanup function to assert the mocks expectations. +func NewPlugin(t testing.TB) *Plugin { + mock := &Plugin{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/mocks/SouthboundInterface.go b/controller/mocks/SouthboundInterface.go index abf903d86..ca8fa0a15 100644 --- a/controller/mocks/SouthboundInterface.go +++ b/controller/mocks/SouthboundInterface.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks @@ -7,6 +7,8 @@ import ( gnmi "github.com/openconfig/gnmi/proto/gnmi" mock "github.com/stretchr/testify/mock" + testing "testing" + uuid "github.com/google/uuid" yang "github.com/openconfig/goyang/pkg/yang" @@ -143,3 +145,12 @@ func (_m *SouthboundInterface) Unmarshal(_a0 []byte, _a1 *gnmi.Path, _a2 ygot.Va return r0 } + +// NewSouthboundInterface creates a new instance of SouthboundInterface. It also registers a cleanup function to assert the mocks expectations. +func NewSouthboundInterface(t testing.TB) *SouthboundInterface { + mock := &SouthboundInterface{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/mocks/Storable.go b/controller/mocks/Storable.go index 2f37e9dc9..9219bcfc0 100644 --- a/controller/mocks/Storable.go +++ b/controller/mocks/Storable.go @@ -1,10 +1,12 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks import ( mock "github.com/stretchr/testify/mock" + testing "testing" + uuid "github.com/google/uuid" ) @@ -28,3 +30,12 @@ func (_m *Storable) ID() uuid.UUID { return r0 } + +// NewStorable creates a new instance of Storable. It also registers a cleanup function to assert the mocks expectations. +func NewStorable(t testing.TB) *Storable { + mock := &Storable{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/mocks/Transport.go b/controller/mocks/Transport.go index b2c7aa34f..ae80536a4 100644 --- a/controller/mocks/Transport.go +++ b/controller/mocks/Transport.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. +// Code generated by mockery v2.11.0. DO NOT EDIT. package mocks @@ -9,6 +9,8 @@ import ( mock "github.com/stretchr/testify/mock" + testing "testing" + ytypes "github.com/openconfig/ygot/ytypes" ) @@ -109,3 +111,12 @@ func (_m *Transport) Type() string { return r0 } + +// NewTransport creates a new instance of Transport. It also registers a cleanup function to assert the mocks expectations. +func NewTransport(t testing.TB) *Transport { + mock := &Transport{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/northbound/server/pnd.go b/controller/northbound/server/pnd.go index 6d5300845..2ef00339a 100644 --- a/controller/northbound/server/pnd.go +++ b/controller/northbound/server/pnd.go @@ -393,7 +393,7 @@ func (p pndServer) GetChange(ctx context.Context, request *ppb.GetChangeRequest) log.Error(err) return nil, status.Errorf(codes.Aborted, "%v", err) } - changes, err := fillChanges(pnd, false, request.Cuid) + changes, err := fillChanges(pnd, false, request.Cuid...) if err != nil { log.Error(err) return nil, status.Errorf(codes.Aborted, "%v", err) @@ -469,10 +469,17 @@ func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]* return nil, status.Errorf(codes.Aborted, "%v", err) } + diff, err := ygot.Diff(c.PreviousState(), c.IntendedState()) + 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(), + Diff: diff, } } return changes, nil @@ -492,25 +499,30 @@ func (p pndServer) SetOndList(ctx context.Context, request *ppb.SetOndListReques return nil, handleRPCError(labels, err) } + deviceIDs := make([]uuid.UUID, 0, len(request.Ond)) for _, r := range request.Ond { 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 { + did, err := pnd.AddDevice(r.DeviceName, r.TransportOption, sid) + if err != nil { log.Error(err) return nil, status.Errorf(codes.Aborted, "%v", err) } + deviceIDs = append(deviceIDs, did) + } + + r := make([]*ppb.SetResponse, len(deviceIDs)) + for i, did := range deviceIDs { + r[i] = &ppb.SetResponse{Id: did.String(), Status: ppb.Status_STATUS_OK} } + return &ppb.SetOndListResponse{ Timestamp: time.Now().UnixNano(), Status: ppb.Status_STATUS_OK, - Responses: []*ppb.SetResponse{ - { - Status: ppb.Status_STATUS_OK, - }, - }, + Responses: r, }, nil } diff --git a/controller/nucleus/change.go b/controller/nucleus/change.go index 6da303875..935360ca5 100644 --- a/controller/nucleus/change.go +++ b/controller/nucleus/change.go @@ -116,6 +116,18 @@ func (c *Change) State() ppb.ChangeState { return state } +// PreviousState returns the previous state of the devices config as +// ygot.GoStruct. +func (c *Change) PreviousState() ygot.GoStruct { + return c.previousState +} + +// IntendedState returns the intended state of the devices config as +// ygot.GoStruct. +func (c *Change) IntendedState() ygot.GoStruct { + return c.intendedState +} + func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<- ppb.ChangeState, <-chan ppb.ChangeState, <-chan error) { stateIn := make(chan ppb.ChangeState) stateOut := make(chan ppb.ChangeState) diff --git a/controller/nucleus/principalNetworkDomain.go b/controller/nucleus/principalNetworkDomain.go index 3d23862bc..ad4b601c7 100644 --- a/controller/nucleus/principalNetworkDomain.go +++ b/controller/nucleus/principalNetworkDomain.go @@ -215,32 +215,31 @@ func (pnd *pndImplementation) RemoveSbi(sid uuid.UUID) error { } // AddDevice adds a new device to the PND -func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, sid uuid.UUID) error { +func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, sid uuid.UUID) (uuid.UUID, error) { labels := prometheus.Labels{"type": opt.Type.String()} start := metrics.StartHook(labels, deviceCreationsTotal) defer metrics.FinishHook(labels, start, deviceCreationDurationSecondsTotal, deviceCreationDurationSeconds) var sbi southbound.SouthboundInterface + var err error switch t := opt.Type; t { case spb.Type_TYPE_CONTAINERISED: return pnd.handleCsbiEnrolment(name, opt) case spb.Type_TYPE_PLUGIN: - var err error sbi, err = pnd.requestPlugin(name, opt) if err != nil { - return err + return uuid.Nil, err } default: - var err error sbi, err = pnd.sbic.Get(store.Query{ID: sid}) if err != nil { - return err + return uuid.Nil, err } } d, err := NewDevice(name, uuid.Nil, opt, sbi) if err != nil { - return err + return uuid.Nil, err } return pnd.addDevice(d) } @@ -302,13 +301,13 @@ func (pnd *pndImplementation) removeSbi(id uuid.UUID) error { } // addDevice adds a device to the PND's device store. -func (pnd *pndImplementation) addDevice(device device.Device) error { +func (pnd *pndImplementation) addDevice(device device.Device) (uuid.UUID, error) { err := pnd.devices.Add(device) if err != nil { - return err + return uuid.Nil, err } - return nil + return device.ID(), nil } func (pnd *pndImplementation) removeDevice(id uuid.UUID) error { @@ -492,7 +491,7 @@ func (pnd *pndImplementation) handleCsbiDeletion(id uuid.UUID) error { return nil } -func (pnd *pndImplementation) handleCsbiEnrolment(name string, opt *tpb.TransportOption) error { +func (pnd *pndImplementation) handleCsbiEnrolment(name string, opt *tpb.TransportOption) (uuid.UUID, error) { g := new(errgroup.Group) ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) defer cancel() @@ -502,20 +501,26 @@ func (pnd *pndImplementation) handleCsbiEnrolment(name string, opt *tpb.Transpor } resp, err := pnd.csbiClient.Create(ctx, req) if err != nil { - return err + return uuid.Nil, err } + // the slice only contains one deployment + var devID uuid.UUID for _, d := range resp.Deployments { dCopy := d g.Go(func() error { - return pnd.createCsbiDevice(ctx, name, dCopy, opt) + devID, err = pnd.createCsbiDevice(ctx, name, dCopy, opt) + if err != nil { + return err + } + return nil }) } err = g.Wait() if err != nil { - return err + return uuid.Nil, err } - return nil + return devID, nil } // createCsbiDevice is a helper method for cSBI device creation. The method @@ -526,10 +531,10 @@ func (pnd *pndImplementation) createCsbiDevice( name string, d *cpb.Deployment, opt *tpb.TransportOption, -) error { +) (uuid.UUID, error) { id, err := uuid.Parse(d.Id) if err != nil { - return err + return uuid.Nil, err } ch := make(chan device.Details, 1) pnd.callback(id, ch) @@ -547,7 +552,7 @@ func (pnd *pndImplementation) createCsbiDevice( log.Infof("syn from csbi %v", deviceDetails.ID) id, err := uuid.Parse(deviceDetails.ID) if err != nil { - return err + return uuid.Nil, err } csbiTransportOptions := &tpb.TransportOption{ Address: deviceDetails.Address, @@ -568,41 +573,42 @@ func (pnd *pndImplementation) createCsbiDevice( // here and in csbi. gClient, err := pnd.csbiClient.GetGoStruct(ctx, req) if err != nil { - return err + return uuid.Nil, err } csbiID, err := saveGenericClientStreamToFile(gClient, "gostructs.go", uuid.New()) if err != nil { - return err + return uuid.Nil, err } // TODO: this is currently just a workaround needs major adjustments // here and in csbi. mClient, err := pnd.csbiClient.GetManifest(ctx, req) if err != nil { - return err + return uuid.Nil, err } _, err = saveGenericClientStreamToFile(mClient, "plugin.yml", csbiID) if err != nil { - return err + return uuid.Nil, err } csbi, err := NewSBI(spb.Type_TYPE_CONTAINERISED, csbiID) if err != nil { - return err + return uuid.Nil, err } err = pnd.sbic.Add(csbi) if err != nil { - return err + return uuid.Nil, err } d, err := NewDevice(name, uuid.Nil, csbiTransportOptions, csbi) if err != nil { - return err + return uuid.Nil, err } d.(*CsbiDevice).UUID = id ch <- device.Details{TransportOption: opt} if err := pnd.devices.Add(d); err != nil { - return err + return uuid.Nil, err } + return id, nil } - return nil + return uuid.Nil, nil } // requestPlugin is a feature for cSBIs and sends a plugin request to the cSBI diff --git a/controller/nucleus/principalNetworkDomain_test.go b/controller/nucleus/principalNetworkDomain_test.go index 2045bd626..a53a7790f 100644 --- a/controller/nucleus/principalNetworkDomain_test.go +++ b/controller/nucleus/principalNetworkDomain_test.go @@ -115,7 +115,7 @@ func Test_pndImplementation_AddDevice(t *testing.T) { t.Error(err) } - err := pnd.AddDevice(tt.args.name, tt.args.opts, defaultSbiID) + _, err := pnd.AddDevice(tt.args.name, tt.args.opts, defaultSbiID) if (err != nil) != tt.wantErr { t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr) } @@ -290,7 +290,8 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) { sbi: sbi, transport: nil, } - if err := pnd.addDevice(d); err != nil { + _, err = pnd.addDevice(d) + if err != nil { t.Error(err) } got, err := pnd.MarshalDevice(tt.args.uuid.String()) @@ -339,7 +340,8 @@ func Test_pndImplementation_RemoveDevice(t *testing.T) { sbi: sbi, transport: nil, } - if err := pnd.addDevice(d); err != nil { + _, err = pnd.addDevice(d) + if err != nil { t.Error(err) } if err := pnd.RemoveDevice(tt.args.uuid); (err != nil) != tt.wantErr { @@ -454,10 +456,12 @@ func Test_pndImplementation_RemoveSbiWithAssociatedDevices(t *testing.T) { if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { t.Error(err) } - if err := pnd.AddDevice("associatedDevice", opts, tt.args.id); err != nil { + _, err = pnd.AddDevice("associatedDevice", opts, tt.args.id) + if err != nil { t.Error(err) } - if err := pnd.AddDevice("associatedDevice2", opts, tt.args.id); err != nil { + _, err = pnd.AddDevice("associatedDevice2", opts, tt.args.id) + if err != nil { t.Error(err) } if tt.name == "exclusively remove associated devices" { @@ -465,7 +469,8 @@ func Test_pndImplementation_RemoveSbiWithAssociatedDevices(t *testing.T) { if err := pnd.addSbi(&OpenConfig{id: newID}); err != nil { t.Error(err) } - if err := pnd.AddDevice("associatedDevice2", opts, newID); err != nil { + _, err := pnd.AddDevice("associatedDevice2", opts, newID) + if err != nil { t.Error(err) } } @@ -560,7 +565,7 @@ func Test_pndImplementation_Request(t *testing.T) { transport: &transport, } - _ = pnd.addDevice(deviceWithMockTransport) + _, _ = pnd.addDevice(deviceWithMockTransport) _, err = pnd.Request(tt.args.uuid, tt.args.path) if (err != nil) != tt.wantErr { @@ -644,7 +649,7 @@ func Test_pndImplementation_RequestAll(t *testing.T) { transport: &transport, } - _ = pnd.addDevice(deviceWithMockTransport) + _, _ = pnd.addDevice(deviceWithMockTransport) device, _ := pnd.devices.Get(store.Query{ID: mdid}) if device == nil { @@ -756,7 +761,8 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { t.Error(err) } - if err := pnd.AddDevice("testdevice", opts, defaultSbiID); err != nil { + _, err := pnd.AddDevice("testdevice", opts, defaultSbiID) + if err != nil { t.Error(err) return } @@ -799,7 +805,8 @@ func Test_pndImplementation_GetDevice(t *testing.T) { t.Error(err) return } - if err = pnd.addDevice(d); err != nil { + _, err = pnd.addDevice(d) + if err != nil { t.Error(err) return } @@ -859,7 +866,8 @@ func Test_pndImplementation_GetDeviceByName(t *testing.T) { t.Error(err) return } - if err = pnd.addDevice(d); err != nil { + _, err = pnd.addDevice(d) + if err != nil { t.Error(err) return } @@ -933,11 +941,12 @@ func Test_pndImplementation_Confirm(t *testing.T) { d := mockDevice() tr := d.Transport().(*mocks.Transport) tr.On("Set", mockContext, mock.Anything, mock.Anything).Return(nil) - if err := pnd.addDevice(d); err != nil { + _, err := pnd.addDevice(d) + if err != nil { t.Error(err) return } - _, err := pnd.ChangeOND(d.ID(), ppb.ApiOperation_API_OPERATION_UPDATE, "system/config/hostname", "ceos3000") + _, err = pnd.ChangeOND(d.ID(), ppb.ApiOperation_API_OPERATION_UPDATE, "system/config/hostname", "ceos3000") if err != nil { t.Error(err) return diff --git a/controller/test/integration/nucleusIntegration_test.go b/controller/test/integration/nucleusIntegration_test.go index c7d44567d..b325c8554 100644 --- a/controller/test/integration/nucleusIntegration_test.go +++ b/controller/test/integration/nucleusIntegration_test.go @@ -177,7 +177,8 @@ func TestGnmi_SetValidIntegration(t *testing.T) { t.Error(err) return } - if err := pnd.AddDevice("test", opt, sbi.ID()); err != nil { + _, err = pnd.AddDevice("test", opt, sbi.ID()) + if err != nil { t.Error(err) return } diff --git a/go.mod b/go.mod index 9718a98b6..b53bb1331 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( require ( github.com/c-bata/go-prompt v0.2.6 github.com/mitchellh/go-homedir v1.1.0 + github.com/pterm/pterm v0.12.41 github.com/spf13/pflag v1.0.5 go.mongodb.org/mongo-driver v1.8.4 google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa @@ -35,6 +36,14 @@ require ( require github.com/sethvargo/go-password v0.2.0 +require ( + github.com/atomicgo/cursor v0.0.1 // indirect + github.com/gookit/color v1.5.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect +) + require ( github.com/Microsoft/go-winio v0.5.1 // indirect github.com/Microsoft/hcsshim v0.9.2 // indirect @@ -61,7 +70,7 @@ require ( github.com/magiconair/properties v1.8.5 // indirect github.com/mattn/go-colorable v0.1.7 // indirect github.com/mattn/go-isatty v0.0.12 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-tty v0.0.3 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mitchellh/mapstructure v1.4.2 // indirect @@ -88,7 +97,7 @@ require ( go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect - golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/ini.v1 v1.64.0 // indirect diff --git a/go.sum b/go.sum index edc081bb5..a4c712aba 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,14 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= +github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= +github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= +github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= +github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= +github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= +github.com/MarvinJWendt/testza v0.3.5 h1:g9krITRRlIsF1eO9sUKXtiTw670gZIIk6T08Keeo1nM= +github.com/MarvinJWendt/testza v0.3.5/go.mod h1:ExbTpWmA1z2E9HSskvrNcwApoX4F9bID692s10nuHRY= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= @@ -140,6 +148,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU= +github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -557,6 +567,9 @@ github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pf github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -671,9 +684,14 @@ github.com/klauspost/compress v1.11.9/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.2/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/reedsolomon v1.9.11/go.mod h1:nLvuzNvy1ZDNQW30IuMc2ZWCbiqrJgdLoUS2X8HAUVg= @@ -722,8 +740,9 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= @@ -962,8 +981,19 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= +github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= +github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= +github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= +github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= +github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= +github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= +github.com/pterm/pterm v0.12.41 h1:e2BRfFo1H9nL8GY0S3ImbZqfZ/YimOk9XtkhoobKJVs= +github.com/pterm/pterm v0.12.41/go.mod h1:LW/G4J2A42XlTaPTAGRPvbBfF4UXvHWhC6SN7ueU4jU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -979,6 +1009,8 @@ github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI= github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -1092,6 +1124,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= @@ -1423,14 +1457,18 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -- GitLab