Skip to content

Commit e1fbedc

Browse files
kangastapeknur
andauthored
feat(gateway): add support for network gateway (#213)
Co-authored-by: Pekka Nurmi <pekka.nurmi@upcloud.com>
1 parent d9918f0 commit e1fbedc

9 files changed

Lines changed: 659 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)
77

88
### Added
99
- labels support for storages
10+
- support for network gateways
1011

1112
### Changed
1213
- errors: all service method now return `Problem` type in case of errors (*BREAKING CHANGE*)

upcloud/error_codes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,5 @@ const (
211211
ErrCodePeeringAccoundInvalid string = "PEERING_ACCOUNT_INVALID"
212212
ErrCodePeeringConflict string = "PEERING_CONFLICT"
213213
ErrPeeringNotDisabled string = "PEERING_NOT_DISABLED"
214+
ErrCodeDuplicateResource string = "DUPLICATE_RESOURCE"
214215
)

upcloud/gateway.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package upcloud
2+
3+
import "time"
4+
5+
// GatewayConfiguredStatus represents a desired status of the service
6+
type GatewayConfiguredStatus string
7+
8+
// GatewayConfiguredStatus represents a current actual status of the service
9+
type GatewayOperationalState string
10+
11+
// GatewayFeature represents a feature of the service
12+
type GatewayFeature string
13+
14+
const (
15+
GatewayConfiguredStatusStarted GatewayConfiguredStatus = "started"
16+
GatewayConfiguredStatusStopped GatewayConfiguredStatus = "stopped"
17+
18+
GatewayOperationalStatePending GatewayOperationalState = "pending"
19+
GatewayOperationalStateSetupAgent GatewayOperationalState = "setup-agent"
20+
GatewayOperationalStateSetupLinkNetwork GatewayOperationalState = "setup-link-network"
21+
GatewayOperationalStateSetupServer GatewayOperationalState = "setup-server"
22+
GatewayOperationalStateSetupNetwork GatewayOperationalState = "setup-network"
23+
GatewayOperationalStateSetupGW GatewayOperationalState = "setup-gw"
24+
GatewayOperationalStateSetupDNS GatewayOperationalState = "setup-dns"
25+
GatewayOperationalStateCheckup GatewayOperationalState = "checkup"
26+
GatewayOperationalStateRunning GatewayOperationalState = "running"
27+
GatewayOperationalStateDeleteDNS GatewayOperationalState = "delete-dns"
28+
GatewayOperationalStateDeleteNetwork GatewayOperationalState = "delete-network"
29+
GatewayOperationalStateDeleteServer GatewayOperationalState = "delete-server"
30+
GatewayOperationalStateDeleteLinkNetwork GatewayOperationalState = "delete-link-network"
31+
GatewayOperationalStateDeleteService GatewayOperationalState = "delete-service"
32+
33+
// GatewayFeatureNAT is the network address translation (NAT) feature of the network gateway
34+
GatewayFeatureNAT GatewayFeature = "nat"
35+
)
36+
37+
type Gateway struct {
38+
UUID string `json:"uuid,omitempty"`
39+
Name string `json:"name,omitempty"`
40+
Zone string `json:"zone,omitempty"`
41+
Labels []Label `json:"labels,omitempty"`
42+
ConfiguredStatus GatewayConfiguredStatus `json:"configured_status,omitempty"`
43+
OperationalState GatewayOperationalState `json:"operational_state,omitempty"`
44+
Features []GatewayFeature `json:"features,omitempty"`
45+
Routers []GatewayRouter `json:"routers,omitempty"`
46+
CreatedAt time.Time `json:"created_at,omitempty"`
47+
UpdatedAt time.Time `json:"updated_at,omitempty"`
48+
}
49+
50+
type GatewayRouter struct {
51+
CreatedAt time.Time `json:"created_at,omitempty"`
52+
UUID string `json:"uuid,omitempty"`
53+
}

upcloud/gateway_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package upcloud
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestGateway(t *testing.T) {
8+
t.Parallel()
9+
10+
jsonStr := `
11+
{
12+
"configured_status": "started",
13+
"created_at": "2022-12-01T09:04:08.529138Z",
14+
"features": [
15+
"nat"
16+
],
17+
"name": "example-gateway",
18+
"operational_state": "running",
19+
"routers": [
20+
{
21+
"created_at": "2022-12-01T09:04:08.529138Z",
22+
"uuid": "0485d477-8d8f-4c97-9bef-731933187538"
23+
}
24+
],
25+
"labels": [
26+
{
27+
"key":"env",
28+
"value":"testing"
29+
}
30+
],
31+
"updated_at": "2022-12-01T19:04:08.529138Z",
32+
"uuid": "10c153e0-12e4-4dea-8748-4f34850ff76d",
33+
"zone": "fi-hel1"
34+
}
35+
`
36+
37+
gateway := &Gateway{
38+
ConfiguredStatus: GatewayConfiguredStatusStarted,
39+
CreatedAt: timeParse("2022-12-01T09:04:08.529138Z"),
40+
Features: []GatewayFeature{
41+
GatewayFeatureNAT,
42+
},
43+
Name: "example-gateway",
44+
OperationalState: "running",
45+
Routers: []GatewayRouter{
46+
{
47+
CreatedAt: timeParse("2022-12-01T09:04:08.529138Z"),
48+
UUID: "0485d477-8d8f-4c97-9bef-731933187538",
49+
},
50+
},
51+
Labels: []Label{
52+
{Key: "env", Value: "testing"},
53+
},
54+
UpdatedAt: timeParse("2022-12-01T19:04:08.529138Z"),
55+
UUID: "10c153e0-12e4-4dea-8748-4f34850ff76d",
56+
Zone: "fi-hel1",
57+
}
58+
59+
testJSON(t, &Gateway{}, gateway, jsonStr)
60+
}

upcloud/request/gateway.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package request
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/UpCloudLtd/upcloud-go-api/v5/upcloud"
7+
)
8+
9+
const gatewayBaseURL string = "/gateway"
10+
11+
type GetGatewaysRequest struct {
12+
Filters []QueryFilter
13+
}
14+
15+
func (r *GetGatewaysRequest) RequestURL() string {
16+
if len(r.Filters) == 0 {
17+
return gatewayBaseURL
18+
}
19+
20+
return fmt.Sprintf("%s?%s", gatewayBaseURL, encodeQueryFilters(r.Filters))
21+
}
22+
23+
type GetGatewayRequest struct {
24+
UUID string
25+
}
26+
27+
func (r *GetGatewayRequest) RequestURL() string {
28+
return fmt.Sprintf("%s/%s", gatewayBaseURL, r.UUID)
29+
}
30+
31+
type GatewayRouter struct {
32+
UUID string `json:"uuid,omitempty"`
33+
}
34+
35+
type CreateGatewayRequest struct {
36+
Name string `json:"name,omitempty"`
37+
Zone string `json:"zone,omitempty"`
38+
Features []upcloud.GatewayFeature `json:"features,omitempty"`
39+
Routers []GatewayRouter `json:"routers,omitempty"`
40+
Labels []upcloud.Label `json:"labels,omitempty"`
41+
ConfiguredStatus upcloud.GatewayConfiguredStatus `json:"configured_status,omitempty"`
42+
}
43+
44+
func (r *CreateGatewayRequest) RequestURL() string {
45+
return gatewayBaseURL
46+
}
47+
48+
type ModifyGatewayRequest struct {
49+
UUID string `json:"-"`
50+
Name string `json:"name,omitempty"`
51+
ConfiguredStatus upcloud.GatewayConfiguredStatus `json:"configured_status,omitempty"`
52+
Labels []upcloud.Label `json:"labels,omitempty"`
53+
}
54+
55+
func (r *ModifyGatewayRequest) RequestURL() string {
56+
return fmt.Sprintf("%s/%s", gatewayBaseURL, r.UUID)
57+
}
58+
59+
type DeleteGatewayRequest struct {
60+
UUID string
61+
}
62+
63+
func (r *DeleteGatewayRequest) RequestURL() string {
64+
return fmt.Sprintf("%s/%s", gatewayBaseURL, r.UUID)
65+
}

upcloud/request/gateway_test.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package request
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/UpCloudLtd/upcloud-go-api/v5/upcloud"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestGetGatewaysRequest(t *testing.T) {
13+
r := GetGatewaysRequest{}
14+
assert.Equal(t, "/gateway", r.RequestURL())
15+
16+
r = GetGatewaysRequest{
17+
Filters: []QueryFilter{
18+
FilterLabel{
19+
Label: upcloud.Label{
20+
Key: "color",
21+
Value: "green",
22+
},
23+
},
24+
FilterLabelKey{Key: "size"},
25+
},
26+
}
27+
assert.Equal(t, "/gateway?label=color%3Dgreen&label=size", r.RequestURL())
28+
}
29+
30+
func TestGetGatewayRequest(t *testing.T) {
31+
t.Parallel()
32+
33+
r := GetGatewayRequest{UUID: "fake"}
34+
assert.Equal(t, gatewayBaseURL+"/fake", r.RequestURL())
35+
}
36+
37+
func TestDeleteGatewayRequest(t *testing.T) {
38+
t.Parallel()
39+
40+
r := DeleteGatewayRequest{UUID: "fake"}
41+
assert.Equal(t, gatewayBaseURL+"/fake", r.RequestURL())
42+
}
43+
44+
func TestCreateGatewayRequest(t *testing.T) {
45+
t.Parallel()
46+
47+
const want string = `
48+
{
49+
"name": "example-gateway",
50+
"zone": "fi-hel1",
51+
"features": [
52+
"nat"
53+
],
54+
"routers": [
55+
{
56+
"uuid": "0485d477-8d8f-4c97-9bef-731933187538"
57+
}
58+
],
59+
"configured_status": "started"
60+
}
61+
`
62+
r := CreateGatewayRequest{
63+
Name: "example-gateway",
64+
Zone: "fi-hel1",
65+
Features: []upcloud.GatewayFeature{upcloud.GatewayFeatureNAT},
66+
Routers: []GatewayRouter{
67+
{
68+
UUID: "0485d477-8d8f-4c97-9bef-731933187538",
69+
},
70+
},
71+
ConfiguredStatus: upcloud.GatewayConfiguredStatusStarted,
72+
}
73+
got, err := json.Marshal(&r)
74+
require.NoError(t, err)
75+
assert.Equal(t, gatewayBaseURL, r.RequestURL())
76+
assert.JSONEq(t, want, string(got))
77+
}
78+
79+
func TestModifyGatewayRequest(t *testing.T) {
80+
t.Parallel()
81+
82+
want := `
83+
{
84+
"name": "example-gateway",
85+
"configured_status": "started"
86+
}
87+
`
88+
r := ModifyGatewayRequest{
89+
UUID: "fake",
90+
Name: "example-gateway",
91+
ConfiguredStatus: upcloud.GatewayConfiguredStatusStarted,
92+
}
93+
got, err := json.Marshal(&r)
94+
require.NoError(t, err)
95+
assert.JSONEq(t, want, string(got))
96+
97+
want = `
98+
{
99+
"name": "example-gateway"
100+
}
101+
`
102+
r = ModifyGatewayRequest{
103+
UUID: "fake",
104+
Name: "example-gateway",
105+
}
106+
got, err = json.Marshal(&r)
107+
require.NoError(t, err)
108+
assert.JSONEq(t, want, string(got))
109+
110+
want = `
111+
{
112+
"configured_status": "started"
113+
}
114+
`
115+
r = ModifyGatewayRequest{
116+
UUID: "fake",
117+
ConfiguredStatus: upcloud.GatewayConfiguredStatusStarted,
118+
}
119+
got, err = json.Marshal(&r)
120+
require.NoError(t, err)
121+
assert.JSONEq(t, want, string(got))
122+
123+
assert.Equal(t, gatewayBaseURL+"/fake", r.RequestURL())
124+
}

0 commit comments

Comments
 (0)