Skip to content

Commit

Permalink
Resell V2 - add cross-region subnets List method
Browse files Browse the repository at this point in the history
Add crossregionsubnets List method and ListOpts structure.
Provide tests and doc example.
Also this commit fixes fields order for Get method fixtures.
  • Loading branch information
kolsean committed Jan 8, 2019
1 parent ee5acdd commit 1db6d84
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 8 deletions.
10 changes: 10 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,15 @@ Example of getting a single cross-region subnet referenced by its id
log.Fatal(err)
}
fmt.Println(crossRegionSubnet)
Example of getting all cross-region subnets
allCrossRegionSubnets, _, err := crossregionsubnets.List(ctx, resellClient, crossregionsubnets.ListOpts{})
if err != nil {
log.Fatal(err)
}
for _, crossRegionSubnet := range allCrossRegionSubnets {
fmt.Println(crossRegionSubnet)
}
*/
package crossregionsubnets
32 changes: 32 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,35 @@ func Get(ctx context.Context, client *selvpcclient.ServiceClient, id string) (*C

return result.CrossRegionSubnet, responseResult, nil
}

// List gets a list of cross-region subnets in the current domain.
func List(ctx context.Context, client *selvpcclient.ServiceClient, opts ListOpts) ([]*CrossRegionSubnet, *selvpcclient.ResponseResult, error) {
url := strings.Join([]string{client.Endpoint, resourceURL}, "/")

queryParams, err := selvpcclient.BuildQueryParameters(opts)
if err != nil {
return nil, nil, err
}
if queryParams != "" {
url = strings.Join([]string{url, queryParams}, "?")
}

responseResult, err := client.DoRequest(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}
if responseResult.Err != nil {
return nil, responseResult, responseResult.Err
}

// Extract cross-region subnets from the response body.
var result struct {
CrossRegionSubnets []*CrossRegionSubnet `json:"cross_region_subnets"`
}
err = responseResult.ExtractResult(&result)
if err != nil {
return nil, responseResult, err
}

return result.CrossRegionSubnets, responseResult, nil
}
6 changes: 6 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/requests_opts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package crossregionsubnets

// ListOpts represents options for the List request.
type ListOpts struct {
Detailed bool `param:"detailed"`
}
124 changes: 116 additions & 8 deletions selvpcclient/resell/v2/crossregionsubnets/testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,42 +66,150 @@ var TestGetCrossRegionSubnetResponse = &crossregionsubnets.CrossRegionSubnet{
Status: "ACTIVE",
Servers: []servers.Server{
{
Status: "ACTIVE",
Updated: crossregionSubnetServerTimeStamp,
ID: "22170dcf-2e58-49b7-9115-951b84d366f6",
Name: "Node01",
},
{
Status: "ACTIVE",
Updated: crossregionSubnetServerTimeStamp,
},
{
ID: "df842202-fdcc-490e-b92a-6e252e5577c7",
Name: "Node02",
Status: "ACTIVE",
Updated: crossregionSubnetServerTimeStamp,
},
},
Subnets: []subnets.Subnet{
{
ID: 10,
Region: "ru-1",
CIDR: "192.168.200.0/24",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
NetworkID: "78c1cbe1-c34d-4685-be2d-a877a1b1dec4",
SubnetID: "7db1255f-2545-4b8a-9446-22608c0f6cb8",
Region: "ru-1",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
VLANID: 1003,
VTEPIPAddress: "10.10.0.101",
},
{
ID: 20,
Region: "ru-3",
CIDR: "192.168.200.0/24",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
NetworkID: "67f7ab15-9424-4b50-999a-1c4de12372ec",
SubnetID: "66ee047b-c699-4d62-9b64-363d2d77f021",
Region: "ru-3",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
VLANID: 1003,
VTEPIPAddress: "10.10.0.201",
},
},
}

// TestListCrossRegionSubnetsResponseRaw represents a raw response from the List request.
const TestListCrossRegionSubnetsResponseRaw = `
{
"cross_region_subnets": [
{
"id": 12,
"cidr": "192.168.200.0/24",
"vlan_id": 1003,
"status": "ACTIVE",
"servers": [
{
"status": "ACTIVE",
"updated": "2019-01-04T08:09:43Z",
"id": "22170dcf-2e58-49b7-9115-951b84d366f6",
"name": "Node01"
},
{
"status": "ACTIVE",
"updated": "2019-01-04T08:09:43Z",
"id": "df842202-fdcc-490e-b92a-6e252e5577c7",
"name": "Node02"
}
],
"subnets": [
{
"id": 10,
"vlan_id": 1003,
"cidr": "192.168.200.0/24",
"project_id": "b63ab68796e34858befb8fa2a8b1e12a",
"network_id": "78c1cbe1-c34d-4685-be2d-a877a1b1dec4",
"subnet_id": "7db1255f-2545-4b8a-9446-22608c0f6cb8",
"region": "ru-1",
"vtep_ip_address": "10.10.0.101"
},
{
"id": 20,
"vlan_id": 1003,
"cidr": "192.168.200.0/24",
"project_id": "b63ab68796e34858befb8fa2a8b1e12a",
"network_id": "67f7ab15-9424-4b50-999a-1c4de12372ec",
"subnet_id": "66ee047b-c699-4d62-9b64-363d2d77f021",
"region": "ru-3",
"vtep_ip_address": "10.10.0.201"
}
]
}
]
}
`

// TestListCrossRegionSubnetsResponse represents an unmarshalled TestListCrossRegionSubnetsResponseRaw
var TestListCrossRegionSubnetsResponse = []*crossregionsubnets.CrossRegionSubnet{
{
ID: 12,
CIDR: "192.168.200.0/24",
VLANID: 1003,
Status: "ACTIVE",
Servers: []servers.Server{
{
ID: "22170dcf-2e58-49b7-9115-951b84d366f6",
Name: "Node01",
Status: "ACTIVE",
Updated: crossregionSubnetServerTimeStamp,
},
{
ID: "df842202-fdcc-490e-b92a-6e252e5577c7",
Name: "Node02",
Status: "ACTIVE",
Updated: crossregionSubnetServerTimeStamp,
},
},
Subnets: []subnets.Subnet{
{
ID: 10,
Region: "ru-1",
CIDR: "192.168.200.0/24",
NetworkID: "78c1cbe1-c34d-4685-be2d-a877a1b1dec4",
SubnetID: "7db1255f-2545-4b8a-9446-22608c0f6cb8",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
VLANID: 1003,
VTEPIPAddress: "10.10.0.101",
},
{
ID: 20,
Region: "ru-3",
CIDR: "192.168.200.0/24",
NetworkID: "67f7ab15-9424-4b50-999a-1c4de12372ec",
SubnetID: "66ee047b-c699-4d62-9b64-363d2d77f021",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
VLANID: 1003,
VTEPIPAddress: "10.10.0.201",
},
},
},
}

// TestManyCrossRegionSubnetsInvalidResponseRaw represents a raw invalid response with
// several cross-region subnets.
const TestManyCrossRegionSubnetsInvalidResponseRaw = `
{
"cross_region_subnets": [
{
"id": "b63ab68796e34858befb8fa2a8b1e12a"
}
]
}
`

// TestSingleCrossRegionSubnetInvalidResponseRaw represents a raw invalid response with
// a single cross-region subnet.
const TestSingleCrossRegionSubnetInvalidResponseRaw = `
Expand Down
110 changes: 110 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,113 @@ func TestGetCrossRegionSubnetUnmarshalError(t *testing.T) {
t.Fatal("expected error from the Get method")
}
}

func TestListCrossRegionSubnets(t *testing.T) {
endpointCalled := false

testEnv := testutils.SetupTestEnv()
defer testEnv.TearDownTestEnv()
testEnv.NewTestResellV2Client()
testutils.HandleReqWithoutBody(t, &testutils.HandleReqOpts{
Mux: testEnv.Mux,
URL: "/resell/v2/cross_region_subnets",
RawResponse: TestListCrossRegionSubnetsResponseRaw,
Method: http.MethodGet,
Status: http.StatusOK,
CallFlag: &endpointCalled,
})

ctx := context.Background()
actual, _, err := crossregionsubnets.List(ctx, testEnv.Client, crossregionsubnets.ListOpts{})
if err != nil {
t.Fatal(err)
}

expected := TestListCrossRegionSubnetsResponse

if !endpointCalled {
t.Fatal("endpoint wasn't called")
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected %#v, but got %#v", expected, actual)
}
}

func TestListCrossRegionSubnetsHTTPError(t *testing.T) {
endpointCalled := false

testEnv := testutils.SetupTestEnv()
defer testEnv.TearDownTestEnv()
testEnv.NewTestResellV2Client()
testutils.HandleReqWithoutBody(t, &testutils.HandleReqOpts{
Mux: testEnv.Mux,
URL: "/resell/v2/cross_region_subnets",
RawResponse: TestListCrossRegionSubnetsResponseRaw,
Method: http.MethodGet,
Status: http.StatusBadGateway,
CallFlag: &endpointCalled,
})

ctx := context.Background()
allCrossRegionSubnets, httpResponse, err := crossregionsubnets.List(ctx, testEnv.Client, crossregionsubnets.ListOpts{})

if !endpointCalled {
t.Fatal("endpoint wasn't called")
}
if allCrossRegionSubnets != nil {
t.Fatal("expected no cross-region subnets from the List method")
}
if err == nil {
t.Fatal("expected error from the List method")
}
if httpResponse.StatusCode != http.StatusBadGateway {
t.Fatalf("expected %d status in the HTTP response, but got %d",
http.StatusBadGateway, httpResponse.StatusCode)
}
}

func TestListCrossRegionSubnetsTimeoutError(t *testing.T) {
testEnv := testutils.SetupTestEnv()
testEnv.Server.Close()
defer testEnv.TearDownTestEnv()
testEnv.NewTestResellV2Client()

ctx := context.Background()
allCrossRegionSubnets, _, err := crossregionsubnets.List(ctx, testEnv.Client, crossregionsubnets.ListOpts{})

if allCrossRegionSubnets != nil {
t.Fatal("expected no cross-region subnets from the List method")
}
if err == nil {
t.Fatal("expected error from the List method")
}
}

func TestListCrossRegionSubnetsUnmarshalError(t *testing.T) {
endpointCalled := false

testEnv := testutils.SetupTestEnv()
defer testEnv.TearDownTestEnv()
testEnv.NewTestResellV2Client()
testutils.HandleReqWithoutBody(t, &testutils.HandleReqOpts{
Mux: testEnv.Mux,
URL: "/resell/v2/cross_region_subnets",
RawResponse: TestManyCrossRegionSubnetsInvalidResponseRaw,
Method: http.MethodGet,
Status: http.StatusOK,
CallFlag: &endpointCalled,
})

ctx := context.Background()
allCrossRegionSubnets, _, err := crossregionsubnets.List(ctx, testEnv.Client, crossregionsubnets.ListOpts{})

if !endpointCalled {
t.Fatal("endpoint wasn't called")
}
if allCrossRegionSubnets != nil {
t.Fatal("expected no cross-region subnets from the List method")
}
if err == nil {
t.Fatal("expected error from the List method")
}
}

0 comments on commit 1db6d84

Please sign in to comment.