Skip to content

Commit ca03c8c

Browse files
authored
Merge pull request #57 from opencredo/master
Update to JSON API version 1.3
2 parents edfdac4 + eba229d commit ca03c8c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+17941
-2155
lines changed

examples/upcloud-cli/main.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,16 @@ func createServer(s *service.Service) error {
8787
Tier: upcloud.StorageTierMaxIOPS,
8888
},
8989
},
90-
IPAddresses: []request.CreateServerIPAddress{
91-
{
92-
Access: upcloud.IPAddressAccessPrivate,
93-
Family: upcloud.IPAddressFamilyIPv4,
90+
Networking: &request.CreateServerNetworking{
91+
Interfaces: []request.CreateServerInterface{
92+
{
93+
IPAddresses: []request.CreateServerIPAddress{
94+
{
95+
Family: upcloud.IPAddressFamilyIPv4,
96+
},
97+
},
98+
Type: upcloud.IPAddressAccessUtility,
99+
},
94100
},
95101
},
96102
})

upcloud/account.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,21 @@ import "encoding/json"
44

55
// Account represents an account
66
type Account struct {
7-
Credits float64 `json:"credits"`
8-
UserName string `json:"username"`
7+
Credits float64 `json:"credits"`
8+
UserName string `json:"username"`
9+
ResourceLimits ResourceLimits `json:"resource_limits"`
10+
}
11+
12+
// ResourceLimits represents an account's resource limits
13+
type ResourceLimits struct {
14+
Cores int `json:"cores"`
15+
DetachedFloatingIps int `json:"detached_floating_ips"`
16+
Memory int `json:"memory"`
17+
Networks int `json:"networks"`
18+
PublicIPv4 int `json:"public_ipv4"`
19+
PublicIPv6 int `json:"public_ipv6"`
20+
StorageHDD int `json:"storage_hdd"`
21+
StorageSSD int `json:"storage_ssd"`
922
}
1023

1124
// UnmarshalJSON is a custom unmarshaller that deals with

upcloud/account_test.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,35 @@ import (
1010
// TestUnmarshalAccount tests that Account objects unmarshal correctly
1111
func TestUnmarshalAccount(t *testing.T) {
1212
originalJSON := `
13-
{
14-
"account": {
15-
"credits": 9972.2324,
16-
"username": "username"
17-
}
18-
}
13+
{
14+
"account": {
15+
"credits": 9972.2324,
16+
"username": "username",
17+
"resource_limits": {
18+
"cores": 200,
19+
"detached_floating_ips": 10,
20+
"memory": 1048576,
21+
"networks": 100,
22+
"public_ipv4": 100,
23+
"public_ipv6": 100,
24+
"storage_hdd": 10240,
25+
"storage_ssd": 10240
26+
}
27+
}
28+
}
1929
`
2030

2131
account := Account{}
2232
err := json.Unmarshal([]byte(originalJSON), &account)
2333
assert.NoError(t, err)
2434
assert.Equal(t, 9972.2324, account.Credits)
2535
assert.Equal(t, "username", account.UserName)
36+
assert.Equal(t, 200, account.ResourceLimits.Cores)
37+
assert.Equal(t, 10, account.ResourceLimits.DetachedFloatingIps)
38+
assert.Equal(t, 1048576, account.ResourceLimits.Memory)
39+
assert.Equal(t, 100, account.ResourceLimits.Networks)
40+
assert.Equal(t, 100, account.ResourceLimits.PublicIPv4)
41+
assert.Equal(t, 100, account.ResourceLimits.PublicIPv6)
42+
assert.Equal(t, 10240, account.ResourceLimits.StorageHDD)
43+
assert.Equal(t, 10240, account.ResourceLimits.StorageSSD)
2644
}

upcloud/client/client.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,18 @@ import (
1414

1515
// Constants
1616
const (
17-
DEFAULT_API_VERSION = "1.2.3"
18-
DEFAULT_API_BASEURL = "https://api.upcloud.com"
17+
DefaultAPIVersion = "1.3.4"
18+
DefaultAPIBaseURL = "https://api.upcloud.com"
1919

2020
// The default timeout (in seconds)
21-
DEFAULT_TIMEOUT = 10
21+
DefaultTimeout = 10
2222
)
2323

2424
// Client represents an API client
2525
type Client struct {
2626
userName string
2727
password string
2828
httpClient *http.Client
29-
30-
apiVersion string
31-
apiBaseURL string
3229
}
3330

3431
// New creates ands returns a new client configured with the specified user and password
@@ -45,10 +42,7 @@ func NewWithHTTPClient(userName string, password string, httpClient *http.Client
4542
client.userName = userName
4643
client.password = password
4744
client.httpClient = httpClient
48-
client.SetTimeout(time.Second * DEFAULT_TIMEOUT)
49-
50-
client.apiVersion = DEFAULT_API_VERSION
51-
client.apiBaseURL = DEFAULT_API_BASEURL
45+
client.SetTimeout(time.Second * DefaultTimeout)
5246

5347
return &client
5448
}
@@ -64,6 +58,7 @@ func (c *Client) GetTimeout() time.Duration {
6458
}
6559

6660
// CreateRequestURL creates and returns a complete request URL for the specified API location
61+
// using a newer API version
6762
func (c *Client) CreateRequestURL(location string) string {
6863
return fmt.Sprintf("%s%s", c.getBaseURL(), location)
6964
}
@@ -113,6 +108,23 @@ func (c *Client) PerformJSONPutRequest(url string, requestBody []byte) ([]byte,
113108
return c.performJSONRequest(request)
114109
}
115110

111+
// PerformJSONPatchRequest performs a PATCH request to the specified URL and returns the response body and eventual errors
112+
func (c *Client) PerformJSONPatchRequest(url string, requestBody []byte) ([]byte, error) {
113+
var bodyReader io.Reader
114+
115+
if requestBody != nil {
116+
bodyReader = bytes.NewBuffer(requestBody)
117+
}
118+
119+
request, err := http.NewRequest(http.MethodPatch, url, bodyReader)
120+
121+
if err != nil {
122+
return nil, err
123+
}
124+
125+
return c.performJSONRequest(request)
126+
}
127+
116128
// PerformJSONDeleteRequest performs a DELETE request to the specified URL and returns the response body and eventual errors
117129
func (c *Client) PerformJSONDeleteRequest(url string) error {
118130
request, err := http.NewRequest(http.MethodDelete, url, nil)
@@ -148,9 +160,9 @@ func (c *Client) performJSONRequest(request *http.Request) ([]byte, error) {
148160

149161
// Returns the base URL to use for API requests
150162
func (c *Client) getBaseURL() string {
151-
urlVersion, _ := semver.Make(c.apiVersion)
163+
urlVersion, _ := semver.Make(DefaultAPIVersion)
152164

153-
return fmt.Sprintf("%s/%d.%d", c.apiBaseURL, urlVersion.Major, urlVersion.Minor)
165+
return fmt.Sprintf("%s/%d.%d", DefaultAPIBaseURL, urlVersion.Major, urlVersion.Minor)
154166
}
155167

156168
// Parses the response and returns either the response body or an error

upcloud/ip_address.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const (
99

1010
IPAddressAccessPrivate = "private"
1111
IPAddressAccessPublic = "public"
12+
IPAddressAccessUtility = "utility"
1213
)
1314

1415
// IPAddresses represents a /ip_address response
@@ -41,13 +42,15 @@ func (s *IPAddresses) UnmarshalJSON(b []byte) error {
4142

4243
// IPAddress represents an IP address
4344
type IPAddress struct {
44-
Access string `json:"access"`
45-
Address string `json:"address"`
46-
Family string `json:"family"`
47-
// TODO: Convert to boolean
48-
PartOfPlan string `json:"part_of_plan"`
49-
PTRRecord string `json:"ptr_record"`
50-
ServerUUID string `json:"server"`
45+
Access string `json:"access"`
46+
Address string `json:"address"`
47+
Family string `json:"family"`
48+
PartOfPlan Boolean `json:"part_of_plan"`
49+
PTRRecord string `json:"ptr_record"`
50+
ServerUUID string `json:"server"`
51+
MAC string `json:"mac"`
52+
Floating Boolean `json:"floating"`
53+
Zone string `json:"zone"`
5154
}
5255

5356
// UnmarshalJSON is a custom unmarshaller that deals with

upcloud/ip_address_test.go

Lines changed: 78 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,87 +10,120 @@ import (
1010
// TestUnmarshalIPAddresses tests that IPAddresses and IPAddress structs are unmarshaled correctly
1111
func TestUnmarshalIPAddresses(t *testing.T) {
1212
originalJSON := `
13-
{
14-
"ip_addresses": {
15-
"ip_address": [
16-
{
17-
"access": "private",
18-
"address": "10.0.0.0",
19-
"family": "IPv4",
20-
"ptr_record": "",
21-
"server": "0053cd80-5945-4105-9081-11192806a8f7"
22-
},
23-
{
24-
"access": "private",
25-
"address": "10.0.0.1",
26-
"family": "IPv4",
27-
"ptr_record": "",
28-
"server": "006b6701-55d2-4374-ac40-56cc1501037f"
29-
},
30-
{
31-
"access": "public",
32-
"address": "x.x.x.x",
33-
"family": "IPv4",
34-
"part_of_plan": "yes",
35-
"ptr_record": "x-x-x-x.zone.upcloud.host",
36-
"server": "0053cd80-5945-4105-9081-11192806a8f7"
37-
},
38-
{
39-
"access": "public",
40-
"address": "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx",
41-
"family": "IPv6",
42-
"ptr_record": "xxxx-xxxx-xxxx-xxxx.v6.zone.upcloud.host",
43-
"server": "006b6701-55d2-4374-ac40-56cc1501037f"
44-
}
45-
]
46-
}
47-
}
48-
`
13+
{
14+
"ip_addresses": {
15+
"ip_address": [
16+
{
17+
"access": "utility",
18+
"address": "10.0.0.0",
19+
"family": "IPv4",
20+
"ptr_record": "",
21+
"server": "0053cd80-5945-4105-9081-11192806a8f7",
22+
"mac": "mm:mm:mm:mm:mm:m1",
23+
"floating": "no",
24+
"zone": "fi-hel2"
25+
},
26+
{
27+
"access": "utility",
28+
"address": "10.0.0.1",
29+
"family": "IPv4",
30+
"ptr_record": "",
31+
"server": "006b6701-55d2-4374-ac40-56cc1501037f",
32+
"mac": "mm:mm:mm:mm:mm:m2",
33+
"floating": "no",
34+
"zone": "de-fra1"
35+
},
36+
{
37+
"access": "public",
38+
"address": "x.x.x.x",
39+
"family": "IPv4",
40+
"part_of_plan": "yes",
41+
"ptr_record": "x-x-x-x.zone.upcloud.host",
42+
"server": "0053cd80-5945-4105-9081-11192806a8f7",
43+
"mac": "mm:mm:mm:mm:mm:m1",
44+
"floating": "yes",
45+
"zone": "de-fra1"
46+
},
47+
{
48+
"access": "public",
49+
"address": "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx",
50+
"family": "IPv6",
51+
"ptr_record": "xxxx-xxxx-xxxx-xxxx.v6.zone.upcloud.host",
52+
"server": "006b6701-55d2-4374-ac40-56cc1501037f",
53+
"mac": "mm:mm:mm:mm:mm:m3",
54+
"floating": "no",
55+
"zone": "fi-hel1"
56+
},
57+
{
58+
"access": "public",
59+
"address": "y.y.y.y",
60+
"family": "IPv4",
61+
"ptr_record": "y.y.y.y.zone.host.upcloud.com",
62+
"floating": "yes",
63+
"zone": "nl-ams1"
64+
}
65+
]
66+
}
67+
}
68+
`
4969

5070
ipAddresses := IPAddresses{}
5171
err := json.Unmarshal([]byte(originalJSON), &ipAddresses)
5272
assert.NoError(t, err)
53-
assert.Len(t, ipAddresses.IPAddresses, 4)
73+
assert.Len(t, ipAddresses.IPAddresses, 5)
5474

5575
testData := []IPAddress{
5676
{
57-
Access: IPAddressAccessPrivate,
77+
Access: IPAddressAccessUtility,
5878
Address: "10.0.0.0",
5979
Family: IPAddressFamilyIPv4,
6080
PTRRecord: "",
6181
ServerUUID: "0053cd80-5945-4105-9081-11192806a8f7",
82+
MAC: "mm:mm:mm:mm:mm:m1",
83+
Zone: "fi-hel2",
6284
},
6385
{
64-
Access: IPAddressAccessPrivate,
86+
Access: IPAddressAccessUtility,
6587
Address: "10.0.0.1",
6688
Family: IPAddressFamilyIPv4,
6789
PTRRecord: "",
6890
ServerUUID: "006b6701-55d2-4374-ac40-56cc1501037f",
91+
MAC: "mm:mm:mm:mm:mm:m2",
92+
Zone: "de-fra1",
6993
},
7094
{
7195
Access: IPAddressAccessPublic,
7296
Address: "x.x.x.x",
7397
Family: IPAddressFamilyIPv4,
74-
PartOfPlan: "yes",
98+
PartOfPlan: true,
7599
PTRRecord: "x-x-x-x.zone.upcloud.host",
76100
ServerUUID: "0053cd80-5945-4105-9081-11192806a8f7",
101+
Floating: true,
102+
MAC: "mm:mm:mm:mm:mm:m1",
103+
Zone: "de-fra1",
77104
},
78105
{
79106
Access: IPAddressAccessPublic,
80107
Address: "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx",
81108
Family: IPAddressFamilyIPv6,
82109
PTRRecord: "xxxx-xxxx-xxxx-xxxx.v6.zone.upcloud.host",
83110
ServerUUID: "006b6701-55d2-4374-ac40-56cc1501037f",
111+
MAC: "mm:mm:mm:mm:mm:m3",
112+
Zone: "fi-hel1",
113+
},
114+
{
115+
Access: IPAddressAccessPublic,
116+
Address: "y.y.y.y",
117+
Family: IPAddressFamilyIPv4,
118+
PTRRecord: "y.y.y.y.zone.host.upcloud.com",
119+
Floating: true,
120+
Zone: "nl-ams1",
84121
},
85122
}
86123

87124
for i, v := range testData {
88125
address := ipAddresses.IPAddresses[i]
89-
assert.Equal(t, v.Access, address.Access)
90-
assert.Equal(t, v.Address, address.Address)
91-
assert.Equal(t, v.Family, address.Family)
92-
assert.Equal(t, v.PTRRecord, address.PTRRecord)
93-
assert.Equal(t, v.ServerUUID, address.ServerUUID)
126+
assert.Equal(t, v, address)
94127
}
95128
}
96129

0 commit comments

Comments
 (0)