diff --git a/selvpcclient/resell/v2/subnets/doc.go b/selvpcclient/resell/v2/subnets/doc.go new file mode 100644 index 0000000..4cb52b6 --- /dev/null +++ b/selvpcclient/resell/v2/subnets/doc.go @@ -0,0 +1,13 @@ +/* +Package subnets provides the ability to retrieve and manage subnets through +the Resell v2 API. + +Example of getting a single subnet referenced by its id + + subnet, _, err := subnets.Get(context, resellClient, subnetID) + if err != nil { + log.Fatal(err) + } + fmt.Println(subnet) +*/ +package subnets diff --git a/selvpcclient/resell/v2/subnets/requests.go b/selvpcclient/resell/v2/subnets/requests.go new file mode 100644 index 0000000..9edbcd0 --- /dev/null +++ b/selvpcclient/resell/v2/subnets/requests.go @@ -0,0 +1,33 @@ +package subnets + +import ( + "context" + "strings" + + "github.com/selectel/go-selvpcclient/selvpcclient" +) + +const resourceURL = "subnets" + +// Get returns a single subnet by its id. +func Get(ctx context.Context, client *selvpcclient.ServiceClient, id string) (*Subnet, *selvpcclient.ResponseResult, error) { + url := strings.Join([]string{client.Endpoint, resourceURL, id}, "/") + responseResult, err := client.DoRequest(ctx, "GET", url, nil) + if err != nil { + return nil, nil, err + } + if responseResult.Err != nil { + return nil, responseResult, responseResult.Err + } + + // Extract a subnet from the response body. + var result struct { + Subnet *Subnet `json:"subnet"` + } + err = responseResult.ExtractResult(&result) + if err != nil { + return nil, responseResult, err + } + + return result.Subnet, responseResult, nil +} diff --git a/selvpcclient/resell/v2/subnets/schemas.go b/selvpcclient/resell/v2/subnets/schemas.go new file mode 100644 index 0000000..30cde89 --- /dev/null +++ b/selvpcclient/resell/v2/subnets/schemas.go @@ -0,0 +1,30 @@ +package subnets + +import "github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/servers" + +// Subnet represents a single Resell subnet. +type Subnet struct { + // ID is a unique id of a subnet. + ID int `json:"id"` + + // Status shows if subnet is used. + Status string `json:"status"` + + // Servers contains info about servers to which subnet is associated to. + Servers []servers.Server `json:"servers"` + + // Region represents a region of where the subnet resides. + Region string `json:"region"` + + // CIDR is a subnet prefix in CIDR notation. + CIDR string `json:"cidr"` + + // 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"` + + // ProjectID represents an associated Resell project. + ProjectID string `json:"project_id"` +} diff --git a/selvpcclient/resell/v2/subnets/testing/fixtures.go b/selvpcclient/resell/v2/subnets/testing/fixtures.go new file mode 100644 index 0000000..f92bec8 --- /dev/null +++ b/selvpcclient/resell/v2/subnets/testing/fixtures.go @@ -0,0 +1,52 @@ +package testing + +import ( + "time" + + "github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/servers" + "github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/subnets" +) + +// TestGetSubnetResponseRaw represents a raw response from the Get request. +const TestGetSubnetResponseRaw = ` +{ + "subnet": { + "cidr": "203.0.113.11/24", + "id": 111122, + "network_id": "8233f12e-c47e-4f1c-953a-1ecd322a7119", + "project_id": "49338ac045f448e294b25d013f890317", + "region": "ru-3", + "servers": [ + { + "id": "253b680c-89f6-4c85-afbf-c9a67c92d3fe", + "name": "Node01", + "status": "ACTIVE", + "updated": "2018-03-12T14:56:19Z" + } + ], + "status": "ACTIVE", + "subnet_id": "94425a6e-19cd-412d-9710-ff40b34a78f4" + } +} +` + +var subnetServerTimeStamp, _ = time.Parse(time.RFC3339, "2018-03-12T14:56:19Z") + +// TestGetSubnetResponse represents an unmarshalled TestGetSubnetResponseRaw. +var TestGetSubnetResponse = &subnets.Subnet{ + ID: 111122, + Status: "ACTIVE", + Servers: []servers.Server{ + { + ID: "253b680c-89f6-4c85-afbf-c9a67c92d3fe", + Name: "Node01", + Status: "ACTIVE", + Updated: subnetServerTimeStamp, + }, + }, + CIDR: "203.0.113.11/24", + NetworkID: "8233f12e-c47e-4f1c-953a-1ecd322a7119", + ProjectID: "49338ac045f448e294b25d013f890317", + Region: "ru-3", + SubnetID: "94425a6e-19cd-412d-9710-ff40b34a78f4", +} diff --git a/selvpcclient/resell/v2/subnets/testing/request_test.go b/selvpcclient/resell/v2/subnets/testing/request_test.go new file mode 100644 index 0000000..feb3c8a --- /dev/null +++ b/selvpcclient/resell/v2/subnets/testing/request_test.go @@ -0,0 +1,38 @@ +package testing + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + + "github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/subnets" + "github.com/selectel/go-selvpcclient/selvpcclient/testutils" +) + +func TestGetSubnet(t *testing.T) { + testEnv := testutils.SetupTestEnv() + defer testEnv.TearDownTestEnv() + testEnv.NewTestResellV2Client() + testEnv.Mux.HandleFunc("/resell/v2/subnets/111122", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, TestGetSubnetResponseRaw) + + if r.Method != http.MethodGet { + t.Fatalf("expected %s method but got %s", http.MethodGet, r.Method) + } + }) + + ctx := context.Background() + actual, _, err := subnets.Get(ctx, testEnv.Client, "111122") + if err != nil { + t.Fatal(err) + } + + expected := TestGetSubnetResponse + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("expected %#v, but got %#v", expected, actual) + } +}