diff --git a/api/apiIntegration_test.go b/api/apiIntegration_test.go index 9839da725ee9a573f3afc768654ea40e126ddd7f..5f1759243e209c2b64caad0b4bd921b7867fd86d 100644 --- a/api/apiIntegration_test.go +++ b/api/apiIntegration_test.go @@ -1,86 +1,15 @@ package api import ( - "os" "testing" + "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" - "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto" + "github.com/google/uuid" guuid "github.com/google/uuid" - gpb "github.com/openconfig/gnmi/proto/gnmi" - log "github.com/sirupsen/logrus" "github.com/spf13/viper" - pb "google.golang.org/protobuf/proto" ) -const unreachable = "203.0.113.10:6030" -const testPath = "/system/config/hostname" - -var testAddress = "141.100.70.170:6030" -var testAPIEndpoint = "gosdn-latest.apps.ocp.fbi.h-da.de" -var testUsername = "admin" -var testPassword = "arista" -var opt *tpb.TransportOption -var gnmiMessages map[string]pb.Message - -func TestMain(m *testing.M) { - testSetupIntegration() - os.Exit(m.Run()) -} - -func testSetupIntegration() { - if os.Getenv("GOSDN_LOG") == "nolog" { - log.SetLevel(log.PanicLevel) - } - - addr := os.Getenv("GOSDN_TEST_ENDPOINT") - if addr != "" { - testAddress = addr - log.Infof("GOSDN_TEST_ENDPOINT set to %v", testAddress) - } - api := os.Getenv("GOSDN_TEST_API_ENDPOINT") - if api != "" { - testAPIEndpoint = api - log.Infof("GOSDN_TEST_API_ENDPOINT set to %v", testAPIEndpoint) - } - u := os.Getenv("GOSDN_TEST_USER") - if u != "" { - testUsername = u - log.Infof("GOSDN_TEST_USER set to %v", testUsername) - } - p := os.Getenv("GOSDN_TEST_PASSWORD") - if p != "" { - testPassword = p - log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword) - } - - gnmiMessages = map[string]pb.Message{ - "../test/proto/cap-resp-arista-ceos": &gpb.CapabilityResponse{}, - "../test/proto/req-full-node": &gpb.GetRequest{}, - "../test/proto/req-full-node-arista-ceos": &gpb.GetRequest{}, - "../test/proto/req-interfaces-arista-ceos": &gpb.GetRequest{}, - "../test/proto/req-interfaces-interface-arista-ceos": &gpb.GetRequest{}, - "../test/proto/req-interfaces-wildcard": &gpb.GetRequest{}, - "../test/proto/resp-full-node": &gpb.GetResponse{}, - "../test/proto/resp-full-node-arista-ceos": &gpb.GetResponse{}, - "../test/proto/resp-interfaces-arista-ceos": &gpb.GetResponse{}, - "../test/proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{}, - "../test/proto/resp-interfaces-wildcard": &gpb.GetResponse{}, - "../test/proto/resp-set-system-config-hostname": &gpb.SetResponse{}, - } - for k, v := range gnmiMessages { - if err := proto.Read(k, v); err != nil { - log.Fatalf("error parsing %v: %v", k, err) - } - } - - opt = &tpb.TransportOption{ - Address: testAddress, - Username: testUsername, - Password: testPassword, - } -} - func TestApiIntegration(t *testing.T) { // TDOO: Remove once openshift grpc support is available t.Skip("skipped due to openshift limitations") @@ -110,21 +39,31 @@ func TestApiIntegration(t *testing.T) { cliPnd := viper.GetString("CLI_PND") cliSbi := viper.GetString("CLI_SBI") - if _, err := AddDevice( + cliPndUUID, err := uuid.Parse(cliPnd) + clisbiUUID, err := uuid.Parse(cliSbi) + + opt := &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } + + if _, err := addDevice( testAPIEndpoint, - testUsername, - testPassword, - cliSbi, - cliPnd, - testAddress, "test-device", + opt, + clisbiUUID, + cliPndUUID, ); (err != nil) != tt.wantErr { t.Errorf("gosdn cli add-device error = %v, wantErr %v", err, tt.wantErr) return } did := viper.GetString("LAST_DEVICE_UUID") - _, err := GetDevice( + _, err = getDevice( testAPIEndpoint, cliPnd, testPath, @@ -135,7 +74,7 @@ func TestApiIntegration(t *testing.T) { return } - _, err = GetDevice( + _, err = getDevice( testAPIEndpoint, cliPnd, "", @@ -147,19 +86,20 @@ func TestApiIntegration(t *testing.T) { } hostname := guuid.New().String() - _, err = Update( + _, err = changeRequest( testAPIEndpoint, did, cliPnd, testPath, hostname, + pnd.ApiOperation_UPDATE, ) if (err != nil) != tt.wantErr { t.Errorf("gosdn cli set error = %v, wantErr %v", err, tt.wantErr) return } - resp, err := GetDevice(testAddress, testUsername, testPassword, testPath) + resp, err := getDevice(testAddress, testUsername, testPassword, testPath) if err != nil { if !tt.wantErr { t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) diff --git a/api/go.mod b/api/go.mod index e3c75264d71e73e5a04413b5717b77667865118c..551e38da5afd80810c840d6a10e7f45a48936844 100644 --- a/api/go.mod +++ b/api/go.mod @@ -3,8 +3,9 @@ module code.fbi.h-da.de/cocsn/gosdn/api go 1.16 require ( - code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609143151-4dabee5ab99a + code.fbi.h-da.de/cocsn/api/go v0.0.0-20210617162200-4b2e8d3035c7 code.fbi.h-da.de/cocsn/gosdn v0.0.3-0.20210609130706-9cca50b3d195 + code.fbi.h-da.de/cocsn/gosdn/interfaces v0.0.0-20210616220833-9f9d4a562783 code.fbi.h-da.de/cocsn/yang-models v0.0.7 github.com/google/uuid v1.2.0 github.com/openconfig/gnmi v0.0.0-20210527163611-d3a3e30199da diff --git a/api/go.sum b/api/go.sum index 697c8302ec0d6fb98a2900b54d8c6ea3c9d4bdce..834132dd2ce8af8a12def42d14cdfa0454864e5e 100644 --- a/api/go.sum +++ b/api/go.sum @@ -22,10 +22,13 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609120033-1ef56612bd26/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= -code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609143151-4dabee5ab99a h1:C2tdh2A4RckZJXUymtF2ec8hE8mTkhn7EQJShv+i/Jk= -code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609143151-4dabee5ab99a/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210617162200-4b2e8d3035c7 h1:pNZ+M0wzJocRP3HXx9NMw042/mvTRrobRspqG3gNTfw= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210617162200-4b2e8d3035c7/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= code.fbi.h-da.de/cocsn/gosdn v0.0.3-0.20210609130706-9cca50b3d195 h1:PKIXDaEtaqmGviMAx4RWK0/bgPgkCNcxKO+XC85lnIg= code.fbi.h-da.de/cocsn/gosdn v0.0.3-0.20210609130706-9cca50b3d195/go.mod h1:EK0GUnwNB+qMMjSJxGzLpfDw+KsUHS2LZkdzshldm4Q= +code.fbi.h-da.de/cocsn/gosdn/interfaces v0.0.0-20210616220833-9f9d4a562783 h1:7ewcRJE+p8p7nJEB5qiGwREcV60UlWB42aXEtaywJuE= +code.fbi.h-da.de/cocsn/gosdn/interfaces v0.0.0-20210616220833-9f9d4a562783/go.mod h1:tFBnAuqTB/1GeNvVhKt+lzZ9KLQE+ri2oEEd4YjVHJw= code.fbi.h-da.de/cocsn/yang-models v0.0.7 h1:3TOo8J+EdAJKeq4o3aaNWZRhjSwguIS8wciW1U9PkSk= code.fbi.h-da.de/cocsn/yang-models v0.0.7/go.mod h1:M+2HinfhTT8nA8qvn2cpWNlOtuiizTNDWA3yfy72K/g= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= diff --git a/api/grpc.go b/api/grpc.go index 6a475df699387bd5e6b78471c8775cecb7b83075..f820f4ccfdae3188f30cd06f7446c11c4dadcb9e 100644 --- a/api/grpc.go +++ b/api/grpc.go @@ -5,14 +5,15 @@ import ( "errors" "time" + pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/client" + "github.com/google/uuid" log "github.com/sirupsen/logrus" "github.com/spf13/viper" - pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" "google.golang.org/grpc" ) @@ -107,8 +108,8 @@ func GetPnd(addr string, args ...string) (*pb.GetResponse, error) { return coreClient.Get(ctx, req) } -// GetChanges requests all pending and unconfirmed changes from the controller -func GetChanges(addr, pnd string) (*ppb.GetResponse, error) { +// getChanges requests all pending and unconfirmed changes from the controller +func getChanges(addr, pnd string) (*ppb.GetResponse, error) { ctx := context.Background() client, err := nbi.PndClient(addr, dialOptions...) if err != nil { @@ -126,9 +127,9 @@ func GetChanges(addr, pnd string) (*ppb.GetResponse, error) { return client.Get(ctx, req) } -// Commit sends a commit request for one or multiple changes to the +// commit sends a commit request for one or multiple changes to the // controller. -func Commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { +func commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { changes := make([]*ppb.SetChange, len(cuids)) for i, arg := range cuids { changes[i] = &ppb.SetChange{ @@ -139,9 +140,9 @@ func Commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { return commitConfirm(addr, pnd, changes) } -// Confirm sends a confirm request for one or multiple changes to the +// confirm sends a confirm request for one or multiple changes to the // controller -func Confirm(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { +func confirm(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { changes := make([]*ppb.SetChange, len(cuids)) for i, arg := range cuids { changes[i] = &ppb.SetChange{ @@ -166,9 +167,9 @@ func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetResponse return client.Set(ctx, req) } -// AddDevice adds a new device to the controller. The device name is optional. +// addDevice adds a new device to the controller. The device name is optional. // If no name is provided a name will be generated upon device creation. -func AddDevice(addr, username, password, sbi, pnd, deviceAddress, deviceName string) (*ppb.SetResponse, error) { +func addDevice(addr, deviceName string, opt *tpb.TransportOption, sid, pid uuid.UUID) (*ppb.SetResponse, error) { pndClient, err := nbi.PndClient(addr, dialOptions...) if err != nil { return nil, err @@ -178,31 +179,29 @@ func AddDevice(addr, username, password, sbi, pnd, deviceAddress, deviceName str Timestamp: time.Now().UnixNano(), Ond: []*ppb.SetOnd{ { - Address: deviceAddress, + Address: opt.GetAddress(), Sbi: &spb.SouthboundInterface{ - Id: sbi, - }, - DeviceName: deviceName, - TransportOption: &tpb.TransportOption{ - Address: addr, - Username: username, - Password: password, - TransportOption: &tpb.TransportOption_GnmiTransportOption{ - GnmiTransportOption: &tpb.GnmiTransportOption{}, - }, + Id: sid.String(), }, + DeviceName: deviceName, + TransportOption: opt, }, }, - Pid: pnd, + Pid: pid.String(), + } + if opt.Csbi { + req.Ond[0].Sbi.Id = uuid.Nil.String() + req.Ond[0].Sbi.Type = spb.Type_CONTAINERISED + req.Ond[0].TransportOption.Csbi = true } ctx := context.Background() return pndClient.Set(ctx, req) } -// GetDevice requests one or multiple devices belonging to a given +// getDevice requests one or multiple devices belonging to a given // PrincipalNetworkDomain from the controller. If no device identifier // is provided, all devices are requested. -func GetDevice(addr, pid, path string, did ...string) (*ppb.GetResponse, error) { +func getDevice(addr, pid string, did ...string) (*ppb.GetResponse, error) { pndClient, err := nbi.PndClient(addr, dialOptions...) if err != nil { return nil, err @@ -227,37 +226,52 @@ func GetDevice(addr, pid, path string, did ...string) (*ppb.GetResponse, error) return pndClient.Get(ctx, req) } -// Update creates a ChangeRequest to update the given path with the given value -// at the given OND on the controller. -func Update(addr, did, pid, path, value string) (*ppb.SetResponse, error) { - req := &ppb.ChangeRequest{ - Id: did, - Path: path, - Value: value, - ApiOp: ppb.ApiOperation_UPDATE, +func getPath(addr, pid, did, path string) (*ppb.GetResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err } - return sendChangeRequest(addr, pid, req) + + req := &ppb.GetRequest{ + Timestamp: time.Now().UnixNano(), + Request: &ppb.GetRequest_Path{ + Path: &ppb.GetPath{ + Did: did, + Path: path, + }, + }, + Pid: pid, + } + ctx := context.Background() + return pndClient.Get(ctx, req) } -// Replace creates a ChangeRequest to replace the given path with the given value -// at the given OND on the controller. -func Replace(addr, did, pid, path, value string) (*ppb.SetResponse, error) { - req := &ppb.ChangeRequest{ - Id: did, - Path: path, - Value: value, - ApiOp: ppb.ApiOperation_REPLACE, +func deleteDevice(addr, pid, did string) (*ppb.DeleteResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err } - return sendChangeRequest(addr, pid, req) + + req := &ppb.DeleteRequest{ + Timestamp: time.Now().UnixNano(), + Type: ppb.DeleteRequest_OND, + Uuid: did, + Pid: pid, + } + ctx := context.Background() + return pndClient.Delete(ctx, req) } -// Delete creates a ChangeRequest to delete the given path node -// at the given OND on the controller. -func Delete(addr, did, pid, path string) (*ppb.SetResponse, error) { +// change creates a ChangeRequest for the specified OND. ApiOperations are +// used to specify the type of the change (update, replace, delete as specified +// in https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#34-modifying-state) +// For delete operations the value field needs to contain an empty string. +func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetResponse, error) { req := &ppb.ChangeRequest{ Id: did, Path: path, - ApiOp: ppb.ApiOperation_DELETE, + Value: value, + ApiOp: op, } return sendChangeRequest(addr, pid, req) } diff --git a/api/grpc_test.go b/api/grpc_test.go index 549652a2ee0afd4939159ce37fa5cb39d2ecf72f..76bd952b3b631b1d5bcb895c5f00f47d5037599d 100644 --- a/api/grpc_test.go +++ b/api/grpc_test.go @@ -1,96 +1,18 @@ package api import ( - "context" - "net" "testing" - pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" - "code.fbi.h-da.de/cocsn/gosdn/mocks" - nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/server" + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" "code.fbi.h-da.de/cocsn/gosdn/nucleus" - "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" - "github.com/google/uuid" log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/mock" - "google.golang.org/grpc" - "google.golang.org/grpc/test/bufconn" + "github.com/spf13/viper" ) -/* -Based on this StackOverflow answer: https://stackoverflow.com/a/52080545/4378176 -*/ - -const bufSize = 1024 * 1024 -const bufnet = "bufnet" -const pndID = "2043519e-46d1-4963-9a8e-d99007e104b8" -const changeID = "0992d600-f7d4-4906-9559-409b04d59a5f" -const sbiID = "f6fd4b35-f039-4111-9156-5e4501bb8a5a" -const ondID = "7e0ed8cc-ebf5-46fa-9794-741494914883" - -var pndStore *nucleus.PndStore -var lis *bufconn.Listener - -func init() { - dialOptions = []grpc.DialOption{ - grpc.WithContextDialer(bufDialer), - grpc.WithInsecure(), - } - lis = bufconn.Listen(bufSize) - s := grpc.NewServer() - pndStore = nucleus.NewPndStore() - - pndUUID, err := uuid.Parse(pndID) - if err != nil { - log.Fatal(err) - } - - changeUUID, err := uuid.Parse(changeID) - if err != nil { - log.Fatal(err) - } - - deviceUUID, err := uuid.Parse(ondID) - if err != nil { - log.Fatal(err) - } - - mockPnd := mocks.PrincipalNetworkDomain{} - mockPnd.On("ID").Return(pndUUID) - mockPnd.On("GetName").Return("test") - mockPnd.On("GetDescription").Return("test") - mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID}) - mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID}) - mockPnd.On("GetChange", mock.Anything).Return(&nucleus.Change{}, nil) - mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{ - UUID: deviceUUID, - GoStruct: &openconfig.Device{}, - }, nil) - mockPnd.On("Commit", mock.Anything).Return(nil) - mockPnd.On("Confirm", mock.Anything).Return(nil) - mockPnd.On("ChangeOND", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - if err := pndStore.Add(&mockPnd); err != nil { - log.Fatal(err) - } - northbound := nbi.NewNBI(pndStore) - pb.RegisterCoreServer(s, northbound.Core) - ppb.RegisterPndServer(s, northbound.Pnd) - go func() { - if err := s.Serve(lis); err != nil { - log.Fatalf("Server exited with error: %v", err) - } - }() -} - -func bufDialer(context.Context, string) (net.Conn, error) { - return lis.Dial() -} - func Test_Init(t *testing.T) { + viper.SetConfigFile("./api_test.toml") if err := Init(bufnet); err != nil { t.Error(err) } @@ -128,7 +50,7 @@ func Test_GetPnd(t *testing.T) { } func Test_GetChanges(t *testing.T) { - resp, err := GetChanges(bufnet, pndID) + resp, err := getChanges(bufnet, pndID) if err != nil { t.Error(err) return @@ -137,14 +59,14 @@ func Test_GetChanges(t *testing.T) { } func Test_CommitConfirm(t *testing.T) { - resp, err := Commit(bufnet, pndID, changeID) + resp, err := commit(bufnet, pndID, changeID) if err != nil { t.Error(err) return } log.Info(resp) - resp, err = Confirm(bufnet, pndID, changeID) + resp, err = confirm(bufnet, pndID, changeID) if err != nil { t.Error(err) return @@ -154,7 +76,15 @@ func Test_CommitConfirm(t *testing.T) { } func Test_AddDevice(t *testing.T) { - resp, err := AddDevice(bufnet, "test", "test", sbiID, pndID, "test", "test") + opt := &tpb.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } + resp, err := addDevice(bufnet, "test", opt, sbiUUID, pndUUID) if err != nil { t.Error(err) return @@ -163,7 +93,7 @@ func Test_AddDevice(t *testing.T) { } func Test_GetDevice(t *testing.T) { - resp, err := GetDevice(bufnet, pndID, "", ondID) + resp, err := getDevice(bufnet, pndID, ondID) if err != nil { t.Error(err) return @@ -175,7 +105,7 @@ func Test_GetDevice(t *testing.T) { } func Test_Update(t *testing.T) { - resp, err := Update(bufnet, ondID, pndID, "", "") + resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_UPDATE) if err != nil { t.Error(err) return @@ -184,7 +114,7 @@ func Test_Update(t *testing.T) { } func Test_Replace(t *testing.T) { - resp, err := Replace(bufnet, ondID, pndID, "", "") + resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_REPLACE) if err != nil { t.Error(err) return @@ -193,7 +123,7 @@ func Test_Replace(t *testing.T) { } func Test_Delete(t *testing.T) { - resp, err := Delete(bufnet, ondID, pndID, "") + resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_DELETE) if err != nil { t.Error(err) return diff --git a/api/initialise_test.go b/api/initialise_test.go new file mode 100644 index 0000000000000000000000000000000000000000..8271cbf8b9e9b92a12a901e8138a4b84fd026d0d --- /dev/null +++ b/api/initialise_test.go @@ -0,0 +1,172 @@ +package api + +import ( + "context" + "net" + "os" + "testing" + + cpb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" + ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" + "code.fbi.h-da.de/cocsn/gosdn/mocks" + nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/server" + "code.fbi.h-da.de/cocsn/gosdn/nucleus" + "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto" + "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" + + gpb "github.com/openconfig/gnmi/proto/gnmi" + pb "google.golang.org/protobuf/proto" +) + +/* +Based on this StackOverflow answer: https://stackoverflow.com/a/52080545/4378176 +*/ + +const bufSize = 1024 * 1024 +const bufnet = "bufnet" +const pndID = "2043519e-46d1-4963-9a8e-d99007e104b8" +const changeID = "0992d600-f7d4-4906-9559-409b04d59a5f" +const sbiID = "f6fd4b35-f039-4111-9156-5e4501bb8a5a" +const ondID = "7e0ed8cc-ebf5-46fa-9794-741494914883" + +var pndStore *nucleus.PndStore +var lis *bufconn.Listener +var pndUUID uuid.UUID +var sbiUUID uuid.UUID + +func bootstrapUnitTest() { + dialOptions = []grpc.DialOption{ + grpc.WithContextDialer(bufDialer), + grpc.WithInsecure(), + } + lis = bufconn.Listen(bufSize) + s := grpc.NewServer() + pndStore = nucleus.NewPndStore() + + changeUUID, err := uuid.Parse(changeID) + if err != nil { + log.Fatal(err) + } + + pndUUID, err = uuid.Parse(pndID) + if err != nil { + log.Fatal(err) + } + + sbiUUID, err = uuid.Parse(sbiID) + if err != nil { + log.Fatal(err) + } + + deviceUUID, err := uuid.Parse(ondID) + if err != nil { + log.Fatal(err) + } + + mockPnd := mocks.PrincipalNetworkDomain{} + mockPnd.On("ID").Return(pndUUID) + mockPnd.On("GetName").Return("test") + mockPnd.On("GetDescription").Return("test") + mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID}) + mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID}) + mockPnd.On("GetChange", mock.Anything).Return(&nucleus.Change{}, nil) + mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{ + UUID: deviceUUID, + GoStruct: &openconfig.Device{}, + }, nil) + mockPnd.On("Commit", mock.Anything).Return(nil) + mockPnd.On("Confirm", mock.Anything).Return(nil) + mockPnd.On("ChangeOND", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + + if err := pndStore.Add(&mockPnd); err != nil { + log.Fatal(err) + } + northbound := nbi.NewNBI(pndStore) + cpb.RegisterCoreServer(s, northbound.Core) + ppb.RegisterPndServer(s, northbound.Pnd) + go func() { + if err := s.Serve(lis); err != nil { + log.Fatalf("Server exited with error: %v", err) + } + }() +} + +func bufDialer(context.Context, string) (net.Conn, error) { + return lis.Dial() +} + +const unreachable = "203.0.113.10:6030" +const testPath = "/system/config/hostname" + +var testAddress = "141.100.70.170:6030" +var testAPIEndpoint = "gosdn-latest.apps.ocp.fbi.h-da.de" +var testUsername = "admin" +var testPassword = "arista" +var opt *tpb.TransportOption +var gnmiMessages map[string]pb.Message + +func TestMain(m *testing.M) { + bootstrapUnitTest() + bootstrapIntegrationTest() + os.Exit(m.Run()) +} + +func bootstrapIntegrationTest() { + if os.Getenv("GOSDN_LOG") == "nolog" { + log.SetLevel(log.PanicLevel) + } + + addr := os.Getenv("GOSDN_TEST_ENDPOINT") + if addr != "" { + testAddress = addr + log.Infof("GOSDN_TEST_ENDPOINT set to %v", testAddress) + } + api := os.Getenv("GOSDN_TEST_API_ENDPOINT") + if api != "" { + testAPIEndpoint = api + log.Infof("GOSDN_TEST_API_ENDPOINT set to %v", testAPIEndpoint) + } + u := os.Getenv("GOSDN_TEST_USER") + if u != "" { + testUsername = u + log.Infof("GOSDN_TEST_USER set to %v", testUsername) + } + p := os.Getenv("GOSDN_TEST_PASSWORD") + if p != "" { + testPassword = p + log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword) + } + + gnmiMessages = map[string]pb.Message{ + "../test/proto/cap-resp-arista-ceos": &gpb.CapabilityResponse{}, + "../test/proto/req-full-node": &gpb.GetRequest{}, + "../test/proto/req-full-node-arista-ceos": &gpb.GetRequest{}, + "../test/proto/req-interfaces-arista-ceos": &gpb.GetRequest{}, + "../test/proto/req-interfaces-interface-arista-ceos": &gpb.GetRequest{}, + "../test/proto/req-interfaces-wildcard": &gpb.GetRequest{}, + "../test/proto/resp-full-node": &gpb.GetResponse{}, + "../test/proto/resp-full-node-arista-ceos": &gpb.GetResponse{}, + "../test/proto/resp-interfaces-arista-ceos": &gpb.GetResponse{}, + "../test/proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{}, + "../test/proto/resp-interfaces-wildcard": &gpb.GetResponse{}, + "../test/proto/resp-set-system-config-hostname": &gpb.SetResponse{}, + } + for k, v := range gnmiMessages { + if err := proto.Read(k, v); err != nil { + log.Fatalf("error parsing %v: %v", k, err) + } + } + + opt = &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + } +} diff --git a/api/pnd.go b/api/pnd.go new file mode 100644 index 0000000000000000000000000000000000000000..86d2b09713152d43920912fcf9b3b2ea346f7019 --- /dev/null +++ b/api/pnd.go @@ -0,0 +1,180 @@ +package api + +import ( + ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/change" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/device" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/store" + "code.fbi.h-da.de/cocsn/gosdn/nucleus/errors" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +type PrincipalNetworkDomainAdapter struct { + id uuid.UUID + endpoint string +} + +func NewAdapter(id, endpoint string) (networkdomain.NetworkDomain, error) { + pid, err := uuid.Parse(id) + if err != nil { + return nil, err + } + return &PrincipalNetworkDomainAdapter{ + id: pid, + endpoint: endpoint, + }, nil +} + +func (p *PrincipalNetworkDomainAdapter) Destroy() error { + return &errors.ErrNotYetImplemented{} +} + +func (p *PrincipalNetworkDomainAdapter) AddSbi(s southbound.SouthboundInterface) error { + return &errors.ErrNotYetImplemented{} +} + +func (p *PrincipalNetworkDomainAdapter) RemoveSbi(uuid.UUID) error { + return &errors.ErrNotYetImplemented{} +} + +// AddDevice adds a new device to the controller. The device name is optional. +// If no name is provided a name will be generated upon device creation. +func (p *PrincipalNetworkDomainAdapter) AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error { + resp, err := addDevice(p.endpoint, name, opts, sid, p.ID()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +// GetDevice requests one or multiple devices belonging to a given +// PrincipalNetworkDomain from the controller. If no device identifier +// is provided, all devices are requested. +func (p *PrincipalNetworkDomainAdapter) GetDevice(identifier string) (device.Device, error) { + resp, err := getDevice(p.endpoint, p.id.String(), identifier) + if err != nil { + return nil, err + } + // TODO: Parse into device.Device + log.Info(resp) + return nil, nil +} + +func (p *PrincipalNetworkDomainAdapter) RemoveDevice(did uuid.UUID) error { + resp, err := deleteDevice(p.endpoint, p.id.String(), did.String()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +func (p *PrincipalNetworkDomainAdapter) Devices() []uuid.UUID { + return nil +} + +func (p *PrincipalNetworkDomainAdapter) ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error { + var v string + if len(value) != 0 { + v = value[0] + } + resp, err := changeRequest(p.endpoint, uuid.String(), p.id.String(), path, v, operation) + if err != nil { + return err + } + log.Info(resp) + return err +} + +func (p *PrincipalNetworkDomainAdapter) Request(did uuid.UUID, path string) error { + resp, err := getPath(p.endpoint, p.id.String(), did.String(), path) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +func (p *PrincipalNetworkDomainAdapter) RequestAll(string) error { + return &errors.ErrNotYetImplemented{} +} + +func (p *PrincipalNetworkDomainAdapter) GetName() string { + return "" +} + +func (p *PrincipalNetworkDomainAdapter) GetDescription() string { + return "" +} + +func (p *PrincipalNetworkDomainAdapter) MarshalDevice(string) (string, error) { + return "", &errors.ErrNotYetImplemented{} +} + +func (p *PrincipalNetworkDomainAdapter) ContainsDevice(uuid.UUID) bool { + return false +} + +func (p *PrincipalNetworkDomainAdapter) GetSBIs() store.Store { + return nil +} + +func (p *PrincipalNetworkDomainAdapter) ID() uuid.UUID { + return p.id +} + +func (p *PrincipalNetworkDomainAdapter) PendingChanges() []uuid.UUID { + resp, err := getChanges(p.endpoint, p.id.String()) + if err != nil { + log.Error(err) + return nil + } + return filterChanges(ppb.Change_PENDING, resp) +} + +func (p *PrincipalNetworkDomainAdapter) CommittedChanges() []uuid.UUID { + resp, err := getChanges(p.endpoint, p.id.String()) + if err != nil { + log.Error(err) + return nil + } + return filterChanges(ppb.Change_COMMITTED, resp) +} + +func (p *PrincipalNetworkDomainAdapter) GetChange(uuid.UUID, ...int) (change.Change, error) { + return nil, &errors.ErrNotYetImplemented{} +} + +func (p *PrincipalNetworkDomainAdapter) Commit(cuid uuid.UUID) error { + resp, err := commit(p.endpoint, p.id.String(), cuid.String()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +func (p *PrincipalNetworkDomainAdapter) Confirm(cuid uuid.UUID) error { + resp, err := confirm(p.endpoint, p.id.String(), cuid.String()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +func filterChanges(state ppb.Change_State, resp *ppb.GetResponse) []uuid.UUID { + changes := make([]uuid.UUID, 0) + for _, ch := range resp.Change { + if ch.State == ppb.Change_PENDING { + id, _ := uuid.Parse(ch.Id) + changes = append(changes, id) + } + } + return changes +} diff --git a/api/pnd_test.go b/api/pnd_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5f6238157715197eadb7e3b71aa696c2cc06cac3 --- /dev/null +++ b/api/pnd_test.go @@ -0,0 +1,665 @@ +package api + +import ( + "reflect" + "testing" + + ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/change" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/device" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound" + "code.fbi.h-da.de/cocsn/gosdn/interfaces/store" + "github.com/google/uuid" +) + +func TestNewAdapter(t *testing.T) { + type args struct { + id string + endpoint string + } + tests := []struct { + name string + args args + want networkdomain.NetworkDomain + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewAdapter(tt.args.id, tt.args.endpoint) + if (err != nil) != tt.wantErr { + t.Errorf("NewAdapter() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewAdapter() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Destroy(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Destroy(); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Destroy() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_AddSbi(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + s southbound.SouthboundInterface + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.AddSbi(tt.args.s); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.AddSbi() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_RemoveSbi(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.RemoveSbi(tt.args.in0); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.RemoveSbi() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_AddDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + name string + opts *tpb.TransportOption + sid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.AddDevice(tt.args.name, tt.args.opts, tt.args.sid); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.AddDevice() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + identifier string + } + tests := []struct { + name string + fields fields + args args + want device.Device + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + got, err := p.GetDevice(tt.args.identifier) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.GetDevice() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.GetDevice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_RemoveDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + did uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.RemoveDevice(tt.args.did); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.RemoveDevice() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Devices(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.Devices(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.Devices() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_ChangeOND(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + uuid uuid.UUID + operation ppb.ApiOperation + path string + value []string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.ChangeOND(tt.args.uuid, tt.args.operation, tt.args.path, tt.args.value...); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.ChangeOND() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Request(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + did uuid.UUID + path string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Request(tt.args.did, tt.args.path); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Request() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_RequestAll(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.RequestAll(tt.args.in0); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.RequestAll() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetName(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.GetName(); got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.GetName() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetDescription(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.GetDescription(); got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.GetDescription() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_MarshalDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 string + } + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + got, err := p.MarshalDevice(tt.args.in0) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.MarshalDevice() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.MarshalDevice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_ContainsDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.ContainsDevice(tt.args.in0); got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.ContainsDevice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetSBIs(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want store.Store + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.GetSBIs(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.GetSBIs() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_ID(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.ID(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.ID() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_PendingChanges(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.PendingChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.PendingChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_CommittedChanges(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.CommittedChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.CommittedChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetChange(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 uuid.UUID + in1 []int + } + tests := []struct { + name string + fields fields + args args + want change.Change + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + got, err := p.GetChange(tt.args.in0, tt.args.in1...) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.GetChange() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.GetChange() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Commit(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + cuid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Commit(tt.args.cuid); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Commit() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Confirm(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + cuid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Confirm(tt.args.cuid); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Confirm() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_filterChanges(t *testing.T) { + type args struct { + state ppb.Change_State + resp *ppb.GetResponse + } + tests := []struct { + name string + args args + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := filterChanges(tt.args.state, tt.args.resp); !reflect.DeepEqual(got, tt.want) { + t.Errorf("filterChanges() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index 60e1819514a94ca9fc97f316e0e7dcff6ad31380..c76110a4e4f115879d5ce2314e609c07945a3fdf 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,8 @@ module code.fbi.h-da.de/cocsn/gosdn go 1.16 require ( - code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609143151-4dabee5ab99a + code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202 + code.fbi.h-da.de/cocsn/gosdn/interfaces v0.0.0-20210616221000-dfaf18a8b4b0 code.fbi.h-da.de/cocsn/yang-models v0.0.7 github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a github.com/docker/docker v20.10.6+incompatible diff --git a/go.sum b/go.sum index 22b65647e51ec81fcc37ff1f8df5a26f412b6d70..a98d01739b3af6d3413ce9f50f908096de12a61f 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,10 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609143151-4dabee5ab99a h1:C2tdh2A4RckZJXUymtF2ec8hE8mTkhn7EQJShv+i/Jk= -code.fbi.h-da.de/cocsn/api/go v0.0.0-20210609143151-4dabee5ab99a/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202 h1:SiRiAm0cXUFkwNBJZdv7twdj6V7Bt6jRFMiMO170CkQ= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= +code.fbi.h-da.de/cocsn/gosdn/interfaces v0.0.0-20210616221000-dfaf18a8b4b0 h1:HW0TKYIO5qnxxaZ3KAAufoT/wv89t+eqZwKGHBo824g= +code.fbi.h-da.de/cocsn/gosdn/interfaces v0.0.0-20210616221000-dfaf18a8b4b0/go.mod h1:tFBnAuqTB/1GeNvVhKt+lzZ9KLQE+ri2oEEd4YjVHJw= code.fbi.h-da.de/cocsn/yang-models v0.0.7 h1:3TOo8J+EdAJKeq4o3aaNWZRhjSwguIS8wciW1U9PkSk= code.fbi.h-da.de/cocsn/yang-models v0.0.7/go.mod h1:M+2HinfhTT8nA8qvn2cpWNlOtuiizTNDWA3yfy72K/g= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= diff --git a/interfaces/go.mod b/interfaces/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..aa90ec51d9cce806be53424a4974cba0fefd4f3e --- /dev/null +++ b/interfaces/go.mod @@ -0,0 +1,12 @@ +module code.fbi.h-da.de/cocsn/gosdn/interfaces + +go 1.16 + +require ( + code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202 + github.com/google/uuid v1.1.2 + github.com/openconfig/gnmi v0.0.0-20210430192044-ab96b57c5113 + github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea + github.com/openconfig/ygot v0.6.0 + google.golang.org/protobuf v1.26.0 +) diff --git a/interfaces/go.sum b/interfaces/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..1b331011787ba6075feaf77f083a7d88b43e8ef5 --- /dev/null +++ b/interfaces/go.sum @@ -0,0 +1,117 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202 h1:SiRiAm0cXUFkwNBJZdv7twdj6V7Bt6jRFMiMO170CkQ= +code.fbi.h-da.de/cocsn/api/go v0.0.0-20210616091959-ec840cb65202/go.mod h1:2+rnE92IyXLbiy3/92EM7JrtsY5tXPAKX90QmsT2+m0= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/protobuf v3.14.0+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/openconfig/gnmi v0.0.0-20210430192044-ab96b57c5113 h1:gHZS9U5wmDYeS8vPu4eEXbWHAVwayPwJ/Ze5RGYGXLw= +github.com/openconfig/gnmi v0.0.0-20210430192044-ab96b57c5113/go.mod h1:H/20NXlnWbCPFC593nxpiKJ+OU//7mW7s7Qk7uVdg3Q= +github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea h1:5MyIz4bN4vpH6aHDN339bkWXAjTkhg1ZKMhR4aIi5Rk= +github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU= +github.com/openconfig/ygot v0.6.0 h1:kJJFPBrczC6TDnz/HMlFTJEdW2CuyUftV13XveIukg0= +github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d h1:HV9Z9qMhQEsdlvxNFELgQ11RkMzO3CMkjEySjCtuLes= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.1/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=