From b20be2e986e039cd7f1e03b8fabfc858288b076d Mon Sep 17 00:00:00 2001 From: AniJ98 Date: Wed, 25 Sep 2024 13:30:15 -0400 Subject: [PATCH] Support for Adding Additional Reserved IP to Existing Linodes (#581) --- instance_ips.go | 16 + instances.go | 2 + .../TestInstance_AddReservedIPToInstance.yaml | 397 ++++++ ...tance_AddReservedIPToInstanceVariants.yaml | 1109 +++++++++++++++++ ...e_CreateWithAlreadyAssignedReservedIP.yaml | 303 +++++ ...TestInstance_CreateWithEmptyIPAddress.yaml | 180 +++ ...nstance_CreateWithMultipleIPAddresses.yaml | 304 +++++ ...nce_CreateWithNonOwnedReservedAddress.yaml | 48 + ...Instance_CreateWithNonReservedAddress.yaml | 48 + .../TestInstance_CreateWithNullIPAddress.yaml | 134 ++ ..._CreateWithOwnedNonAssignedReservedIP.yaml | 258 ++++ ...tInstance_CreateWithReservedIPAddress.yaml | 259 ++++ ...e_CreateWithReservedIPAddressVariants.yaml | 748 +++++++++++ .../TestInstance_CreateWithoutIPv4Field.yaml | 134 ++ .../integration/instance_reserved_ips_test.go | 456 +++++++ 15 files changed, 4396 insertions(+) create mode 100644 test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml create mode 100644 test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithAlreadyAssignedReservedIP.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithEmptyIPAddress.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithMultipleIPAddresses.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithNonOwnedReservedAddress.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithNonReservedAddress.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithNullIPAddress.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithOwnedNonAssignedReservedIP.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithReservedIPAddress.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithReservedIPAddressVariants.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithoutIPv4Field.yaml create mode 100644 test/integration/instance_reserved_ips_test.go diff --git a/instance_ips.go b/instance_ips.go index 568be05eb..7a5ad62c6 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -79,6 +79,12 @@ type IPv6Range struct { Linodes []int `json:"linodes"` } +type InstanceReserveIPOptions struct { + Type string `json:"type"` + Public bool `json:"public"` + Address string `json:"address"` +} + // InstanceIPType constants start with IPType and include Linode Instance IP Types type InstanceIPType string @@ -144,3 +150,13 @@ func (c *Client) DeleteInstanceIPAddress(ctx context.Context, linodeID int, ipAd err := doDELETERequest(ctx, c, e) return err } + +// Function to add additional reserved IPV4 addresses to an existing linode +func (c *Client) AssignInstanceReservedIP(ctx context.Context, linodeID int, opts InstanceReserveIPOptions) (*InstanceIP, error) { + endpoint := formatAPIPath("linode/instances/%d/ips", linodeID) + response, err := doPOSTRequest[InstanceIP](ctx, c, endpoint, opts) + if err != nil { + return nil, err + } + return response, nil +} diff --git a/instances.go b/instances.go index 92eb6629a..31876598f 100644 --- a/instances.go +++ b/instances.go @@ -164,6 +164,8 @@ type InstanceCreateOptions struct { // Deprecated: group is a deprecated property denoting a group label for the Linode. Group string `json:"group,omitempty"` + + IPv4 []string `json:"ipv4,omitempty"` } // InstanceCreatePlacementGroupOptions represents the placement group diff --git a/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml b/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml new file mode 100644 index 000000000..8ff4312cc --- /dev/null +++ b/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml @@ -0,0 +1,397 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"test-instance-for-ip-reservation","root_pass":"5vJy-=\\NV\u003c1w`6!2Yf~6.2zN4L-zz5w\\2nWk0lH6Zq/}BN8[3Ou#37shHE-C3|rV"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63837282, "label": "test-instance-for-ip-reservation", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.79.160.146"], "ipv6": "2600:3c03::f03c:95ff:fe46:25ac/128", + "image": null, "region": "us-east", "site_type": "core", "specs": {"disk": 25600, + "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": {"cpu": + 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": 10000}, + "backups": {"enabled": false, "available": false, "schedule": {"day": null, + "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "aab21dc7e975cd72af77bb1dee30b501acd7d3b9", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "858" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:53:07 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "45.79.150.200", "gateway": "45.79.150.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-150-200.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "261" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:53:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"45.79.150.200"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837282/ips + method: POST + response: + body: '{"address": "45.79.150.200", "gateway": "45.79.150.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-150-200.ip.linodeusercontent.com", + "linode_id": 63837282, "region": "us-east", "vpc_nat_1_1": null, "reserved": + true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "265" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:53:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837282/ips + method: GET + response: + body: '{"ipv4": {"public": [{"address": "45.79.150.200", "gateway": "45.79.150.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "45-79-150-200.ip.linodeusercontent.com", "linode_id": 63837282, "region": + "us-east", "vpc_nat_1_1": null, "reserved": true}, {"address": "45.79.160.146", + "gateway": "45.79.160.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-160-146.ip.linodeusercontent.com", "linode_id": + 63837282, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}], "private": + [], "shared": [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": + "2600:3c03::f03c:95ff:fe46:25ac", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63837282, "region": + "us-east", "public": true}, "link_local": {"address": "fe80::f03c:95ff:fe46:25ac", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 63837282, "region": "us-east", "public": + false}, "global": []}}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:53:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - linodes:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.150.200 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:53:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837282 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:53:10 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml b/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml new file mode 100644 index 000000000..6239225d6 --- /dev/null +++ b/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml @@ -0,0 +1,1109 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"test-instance-for-ip-reservation","root_pass":"G2iB;VR!85]g1LXU^sC9zW;f\u00268168Ee\u003ca6g*td{r16tGq\u003cm4.^Yd''p$7UH,5-6BM"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63837167, "label": "test-instance-for-ip-reservation", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["97.107.141.56"], "ipv6": "2600:3c03::f03c:95ff:fe46:d62c/128", + "image": null, "region": "us-east", "site_type": "core", "specs": {"disk": 25600, + "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": {"cpu": + 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": 10000}, + "backups": {"enabled": false, "available": false, "schedule": {"day": null, + "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "aab21dc7e975cd72af77bb1dee30b501acd7d3b9", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "858" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:41 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "23.92.21.220", "gateway": "23.92.21.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-21-220.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "258" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:41 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"23.92.21.220"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"address": "23.92.21.220", "gateway": "23.92.21.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-21-220.ip.linodeusercontent.com", + "linode_id": 63837167, "region": "us-east", "vpc_nat_1_1": null, "reserved": + true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "262" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:41 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":false,"address":"23.92.21.220"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Cannot reserve a private address.", "field": "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "81" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:41 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "45.79.150.200", "gateway": "45.79.150.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-150-200.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "261" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:42 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"45.79.150.200"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63510870/ips + method: POST + response: + body: '{"errors": [{"reason": "Additional IPv4 addresses require technical justification. Please + contact support describing your requirement"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "138" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:42 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.150.200 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:42 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"23.92.21.220"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/888888/ips + method: POST + response: + body: '{"errors": [{"reason": "Not found"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:42 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 404 Not Found + code: 404 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"23.92.21.220"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Address must be currently unassigned.", "field": + "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "85" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:42 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"198.51.100.1"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Address must be reserved and must be currently + unassigned.", "field": "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "106" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:42 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"ca-central"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "172.105.0.89", "gateway": "172.105.0.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-0-89.ip.linodeusercontent.com", + "linode_id": null, "region": "ca-central", "vpc_nat_1_1": null, "reserved": + true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "262" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:43 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"172.105.0.89"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Address must belong to same region as linode.", + "field": "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "93" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv6","public":true,"address":"23.92.21.220"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Only addresses of type ipv4 are currently supported."}, + {"reason": "Address must be currently unassigned.", "field": "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "153" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":false,"address":"23.92.21.220"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Cannot reserve a private address.", "field": "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "81" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"12345"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": + "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "85" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":""}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": + "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "85" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":""}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": + "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "85" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":""}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167/ips + method: POST + response: + body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": + "address"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "85" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.0.89 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:44 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.21.220 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:44 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63837167 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 19:48:46 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithAlreadyAssignedReservedIP.yaml b/test/integration/fixtures/TestInstance_CreateWithAlreadyAssignedReservedIP.yaml new file mode 100644 index 000000000..7d995a2f6 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithAlreadyAssignedReservedIP.yaml @@ -0,0 +1,303 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "172.104.28.100", "gateway": "172.104.28.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-28-100.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "264" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:18 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-5joh9oqb2908","root_pass":"?Mw;l]:[\u00262x^pK4819J9y[=623gC0qlLFj9?\u003e2ia6RSM!HHpc1Z;NG3r3Kz.=Mb]","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.28.100"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63830251, "label": "go-test-ins-reserved-ip-5joh9oqb2908", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["172.104.28.100"], "ipv6": "2600:3c03::f03c:95ff:fea5:b601/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "e2b2194e60c6054585feb7014b294d65664c16a9", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:19 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-lm38753c0ooi","root_pass":"B8c03IyO8!+xfZt439xEpv#5n3H9HoJ^P\\^\u003c`2|XqgLZ9TDtXGq=04f\u003e4''$|.l}4","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.28.100"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Address must be currently unassigned.", "field": + "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "82" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63830251 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:21 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/172.104.28.100 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:22 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithEmptyIPAddress.yaml b/test/integration/fixtures/TestInstance_CreateWithEmptyIPAddress.yaml new file mode 100644 index 000000000..135f1d7d1 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithEmptyIPAddress.yaml @@ -0,0 +1,180 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-2erk03yy2m36","root_pass":".H?9RM6V''ixIX),:X+?UP6[[tdg4wpQ5EnccaV2,@+l8FSw@2F58\u003ci3o16Cn68?6","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":[""]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Too many requests"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "45" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:22 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "5" + status: 429 Too Many Requests + code: 429 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-2erk03yy2m36","root_pass":".H?9RM6V''ixIX),:X+?UP6[[tdg4wpQ5EnccaV2,@+l8FSw@2F58\u003ci3o16Cn68?6","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":[""]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Too many requests"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "45" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:25 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "5" + status: 429 Too Many Requests + code: 429 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-2erk03yy2m36","root_pass":".H?9RM6V''ixIX),:X+?UP6[[tdg4wpQ5EnccaV2,@+l8FSw@2F58\u003ci3o16Cn68?6","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":[""]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Too many requests"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "45" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:29 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "5" + status: 429 Too Many Requests + code: 429 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-2erk03yy2m36","root_pass":".H?9RM6V''ixIX),:X+?UP6[[tdg4wpQ5EnccaV2,@+l8FSw@2F58\u003ci3o16Cn68?6","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":[""]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:32 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithMultipleIPAddresses.yaml b/test/integration/fixtures/TestInstance_CreateWithMultipleIPAddresses.yaml new file mode 100644 index 000000000..bfd65fc05 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithMultipleIPAddresses.yaml @@ -0,0 +1,304 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "66.228.42.57", "gateway": "66.228.42.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-42-57.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "259" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:36 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-4rc1sui21a14","root_pass":"E1dxAxLSB0}\u003c977C=n+5u1g@x4tOx/,5rav03~W''7!]7#lgOJRLO.0Zm$}52f-LT","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["66.228.42.57","192.0.2.2"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Too many requests"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "45" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:36 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 429 Too Many Requests + code: 429 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-4rc1sui21a14","root_pass":"E1dxAxLSB0}\u003c977C=n+5u1g@x4tOx/,5rav03~W''7!]7#lgOJRLO.0Zm$}52f-LT","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["66.228.42.57","192.0.2.2"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Too many requests"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "45" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:39 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 429 Too Many Requests + code: 429 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-4rc1sui21a14","root_pass":"E1dxAxLSB0}\u003c977C=n+5u1g@x4tOx/,5rav03~W''7!]7#lgOJRLO.0Zm$}52f-LT","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["66.228.42.57","192.0.2.2"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Too many requests"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "45" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 429 Too Many Requests + code: 429 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-4rc1sui21a14","root_pass":"E1dxAxLSB0}\u003c977C=n+5u1g@x4tOx/,5rav03~W''7!]7#lgOJRLO.0Zm$}52f-LT","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["66.228.42.57","192.0.2.2"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:46 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/66.228.42.57 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:46 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithNonOwnedReservedAddress.yaml b/test/integration/fixtures/TestInstance_CreateWithNonOwnedReservedAddress.yaml new file mode 100644 index 000000000..31c14662f --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithNonOwnedReservedAddress.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-x34lc083oko4","root_pass":"}VsdSi,{!omez2A1BMU7J7p`41z1ER6-rs=hD,151f2\u003e/81q\\SJNg].Rz7Q=`Z\u00262","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["198.51.100.1"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:22 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithNonReservedAddress.yaml b/test/integration/fixtures/TestInstance_CreateWithNonReservedAddress.yaml new file mode 100644 index 000000000..bc8140ae9 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithNonReservedAddress.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-or7801td3le2","root_pass":"NJ361jSqj5#YLI;4I33S\u0026|C\\LlW74Bp!b9=g35b?[O0mU|7jnW''.ci*d)(0[9Pat","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["192.0.2.1"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:22 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithNullIPAddress.yaml b/test/integration/fixtures/TestInstance_CreateWithNullIPAddress.yaml new file mode 100644 index 000000000..127653d05 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithNullIPAddress.yaml @@ -0,0 +1,134 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-vym5299ve91d","root_pass":"!86lC/O''5Q3\u0026(H3vb0LD4@Tu0JaM''Wo0N4ja13yj~)?qUA/f@.x/0=aM60o=4mHB","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63830264, "label": "go-test-ins-reserved-ip-vym5299ve91d", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.56.104.17"], "ipv6": "2600:3c03::f03c:95ff:fea5:b690/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "c6618489f09422003470c02e7f12a3e0b5303ddb", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:34 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63830264 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:36 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithOwnedNonAssignedReservedIP.yaml b/test/integration/fixtures/TestInstance_CreateWithOwnedNonAssignedReservedIP.yaml new file mode 100644 index 000000000..7eeb83aae --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithOwnedNonAssignedReservedIP.yaml @@ -0,0 +1,258 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "172.104.28.70", "gateway": "172.104.28.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-28-70.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "262" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:14 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-vsr6v8p5t918","root_pass":"SO#sQ!0],LgsF3BJ0B(5\u003e}By6q2+\u0026c1fi{C\u0026f4=c?x2R!@Eiz+4iT742G7eb9JC7","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.28.70"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63830249, "label": "go-test-ins-reserved-ip-vsr6v8p5t918", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["172.104.28.70"], "ipv6": "2600:3c03::f03c:95ff:fea5:b656/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "e2b2194e60c6054585feb7014b294d65664c16a9", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:15 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63830249 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:17 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/172.104.28.70 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:17 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithReservedIPAddress.yaml b/test/integration/fixtures/TestInstance_CreateWithReservedIPAddress.yaml new file mode 100644 index 000000000..6615c2205 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithReservedIPAddress.yaml @@ -0,0 +1,259 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "172.104.20.68", "gateway": "172.104.20.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-20-68.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "262" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:05 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-x0or7k0186hu","root_pass":"?6I~^OU95=viKV8$wb,Q=`dUCjq8x''8l^z0m4KD~8c6F\u003e-6\u003eW60I6Cf6Ln2#Gca$","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.20.68"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63432426, "label": "go-test-ins-reserved-ip-x0or7k0186hu", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["172.104.20.68"], "ipv6": "2600:3c03::f03c:95ff:fec2:4ccc/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "d5c60a121fe8f306350b432af2263337c9e0495a", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "857" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:06 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63432426 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/172.104.20.68 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithReservedIPAddressVariants.yaml b/test/integration/fixtures/TestInstance_CreateWithReservedIPAddressVariants.yaml new file mode 100644 index 000000000..d7c1fd9b2 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithReservedIPAddressVariants.yaml @@ -0,0 +1,748 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips + method: POST + response: + body: '{"address": "172.104.20.77", "gateway": "172.104.20.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-20-77.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "262" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-776ugys2x84t","root_pass":"9Nf1L;\u003e6ajieNPt\\X+2gP+8~rB`uJ22c;\u003e03C9Na40J}-}:)lQlj1[Y7qs-59UFV","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.20.77"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63432429, "label": "go-test-ins-reserved-ip-776ugys2x84t", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["172.104.20.77"], "ipv6": "2600:3c03::f03c:95ff:fec2:4c1b/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "d5c60a121fe8f306350b432af2263337c9e0495a", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "857" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:09 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-k834ai1y8j2a","root_pass":"~um0O^Z`j5S=4tRxo(4pAn+;8eA4[2?zWOg5[8P3szYRfx;9X97|f4~8V:2QM=\u003eU","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.20.77"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Address must be currently unassigned.", "field": + "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "82" + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:09 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-k13vw921yh5i","root_pass":"@g\\27J,2J$aX5xj$4v-\u003c3,Ny7nc5{WvY:''pDH7Vj1E45:9MjxP{=s14Kv$b-S5SD","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["192.0.2.1"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:09 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-k7zhi2807xk8","root_pass":"0BDN\\iia1C`\u0026O45tXS4[@7;0lF8)W+k[NRn6v3Y5ZtM/8e81xpwT[)i[f-\\-H1u4","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["198.51.100.1"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:09 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-n9ssc0141zh7","root_pass":":LD8t4cgg|164/p=L151I3\\WdMAkw]Vw3O5;+E)bAg,9\\b58Sc`u5`d)E\u003e3]GBZk","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":[""]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:22 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-e14gz6bc5p37","root_pass":"KjQ13TO2`g}huOSKKe3988}([j(o#[P]]e08tXUqd=?B3A87l12hOlU4I|\u003el9\u003eh/","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63432443, "label": "go-test-ins-reserved-ip-e14gz6bc5p37", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["97.107.138.251"], "ipv6": "2600:3c03::f03c:95ff:fec2:4c10/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "9c7219f8e3e33875047e6b169b3f167a43218198", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "858" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:38 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-3bly0ps6071m","root_pass":"H`X!T5x{D.4(J3k05dY,1IG=T/6e87DoN\\6DF@Bp8?4/.Nscw=qxn{4W4cluv91''","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["172.104.20.77","192.0.2.2"]}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"errors": [{"reason": "Must provide a single valid reserved ipv4 address", + "field": "ipv4"}]}' + headers: + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "94" + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:38 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-bw5b43pih670","root_pass":"wqx^Q)\u003ca\u0026))H`MV4n+ZT6geC53w3jV(n{F6JzG9G5h01jw97;/FxFi6HR?=:\\640","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63432444, "label": "go-test-ins-reserved-ip-bw5b43pih670", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.33.68.112"], "ipv6": "2600:3c03::f03c:95ff:fec2:4c8b/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "feeaaa559bcc85eaf49df4ff34238607aee5ad94", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "856" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:39 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63432444 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:41 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63432443 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:43 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63432429 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:44 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/networking/reserved/ips/172.104.20.77 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Sep 2024 19:13:44 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestInstance_CreateWithoutIPv4Field.yaml b/test/integration/fixtures/TestInstance_CreateWithoutIPv4Field.yaml new file mode 100644 index 000000000..9f8cd4544 --- /dev/null +++ b/test/integration/fixtures/TestInstance_CreateWithoutIPv4Field.yaml @@ -0,0 +1,134 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-reserved-ip-le6w459su62x","root_pass":"j\\9[AV1,4@91t=V7nB2;QW8~dsmoWfK,b@A9g-K\u003cRr3xBn{11|i8TJzc\u0026:Q$H663","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 63830274, "label": "go-test-ins-reserved-ip-le6w459su62x", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.56.104.28"], "ipv6": "2600:3c03::f03c:95ff:fea5:92e5/128", + "image": "linode/alpine3.17", "region": "us-east", "site_type": "core", "specs": + {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": + {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": + 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": + null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "c6618489f09422003470c02e7f12a3e0b5303ddb", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:48 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/63830274 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 12 Sep 2024 16:44:50 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/instance_reserved_ips_test.go b/test/integration/instance_reserved_ips_test.go new file mode 100644 index 000000000..e1f55af61 --- /dev/null +++ b/test/integration/instance_reserved_ips_test.go @@ -0,0 +1,456 @@ +package integration + +import ( + "context" + "testing" + + "github.com/linode/linodego" +) + +func TestInstance_CreateWithReservedIPAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithReservedIPAddress") + defer teardown() + + // Reserve an IP for testing + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: "us-east"}) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + defer func() { + err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Errorf("Failed to delete reserved IP: %v", err) + } + }() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + defer instanceTeardown() + if err != nil { + t.Fatalf("Error creating instance with reserved IP: %s", err) + } + +} + +func createInstanceWithReservedIP( + t *testing.T, + client *linodego.Client, + reservedIP string, + modifiers ...instanceModifier, +) (*linodego.Instance, func(), error) { + t.Helper() + + createOpts := linodego.InstanceCreateOptions{ + Label: "go-test-ins-reserved-ip-" + randLabel(), + Region: "us-east", + Type: "g6-nanode-1", + Booted: linodego.Pointer(false), + Image: "linode/alpine3.17", + RootPass: randPassword(), + Interfaces: []linodego.InstanceConfigInterfaceCreateOptions{ + { + Purpose: linodego.InterfacePurposePublic, + Label: "", + IPAMAddress: "", + }, + }, + IPv4: []string{reservedIP}, + } + + for _, modifier := range modifiers { + modifier(client, &createOpts) + } + + instance, err := client.CreateInstance(context.Background(), createOpts) + if err != nil { + return nil, func() {}, err + } + + teardown := func() { + if terr := client.DeleteInstance(context.Background(), instance.ID); terr != nil { + t.Errorf("Error deleting test Instance: %s", terr) + } + } + + return instance, teardown, nil +} + +func TestInstance_CreateWithOwnedNonAssignedReservedIP(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithOwnedNonAssignedReservedIP") + defer teardown() + + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: "us-east"}) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + defer func() { + err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Errorf("Failed to delete reserved IP: %v", err) + } + }() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + defer instanceTeardown() + if err != nil { + t.Errorf("Unexpected error with owned non-assigned reserved IP: %v", err) + } +} + +func TestInstance_CreateWithAlreadyAssignedReservedIP(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithAlreadyAssignedReservedIP") + defer teardown() + + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: "us-east"}) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + defer func() { + err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Errorf("Failed to delete reserved IP: %v", err) + } + }() + + // First, create an instance with the reserved IP + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + defer instanceTeardown() + if err != nil { + t.Fatalf("Failed to create initial instance: %v", err) + } + + // Now try to create another instance with the same IP + _, secondInstanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + defer secondInstanceTeardown() + if err == nil { + t.Errorf("Expected error with already assigned reserved IP, but got none") + } +} + +func TestInstance_CreateWithNonReservedAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonReservedAddress") + defer teardown() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "192.0.2.1") + defer instanceTeardown() + if err == nil { + t.Errorf("Expected error with non-reserved address, but got none") + } +} + +func TestInstance_CreateWithNonOwnedReservedAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonOwnedReservedAddress") + defer teardown() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "198.51.100.1") + defer instanceTeardown() + if err == nil { + t.Errorf("Expected error with non-owned reserved address, but got none") + } +} + +func TestInstance_CreateWithEmptyIPAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithEmptyIPAddress") + defer teardown() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "") + defer instanceTeardown() + if err == nil { + t.Errorf("Expected error with empty IP address, but got none") + } +} + +func TestInstance_CreateWithNullIPAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNullIPAddress") + defer teardown() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + opts.IPv4 = nil + }) + defer instanceTeardown() + if err != nil { + t.Errorf("Unexpected error with null IP address: %v", err) + } +} + +func TestInstance_CreateWithMultipleIPAddresses(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithMultipleIPAddresses") + defer teardown() + + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: "us-east"}) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + defer func() { + err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Errorf("Failed to delete reserved IP: %v", err) + } + }() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + opts.IPv4 = []string{reservedIP.Address, "192.0.2.2"} + }) + defer instanceTeardown() + if err == nil { + t.Errorf("Expected error with multiple IP addresses, but got none") + } +} + +func TestInstance_CreateWithoutIPv4Field(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithoutIPv4Field") + defer teardown() + + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + opts.IPv4 = nil + }) + defer instanceTeardown() + if err != nil { + t.Errorf("Unexpected error when omitting IPv4 field: %v", err) + } +} + +func TestInstance_AddReservedIPToInstance(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_AddReservedIPToInstance") + defer teardown() + + // Create a test Linode instance + instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ + Region: "us-east", + Type: "g6-nanode-1", + Label: "test-instance-for-ip-reservation", + RootPass: randPassword(), + }) + if err != nil { + t.Fatalf("Error creating test instance: %v", err) + } + defer func() { + if err := client.DeleteInstance(context.Background(), instance.ID); err != nil { + t.Errorf("Error deleting test instance: %v", err) + } + }() + + // Reserve an IP address + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "us-east", + }) + if err != nil { + t.Fatalf("Error reserving IP address: %v", err) + } + defer func() { + if err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address); err != nil { + t.Errorf("Error deleting reserved IP: %v", err) + } + }() + + // Add the reserved IP to the instance + opts := linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: reservedIP.Address, + } + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, opts) + if err != nil { + t.Fatalf("Error adding reserved IP to instance: %v", err) + } + + // Verify the IP was added to the instance + ips, err := client.GetInstanceIPAddresses(context.Background(), instance.ID) + if err != nil { + t.Fatalf("Error getting instance IP addresses: %v", err) + } + + found := false + for _, ip := range ips.IPv4.Public { + if ip.Address == reservedIP.Address { + found = true + break + } + } + + if !found { + t.Errorf("Reserved IP %s was not found in instance's IP addresses", reservedIP.Address) + } +} + +func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_AddReservedIPToInstanceVariants") + defer teardown() + + // Create a test Linode instance + instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ + Region: "us-east", + Type: "g6-nanode-1", + Label: "test-instance-for-ip-reservation", + RootPass: randPassword(), + }) + if err != nil { + t.Fatalf("Error creating test instance: %v", err) + } + defer func() { + if err := client.DeleteInstance(context.Background(), instance.ID); err != nil { + t.Errorf("Error deleting test instance: %v", err) + } + }() + + // Reserve an IP address + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "us-east", + }) + if err != nil { + t.Fatalf("Error reserving IP address: %v", err) + } + defer func() { + if err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address); err != nil { + t.Errorf("Error deleting reserved IP: %v", err) + } + }() + + // Test: Add reserved IP to instance with valid parameters + opts := linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: reservedIP.Address, + } + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, opts) + if err != nil { + t.Fatalf("Error adding reserved IP to instance: %v", err) + } + + // Test: Omit public field + omitPublicOpts := linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Address: reservedIP.Address, + // Public field is omitted here + } + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, omitPublicOpts) + if err == nil { + t.Fatalf("Expected error when adding reserved IP with omitted public field, but got none") + } + + // Assume we have a Linode that has been created without a reserved IP address and IPMAX set to 1 + linodeID := 63510870 + + // Reserve IP address + resIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "us-east", + }) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + + // Add IP address to the Linode + _, err = client.AssignInstanceReservedIP(context.Background(), linodeID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: resIP.Address, + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP to a Linode at its IPMAX limit, but got none") + } + + // Delete the reserved IP Address + + if err := client.DeleteReservedIPAddress(context.Background(), resIP.Address); err != nil { + t.Errorf("Failed to delete first reserved IP: %v", err) + } + + // Test: Non-owned Linode ID + nonOwnedInstanceID := 888888 // Replace with an actual non-owned Linode ID + _, err = client.AssignInstanceReservedIP(context.Background(), nonOwnedInstanceID, opts) + if err == nil { + t.Errorf("Expected error when adding reserved IP to non-owned Linode, but got none") + } + + // Test: Already assigned reserved IP + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, opts) + if err == nil { + t.Errorf("Expected error when adding already assigned reserved IP, but got none") + } + + // Test: Non-owned reserved IP + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: "198.51.100.1", // Assume this is a non-owned reserved IP + }) + if err == nil { + t.Errorf("Expected error when adding non-owned reserved IP, but got none") + } + + // Test: Reserved IP in different datacenter + // Reserve an IP address + diffDataCentreIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "ca-central", + }) + if err != nil { + t.Fatalf("Error reserving IP address: %v", err) + } + defer func() { + if err := client.DeleteReservedIPAddress(context.Background(), diffDataCentreIP.Address); err != nil { + t.Errorf("Error deleting reserved IP: %v", err) + } + }() + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: diffDataCentreIP.Address, // Assume this IP is in a different datacenter + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP in different datacenter, but got none") + } + + // Test: IPv6 type + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv6", + Public: true, + Address: reservedIP.Address, + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with type ipv6, but got none") + } + + // Test: Public field set to false + opts.Public = false + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, opts) + if err == nil { + t.Errorf("Expected error when adding reserved IP with public field set to false, but got none") + } + + // Test: Integer as address + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: "12345", // Invalid IP format + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with integer as address, but got none") + } + + // Test: Empty address + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + Address: "", + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with empty address, but got none") + } + + // Test: Null address + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with null address, but got none") + } + + // Test: Omit address field + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + }) + if err == nil { + t.Errorf("Expected error when omitting address field, but got none") + } +}