Skip to content

Commit

Permalink
Merge ef3c878 into a3901fa
Browse files Browse the repository at this point in the history
  • Loading branch information
kolsean committed Jan 10, 2019
2 parents a3901fa + ef3c878 commit f2c53ea
Show file tree
Hide file tree
Showing 5 changed files with 305 additions and 0 deletions.
26 changes: 26 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,31 @@ Example of getting all cross-region subnets
for _, crossRegionSubnet := range allCrossRegionSubnets {
fmt.Println(crossRegionSubnet)
}
Example of creating cross-region subnets
createOpts := crossregionsubnets.CrossRegionSubnetOpts{
CrossRegionSubnets: []crossregionsubnets.CrossRegionSubnetOpt{
{
Quantity: 1,
Regions: []crossregionsubnets.CrossRegionOpt{
{
Region: "ru-1",
},
{
Region: "ru-3",
},
},
CIDR: "192.168.200.0/24",
},
},
}
newCrossRegionSubnets, _, err := crossregionsubnets.Create(ctx, resellClient, projectID, createOpts)
if err != nil {
log.Fatal(err)
}
for _, newCrossRegionSubnet := range newCrossRegionSubnets {
fmt.Printf("%v\n", newCrossRegionSubnet)
}
*/
package crossregionsubnets
31 changes: 31 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/requests.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package crossregionsubnets

import (
"bytes"
"context"
"encoding/json"
"net/http"
"strings"

Expand Down Expand Up @@ -64,3 +66,32 @@ func List(ctx context.Context, client *selvpcclient.ServiceClient, opts ListOpts

return result.CrossRegionSubnets, responseResult, nil
}

// Create requests a creation of the cross-region subnets in the specified project.
func Create(ctx context.Context, client *selvpcclient.ServiceClient, projectID string, createOpts CrossRegionSubnetOpts) ([]*CrossRegionSubnet, *selvpcclient.ResponseResult, error) {
createCrossRegionSubnetsOpts := &createOpts
requestBody, err := json.Marshal(createCrossRegionSubnetsOpts)
if err != nil {
return nil, nil, err
}

url := strings.Join([]string{client.Endpoint, resourceURL, "projects", projectID}, "/")
responseResult, err := client.DoRequest(ctx, http.MethodPost, url, bytes.NewReader(requestBody))
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
}
24 changes: 24 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/requests_opts.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
package crossregionsubnets

// CrossRegionSubnetOpts represents options for the cross-region subnets Create request.
type CrossRegionSubnetOpts struct {
// CrossRegionSubnets represents options for all cross-region subnets.
CrossRegionSubnets []CrossRegionSubnetOpt `json:"cross_region_subnets"`
}

// CrossRegionSubnetOpt represents options for the single cross-region subnet.
type CrossRegionSubnetOpt struct {
// Quantity represents how many subnets do we need to create.
Quantity int `json:"quantity"`

// Regions represents region options for the cross-region subnet.
Regions []CrossRegionOpt `json:"regions"`

// CIDR represents a subnet prefix in CIDR notation for the cross-region subnet.
CIDR string `json:"cidr"`
}

// CrossRegionOpt represents region options for the cross-region subnet.
type CrossRegionOpt struct {
// Region represents region that cross-region subnet is associated to.
Region string `json:"region"`
}

// ListOpts represents options for the List request.
type ListOpts struct {
Detailed bool `param:"detailed"`
Expand Down
106 changes: 106 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,112 @@ var TestListCrossRegionSubnetsResponse = []*crossregionsubnets.CrossRegionSubnet
},
}

// TestCreateCrossRegionSubnetsOptsRaw represents marshalled options for the Create request.
const TestCreateCrossRegionSubnetsOptsRaw = `
{
"cross_region_subnets": [
{
"quantity": 1,
"regions": [
{
"region": "ru-1"
},
{
"region": "ru-3"
}
],
"cidr": "192.168.200.0/24"
}
]
}
`

// TestCreateCrossRegionSubnetsOpts represents options for the Create request.
var TestCreateCrossRegionSubnetsOpts = crossregionsubnets.CrossRegionSubnetOpts{
CrossRegionSubnets: []crossregionsubnets.CrossRegionSubnetOpt{
{
Quantity: 1,
Regions: []crossregionsubnets.CrossRegionOpt{
{
Region: "ru-1",
},
{
Region: "ru-3",
},
},
CIDR: "192.168.200.0/24",
},
},
}

// TestCreateCrossRegionSubnetsResponseRaw represents a raw response from the Create request.
const TestCreateCrossRegionSubnetsResponseRaw = `
{
"cross_region_subnets": [
{
"id": 12,
"cidr": "192.168.200.0/24",
"vlan_id": 1003,
"status": "DOWN",
"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"
}
]
}
]
}
`

// TestCreateCrossRegionSubnetsResponse represents an unmarshalled TestCreateCrossRegionSubnetsResponseRaw
var TestCreateCrossRegionSubnetsResponse = []*crossregionsubnets.CrossRegionSubnet{
{
ID: 12,
CIDR: "192.168.200.0/24",
VLANID: 1003,
Status: "DOWN",
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 = `
Expand Down
118 changes: 118 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,121 @@ func TestListCrossRegionSubnetsUnmarshalError(t *testing.T) {
t.Fatal("expected error from the List method")
}
}

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

testEnv := testutils.SetupTestEnv()
defer testEnv.TearDownTestEnv()
testEnv.NewTestResellV2Client()
testutils.HandleReqWithBody(t, &testutils.HandleReqOpts{
Mux: testEnv.Mux,
URL: "/resell/v2/cross_region_subnets/projects/b63ab68796e34858befb8fa2a8b1e12a",
RawResponse: TestCreateCrossRegionSubnetsResponseRaw,
RawRequest: TestCreateCrossRegionSubnetsOptsRaw,
Method: http.MethodPost,
Status: http.StatusOK,
CallFlag: &endpointCalled,
})

ctx := context.Background()
createOpts := TestCreateCrossRegionSubnetsOpts
actualResponse, _, err := crossregionsubnets.Create(ctx, testEnv.Client, "b63ab68796e34858befb8fa2a8b1e12a", createOpts)
if err != nil {
t.Fatal(err)
}

expectedResponse := TestCreateCrossRegionSubnetsResponse

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

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

testEnv := testutils.SetupTestEnv()
defer testEnv.TearDownTestEnv()
testEnv.NewTestResellV2Client()
testutils.HandleReqWithBody(t, &testutils.HandleReqOpts{
Mux: testEnv.Mux,
URL: "/resell/v2/cross_region_subnets/projects/b63ab68796e34858befb8fa2a8b1e12a",
RawResponse: TestCreateCrossRegionSubnetsResponseRaw,
RawRequest: TestCreateCrossRegionSubnetsOptsRaw,
Method: http.MethodPost,
Status: http.StatusBadRequest,
CallFlag: &endpointCalled,
})

ctx := context.Background()
createOpts := TestCreateCrossRegionSubnetsOpts
crossregionSubnet, httpResponse, err := crossregionsubnets.Create(ctx, testEnv.Client,
"b63ab68796e34858befb8fa2a8b1e12a", createOpts)

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

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

ctx := context.Background()
createOpts := TestCreateCrossRegionSubnetsOpts
crossregionSubnet, _, err := crossregionsubnets.Create(ctx, testEnv.Client, "b63ab68796e34858befb8fa2a8b1e12a", createOpts)

if crossregionSubnet != nil {
t.Fatal("expected no cross-region subnet from the Create method")
}
if err == nil {
t.Fatal("expected error from the Create method")
}
}

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

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

ctx := context.Background()
createOpts := TestCreateCrossRegionSubnetsOpts
crossregionSubnet, _, err := crossregionsubnets.Create(ctx, testEnv.Client, "b63ab68796e34858befb8fa2a8b1e12a", createOpts)

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

0 comments on commit f2c53ea

Please sign in to comment.