Skip to content

Commit

Permalink
Merge 1a68e98 into 8839192
Browse files Browse the repository at this point in the history
  • Loading branch information
kolsean committed Jan 5, 2019
2 parents 8839192 + 1a68e98 commit 0acd585
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ You can use this library to work with the following objects of the Selectel VPC
* [tokens](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/tokens)
* [subnets](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/subnets)
* [vrrp_subnets](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/vrrpsubnets)
* [cross_region_subnets](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/crossregionsubnets)
* [floating ips](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/floatingips)
* [licenses](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/licenses)
* [keypairs](https://godoc.org/github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/keypairs)
Expand Down
13 changes: 13 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
Package crossregionsubnets provides the ability to retrieve and manage cross-region subnets
through the Resell v2 API.
Example of getting a single cross-region subnet referenced by its id
crossRegionSubnet, _, err := crossregionsubnets.Get(context, resellClient, crossRegionSubnetID)
if err != nil {
log.Fatal(err)
}
fmt.Println(crossRegionSubnet)
*/
package crossregionsubnets
34 changes: 34 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package crossregionsubnets

import (
"context"
"net/http"
"strings"

"github.com/selectel/go-selvpcclient/selvpcclient"
)

const resourceURL = "cross_region_subnets"

//Get returns a single cross-region subnet by its id.
func Get(ctx context.Context, client *selvpcclient.ServiceClient, id string) (*CrossRegionSubnet, *selvpcclient.ResponseResult, error) {
url := strings.Join([]string{client.Endpoint, resourceURL, id}, "/")
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 a cross-region subnet from the response body.
var result struct {
CrossRegionSubnet *CrossRegionSubnet `json:"cross_region_subnet"`
}
err = responseResult.ExtractResult(&result)
if err != nil {
return nil, responseResult, err
}

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

import (
"github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/servers"
)

// CrossRegionSubnet represents a single Resell cross-region subnet.
type CrossRegionSubnet struct {
// ID is a unique id of a cross-region subnet.
ID int `json:"id"`

// CIDR is a cross-region subnet prefix in CIDR notation.
CIDR string `json:"cidr"`

// VlanID represents id of the associated VLAN in the Networking service.
VlanID int `json:"vlan_id"`

// Status shows if cross-region subnet is used.
Status string `json:"status"`

// Servers contains info about servers to which cross-region subnet is associated to.
Servers []servers.Server `json:"servers"`

// Subnets contains info about subnets in every region that cross-region subnet is attached to.
Subnets []Subnet `json:"subnets"`
}

// Subnet represents a single subnet to which cross-region subnet is associated to.
type Subnet struct {

// ID is a unique id of a subnet.
ID int `json:"id"`

// VlanID represents id of the associated VLAN in the Networking service.
VlanID int `json:"vlan_id"`

// CIDR is a subnet prefix in CIDR notation.
CIDR string `json:"cidr"`

// ProjectID represents an associated Identity service project.
ProjectID string `json:"project_id"`

// NetworkID represents id of the associated network in the Networking service.
NetworkID string `json:"network_id"`

// SubnetID represents id of the associated subnet in the Networking service.
SubnetID string `json:"subnet_id"`

// Region represents a region where the subnet resides.
Region string `json:"region"`

// VtepIP represents an ip address of the associated VTEP in the Networking service.
VtepIP string `json:"vtep_ip_address"`
}
112 changes: 112 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/testing/fixtures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package testing

import (
"time"

"github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/crossregionsubnets"
"github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/servers"
)

// TestGetCrossRegionSubnetResponseRaw represents a raw response from the Get request.
const TestGetCrossRegionSubnetResponseRaw = `
{
"cross_region_subnet": {
"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"
}
]
}
}
`

var crossregionSubnetServerTimeStamp, _ = time.Parse(time.RFC3339, "2019-01-04T08:09:43Z")

// TestGetCrossRegionSubnetResponse represents an unmarshalled TestGetCrossRegionSubnetResponseRaw.
var TestGetCrossRegionSubnetResponse = &crossregionsubnets.CrossRegionSubnet{
ID: 12,
CIDR: "192.168.200.0/24",
VlanID: 1003,
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",
},
},
Subnets: []crossregionsubnets.Subnet{
{
ID: 10,
VlanID: 1003,
CIDR: "192.168.200.0/24",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
NetworkID: "78c1cbe1-c34d-4685-be2d-a877a1b1dec4",
SubnetID: "7db1255f-2545-4b8a-9446-22608c0f6cb8",
Region: "ru-1",
VtepIP: "10.10.0.101",
},
{
ID: 20,
VlanID: 1003,
CIDR: "192.168.200.0/24",
ProjectID: "b63ab68796e34858befb8fa2a8b1e12a",
NetworkID: "67f7ab15-9424-4b50-999a-1c4de12372ec",
SubnetID: "66ee047b-c699-4d62-9b64-363d2d77f021",
Region: "ru-3",
VtepIP: "10.10.0.201",
},
},
}

// TestSingleCrossRegionSubnetInvalidResponseRaw represents a raw invalid response with
// a single cross-region subnet.
const TestSingleCrossRegionSubnetInvalidResponseRaw = `
{
"cross_region_subnet": {
"id": "b63ab68796e34858befb8fa2a8b1e12a"
}
}
`
121 changes: 121 additions & 0 deletions selvpcclient/resell/v2/crossregionsubnets/testing/requests_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package testing

import (
"context"
"net/http"
"reflect"
"testing"

"github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/crossregionsubnets"
"github.com/selectel/go-selvpcclient/selvpcclient/testutils"
)

func TestGetCrossRegionSubnet(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/12",
RawResponse: TestGetCrossRegionSubnetResponseRaw,
Method: http.MethodGet,
Status: http.StatusOK,
CallFlag: &endpointCalled,
})

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

expected := TestGetCrossRegionSubnetResponse

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

func TestGetCrossRegionSubnetHTTPError(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/12",
RawResponse: TestGetCrossRegionSubnetResponseRaw,
Method: http.MethodGet,
Status: http.StatusBadGateway,
CallFlag: &endpointCalled,
})

ctx := context.Background()
crossRegionSubnet, httpResponse, err := crossregionsubnets.Get(ctx, testEnv.Client, "12")

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

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

ctx := context.Background()
crossRegionSubnet, _, err := crossregionsubnets.Get(ctx, testEnv.Client, "12")

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

func TestGetCrossRegionSubnetUnmarshalError(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/12",
RawResponse: TestSingleCrossRegionSubnetInvalidResponseRaw,
Method: http.MethodGet,
Status: http.StatusOK,
CallFlag: &endpointCalled,
})

ctx := context.Background()
crossRegionSubnet, _, err := crossregionsubnets.Get(ctx, testEnv.Client, "12")

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

0 comments on commit 0acd585

Please sign in to comment.