From 1b87e787a6e35c3497849fc8989859eea089ead5 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 22 Aug 2024 16:16:05 -0400 Subject: [PATCH 01/43] added reserved field to InstanceIP struct for IP Reservation response --- instance_ips.go | 1 + 1 file changed, 1 insertion(+) diff --git a/instance_ips.go b/instance_ips.go index 0d86bd91c..568be05eb 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -31,6 +31,7 @@ type InstanceIP struct { LinodeID int `json:"linode_id"` Region string `json:"region"` VPCNAT1To1 *InstanceIPNAT1To1 `json:"vpc_nat_1_1"` + Reserved bool `json:"reserved"` } // VPCIP represents a private IP address in a VPC subnet with additional networking details From 311ecfcbeb026f8cb14040178a78451c940e11a0 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 22 Aug 2024 16:30:00 -0400 Subject: [PATCH 02/43] Reserved IP resource for handling IP reservation API's --- network_reserved_ips.go | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 network_reserved_ips.go diff --git a/network_reserved_ips.go b/network_reserved_ips.go new file mode 100644 index 000000000..02ff1c7a7 --- /dev/null +++ b/network_reserved_ips.go @@ -0,0 +1,49 @@ +package linodego + +import ( + "context" +) + +// ReserveIPOptions represents the options for reserving an IP address +type ReserveIPOptions struct { + Region string `json:"region"` +} + +// GetReservedIPs retrieves a list of reserved IP addresses +func (c *Client) GetReservedIPs(ctx context.Context, opts *ListOptions) ([]InstanceIP, error) { + e := formatAPIPath("networking/reserved/ips") + response, err := getPaginatedResults[InstanceIP](ctx, c, e, opts) + if err != nil { + return nil, err + } + + return response, nil +} + +// GetReservedIPAddress retrieves details of a specific reserved IP address +func (c *Client) GetReservedIPAddress(ctx context.Context, id string) (*InstanceIP, error) { + e := formatAPIPath("networking/reserved/ips/%s", id) + response, err := doGETRequest[InstanceIP](ctx, c, e) + if err != nil { + return nil, err + } + + return response, nil +} + +// ReserveIPAddress reserves a new IP address +func (c *Client) ReserveIPAddress(ctx context.Context, opts ReserveIPOptions) (*InstanceIP, error) { + e := "networking/reserved/ips" + response, err := doPOSTRequest[InstanceIP](ctx, c, e, opts) + if err != nil { + return nil, err + } + + return response, nil +} + +// DeleteReservedIPAddress deletes a reserved IP address +func (c *Client) DeleteReservedIPAddress(ctx context.Context, ipAddress string) error { + e := formatAPIPath("networking/reserved/ips/%s", ipAddress) + return doDELETERequest(ctx, c, e) +} From 7fb337e059f5a857258aa5bffea95487016d9792 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 22 Aug 2024 16:33:39 -0400 Subject: [PATCH 03/43] Added integration test covering multiple scenarios of reserving IP addresses --- test/integration/network_reserved_ips_test.go | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 test/integration/network_reserved_ips_test.go diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go new file mode 100644 index 000000000..9b8548df0 --- /dev/null +++ b/test/integration/network_reserved_ips_test.go @@ -0,0 +1,284 @@ +package integration + +import ( + "context" + "os" + "testing" + + . "github.com/linode/linodego" +) + +// TestReservedIPAddresses_InsufficientPermissions tests the behavior when a user account +// doesn't have the can_reserve_ip flag enabled +func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { + original := os.Getenv("LINODE_TOKEN") + dummyToken := "badtoken" + os.Setenv("LINODE_TOKEN", dummyToken) + + client, teardown := createTestClient(t, "fixtures/TestReservedIpAddresses_InsufficientPermissions") + defer teardown() + defer os.Setenv("LINODE_TOKEN", original) + + filter := "" + i, getReservedIpsError := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if getReservedIpsError != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", getReservedIpsError) + } + + if len(i) == 0 { + t.Logf("Expected a list of ipaddresses, but got none %v", i) + } + + // Attempt to reserve an IP address + reservedIp, reserveIpError := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + if reserveIpError != nil { + t.Logf("Failed to reserve IP: %v", reserveIpError) + } else { + t.Logf("Successfully reserved IP: %+v", reservedIp) + } + + // Attempt to get a reserved IP address + address := "172.28.3.4" + ipaddress, getReservedIpError := client.GetReservedIPAddress(context.Background(), address) + if getReservedIpError != nil { + t.Logf("Error getting ipaddress, expected struct, got %v and error %v", ipaddress, getReservedIpError) + } + + // Attempt to delete a reserved IP address + addressToBeDeleted := "172.28.3.4" + deleterr := client.DeleteReservedIPAddress(context.Background(), addressToBeDeleted) + if deleterr != nil { + t.Logf("Error deleting reserved IP address: %v", deleterr) + } else { + t.Logf("Successfully deleted reserved IP address: %s", addressToBeDeleted) + } +} + +// TestReservedIPAddresses_EndToEndTest performs an end-to-end test of the Reserved IP functionality +// for users with the can_reserve_ip flag enabled +func TestReservedIPAddresses_EndToEndTest(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIpAddresses_EndToEndTest") + defer teardown() + + filter := "" + ipList, listIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if listIpErr != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", listIpErr) + } else { + if len(ipList) == 0 { + t.Logf("The customer has not reserved an IP %v", ipList) + } + } + + // Attempt to reserve an IP + reserveIP, reserveIpErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + if reserveIpErr != nil { + t.Logf("Failed to reserve IP: %v", reserveIpErr) + } else { + t.Logf("Successfully reserved IP: %+v", reserveIP) + } + + if reserveIP != nil { + // Fetch the reserved IP + reservedIP, fetchIpErr := client.GetReservedIPAddress(context.Background(), reserveIP.Address) + if fetchIpErr != nil { + t.Logf("Error getting ipaddress, expected struct, got %v and error %v", reservedIP, fetchIpErr) + } + + // Verify the list of IPs has increased + verifyList, verifyListIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if verifyListIpErr != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", verifyListIpErr) + } else { + if len(verifyList)-len(ipList) == 1 { + t.Log("Increase in IP list confirmed", verifyList) + } else { + t.Errorf("Increase in IP list not confirmed") + } + } + + // Delete the reserved IP + if reserveIP != nil { + deleteErr := client.DeleteReservedIPAddress(context.Background(), reserveIP.Address) + if deleteErr != nil { + t.Logf("Error deleting reserved IP address: %v", deleteErr) + } else { + t.Logf("Successfully deleted reserved IP address: %s", reserveIP.Address) + } + } + + // Verify the IP has been deleted + if reserveIP != nil { + verifyDeletedIP, fetchDeletedIpErr := client.GetReservedIPAddress(context.Background(), reserveIP.Address) + if fetchDeletedIpErr != nil { + t.Logf("Error getting ipaddress, expected struct, got %v and error %v", verifyDeletedIP, fetchDeletedIpErr) + } + + verifyDeletedFromList, verifyDeletedFromListIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if verifyDeletedFromListIpErr != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", verifyDeletedFromListIpErr) + } else { + if len(verifyDeletedFromList) < len(verifyList) { + t.Log("IP address deletion confirmed", verifyDeletedFromList) + } else { + t.Errorf("Verification - Failed") + } + } + } + } +} + +// TestReservedIPAddresses_ListIPAddressesVariants tests various scenarios for listing IP addresses +func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") + defer teardown() + + filter := "" + ipList, listIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if listIpErr != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", listIpErr) + } else { + if len(ipList) == 0 { + t.Logf("The customer has not reserved an IP %v", ipList) + } + } +} + +// TestReservedIPAddresses_GetIPAddressVariants tests various scenarios for getting a specific IP address +func TestReservedIPAddresses_GetIPAddressVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_GetIPAddressVariants") + defer teardown() + + // Reserve an IP for testing + reserveIP, reserveIpErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + if reserveIpErr != nil { + t.Logf("Failed to reserve IP: %v", reserveIpErr) + } else { + t.Logf("Successfully reserved IP: %+v", reserveIP) + } + + if reserveIP != nil { + // Test getting a valid reserved IP + validReservedIP, validFetchIpErr := client.GetReservedIPAddress(context.Background(), reserveIP.Address) + if validFetchIpErr != nil { + t.Logf("Error getting ipaddress, expected struct, got %v and error %v", validReservedIP, validFetchIpErr) + } + + // Test getting an invalid IP + invalidReservedIP, invalidFetchIpErr := client.GetReservedIPAddress(context.Background(), "INVALID_IP") + if invalidFetchIpErr != nil { + t.Logf("Error getting ipaddress, expected struct, got %v and error %v", invalidReservedIP, invalidFetchIpErr) + } + } +} + +// TestReservedIPAddresses_ReserveIPVariants tests various scenarios for reserving an IP address +func TestReservedIPAddresses_ReserveIPVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ReserveIPVariants") + defer teardown() + + // Test reserving IP with omitted region + omitRegion, omitRegionErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{}) + if omitRegionErr != nil { + t.Logf("Failed to reserve IP: %v", omitRegionErr) + } else { + t.Logf("Successfully reserved IP: %+v", omitRegion) + } + + // Test reserving IP with invalid region + invalidRegion, invalidRegionErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us", + }) + if invalidRegionErr != nil { + t.Logf("Failed to reserve IP: %v", invalidRegionErr) + } else { + t.Logf("Successfully reserved IP: %+v", invalidRegion) + } + + // Test reserving IP with empty region + emptyRegion, emptyRegionErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "", + }) + if emptyRegionErr != nil { + t.Logf("Failed to reserve IP: %v", emptyRegionErr) + } else { + t.Logf("Successfully reserved IP: %+v", emptyRegion) + } + + // Test valid IP reservation + validReservation, validReservationErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + if validReservationErr != nil { + t.Logf("Failed to reserve IP: %v", validReservationErr) + } else { + t.Logf("Successfully reserved IP: %+v", validReservation) + } + + // Test exceeding reservation limit + exceedReservationLimit, exceedReservationErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + if exceedReservationErr != nil { + t.Logf("Failed to reserve IP: %v", exceedReservationErr) + } else { + t.Logf("Successfully reserved IP: %+v", exceedReservationLimit) + } +} + +// TestReservedIPAddresses_DeleteIPAddressVariants tests various scenarios for deleting a reserved IP address +func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_DeleteIPAddressVariants") + defer teardown() + + filter := "" + ipList, listIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if listIpErr != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", listIpErr) + } else { + if len(ipList) == 0 { + t.Logf("The customer has not reserved an IP %v", ipList) + } + } + + if len(ipList) > 0 { + ipToBeDeleted := ipList[len(ipList)-1] + deleteErr := client.DeleteReservedIPAddress(context.Background(), ipToBeDeleted.Address) + if deleteErr != nil { + t.Logf("Error deleting reserved IP address: %v", deleteErr) + } else { + t.Logf("Successfully deleted reserved IP address: %s", ipToBeDeleted.Address) + } + + // Verify deletion + verifyDeletedFromList, verifyDeletedFromListIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) + if verifyDeletedFromListIpErr != nil { + t.Logf("Error listing ipaddresses, expected struct, got error %v", verifyDeletedFromListIpErr) + } else { + if len(verifyDeletedFromList) < len(ipList) { + t.Log("IP address deletion confirmed", verifyDeletedFromList) + } else { + t.Errorf("Verification - Failed") + } + } + + verifyDeletedIP, fetchDeletedIpErr := client.GetReservedIPAddress(context.Background(), ipToBeDeleted.Address) + if fetchDeletedIpErr != nil { + t.Logf("IP address not found got %v and error %v", verifyDeletedIP, fetchDeletedIpErr) + } + + // Test deleting an unowned IP + deletingUnownedIPErr := client.DeleteReservedIPAddress(context.Background(), "255.255.255.4") + if deletingUnownedIPErr != nil { + t.Logf("Error deleting reserved IP address: %v", deletingUnownedIPErr) + } else { + t.Logf("Successfully deleted reserved IP address: %s", "255.255.255.4") + } + } +} From 1c6a8ab3589eab08aa674bf32590fc7c7c52eba4 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 22 Aug 2024 16:35:00 -0400 Subject: [PATCH 04/43] The fixture files for different scenarios of IP Reservation - EndToEnd, InsuffecientPermission, ReserveIP, GetReservedIP, getReservedIPs, DeleteReservedIPs --- ...edIPAddresses_DeleteIPAddressVariants.yaml | 50 ++++ ...ervedIPAddresses_GetIPAddressVariants.yaml | 46 ++++ ...edIPAddresses_ListIPAddressesVariants.yaml | 50 ++++ ...ReservedIPAddresses_ReserveIPVariants.yaml | 218 ++++++++++++++++++ .../TestReservedIpAddresses_EndToEndTest.yaml | 93 ++++++++ ...edIpAddresses_InsufficientPermissions.yaml | 185 +++++++++++++++ 6 files changed, 642 insertions(+) create mode 100644 test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml create mode 100644 test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml create mode 100644 test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml create mode 100644 test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml create mode 100644 test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml create mode 100644 test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml diff --git a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml new file mode 100644 index 000000000..e7f61c413 --- /dev/null +++ b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- 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?page=1 + method: GET + response: + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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 + Connection: + - keep-alive + Content-Length: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:45 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml new file mode 100644 index 000000000..ae96cd3a3 --- /dev/null +++ b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml @@ -0,0 +1,46 @@ +--- +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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml new file mode 100644 index 000000000..cd17f05e6 --- /dev/null +++ b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- 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?page=1 + method: GET + response: + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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 + Connection: + - keep-alive + Content-Length: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml new file mode 100644 index 000000000..e2b30cd0b --- /dev/null +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -0,0 +1,218 @@ +--- +version: 1 +interactions: +- request: + body: '{"region":""}' + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" +- request: + body: '{"region":"us"}' + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" +- request: + body: '{"region":""}' + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:45 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:45 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" diff --git a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml b/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml new file mode 100644 index 000000000..860bfd5af --- /dev/null +++ b/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml @@ -0,0 +1,93 @@ +--- +version: 1 +interactions: +- 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?page=1 + method: GET + response: + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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 + Connection: + - keep-alive + Content-Length: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" diff --git a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml new file mode 100644 index 000000000..47d76dfdd --- /dev/null +++ b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml @@ -0,0 +1,185 @@ +--- +version: 1 +interactions: +- 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?page=1 + method: GET + response: + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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 + Connection: + - keep-alive + Content-Length: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:43 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + 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: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:43 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + 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.28.3.4 + method: GET + response: + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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 + Connection: + - keep-alive + Content-Length: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:43 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + 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.28.3.4 + method: DELETE + response: + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' + 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 + Connection: + - keep-alive + Content-Length: + - "97" + Content-Type: + - application/json + Expires: + - Thu, 22 Aug 2024 20:10:44 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + status: 404 Not Found + code: 404 + duration: "" From fd426cca00d274f0409a002997b731d91801844b Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 26 Aug 2024 14:36:58 -0400 Subject: [PATCH 05/43] Updated the fixture files with responses after the user has permissions to reserve IP --- ...edIPAddresses_DeleteIPAddressVariants.yaml | 249 +++++++++++++++++- ...ervedIPAddresses_GetIPAddressVariants.yaml | 14 +- ...edIPAddresses_ListIPAddressesVariants.yaml | 33 ++- ...ReservedIPAddresses_ReserveIPVariants.yaml | 67 ++--- .../TestReservedIpAddresses_EndToEndTest.yaml | 47 +++- ...edIpAddresses_InsufficientPermissions.yaml | 80 ++++-- 6 files changed, 412 insertions(+), 78 deletions(-) diff --git a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml index e7f61c413..99bf19d0f 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml @@ -14,15 +14,24 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, + {"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], + "page": 1, "pages": 1, "results": 2}' 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: @@ -30,21 +39,253 @@ interactions: Connection: - keep-alive Content-Length: - - "97" + - "570" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:45 GMT + - Mon, 26 Aug 2024 18:31:11 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 Vary: - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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/45.33.69.212 + 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: + - Mon, 26 Aug 2024 18:31:11 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?page=1 + method: GET + response: + body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], + "page": 1, "pages": 1, "results": 1}' + 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: + - "310" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 18:31:11 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter X-Accepted-Oauth-Scopes: - ips:read_only + 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/45.33.69.212 + method: GET + 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 + Connection: + - keep-alive + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 18:31:11 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 404 Not Found + code: 404 + 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/255.255.255.4 + method: DELETE + 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 + Connection: + - keep-alive + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 18:31:11 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write X-Frame-Options: - DENY X-Oauth-Scopes: - '*' + X-Ratelimit-Limit: + - "10" status: 404 Not Found code: 404 duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml index ae96cd3a3..0f8e92017 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml @@ -14,8 +14,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "Additional Reserved 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 @@ -28,11 +28,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "147" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:10 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -41,6 +41,8 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml index cd17f05e6..fdc11bca4 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml @@ -14,15 +14,24 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, + {"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], + "page": 1, "pages": 1, "results": 2}' 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: @@ -30,21 +39,33 @@ interactions: Connection: - keep-alive Content-Length: - - "97" + - "570" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:09 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 Vary: - Authorization, X-Filter + - Authorization, X-Filter X-Accepted-Oauth-Scopes: - ips:read_only + X-Content-Type-Options: + - nosniff X-Frame-Options: - DENY + - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml index e2b30cd0b..4a0d24b05 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -14,8 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "region is not valid", "field": "region"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -28,11 +27,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "66" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:10 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -41,8 +40,10 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" - request: body: '{"region":"us"}' @@ -57,8 +58,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "region is not valid", "field": "region"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -71,11 +71,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "66" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:10 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -84,8 +84,10 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" - request: body: '{"region":""}' @@ -100,8 +102,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "region is not valid", "field": "region"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -114,11 +115,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "66" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:10 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -127,8 +128,10 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" - request: body: '{"region":"us-east"}' @@ -143,8 +146,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "Additional Reserved 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 @@ -157,11 +160,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "147" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:45 GMT + - Mon, 26 Aug 2024 18:31:10 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -170,8 +173,10 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" - request: body: '{"region":"us-east"}' @@ -186,8 +191,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "Additional Reserved 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 @@ -200,11 +205,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "147" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:45 GMT + - Mon, 26 Aug 2024 18:31:11 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -213,6 +218,8 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" diff --git a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml b/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml index 860bfd5af..cc6e5f5ce 100644 --- a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml +++ b/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml @@ -14,15 +14,24 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, + {"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], + "page": 1, "pages": 1, "results": 2}' 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: @@ -30,23 +39,35 @@ interactions: Connection: - keep-alive Content-Length: - - "97" + - "570" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:09 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 Vary: - Authorization, X-Filter + - Authorization, X-Filter X-Accepted-Oauth-Scopes: - ips:read_only + X-Content-Type-Options: + - nosniff X-Frame-Options: - DENY + - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 duration: "" - request: body: '{"region":"us-east"}' @@ -61,8 +82,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "Additional Reserved 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 @@ -75,11 +96,11 @@ interactions: Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "97" + - "147" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:09 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -88,6 +109,8 @@ interactions: - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 duration: "" diff --git a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml index 47d76dfdd..70589d0c5 100644 --- a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml +++ b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml @@ -14,15 +14,21 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], + "page": 1, "pages": 1, "results": 1}' 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: @@ -30,23 +36,35 @@ interactions: Connection: - keep-alive Content-Length: - - "97" + - "310" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:43 GMT + - Mon, 26 Aug 2024 18:31:02 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 Vary: - Authorization, X-Filter + - Authorization, X-Filter X-Accepted-Oauth-Scopes: - ips:read_only + X-Content-Type-Options: + - nosniff X-Frame-Options: - DENY + - DENY X-Oauth-Scopes: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 duration: "" - request: body: '{"region":"us-east"}' @@ -61,35 +79,55 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.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: - - "97" + - "258" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:43 GMT + - Mon, 26 Aug 2024 18:31: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: - '*' - status: 404 Not Found - code: 404 + X-Ratelimit-Limit: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 duration: "" - request: body: "" @@ -104,8 +142,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips/172.28.3.4 method: GET response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "Not found"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -120,11 +157,11 @@ interactions: Connection: - keep-alive Content-Length: - - "97" + - "37" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:43 GMT + - Mon, 26 Aug 2024 18:31:09 GMT Pragma: - no-cache Vary: @@ -135,6 +172,8 @@ interactions: - DENY X-Oauth-Scopes: - '*' + X-Ratelimit-Limit: + - "10" status: 404 Not Found code: 404 duration: "" @@ -151,8 +190,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips/172.28.3.4 method: DELETE response: - body: '{"errors": [{"reason": "Account doesn''t have permission to access the - ''Reserved IPs'' feature."}]}' + body: '{"errors": [{"reason": "Not found"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -167,11 +205,11 @@ interactions: Connection: - keep-alive Content-Length: - - "97" + - "37" Content-Type: - application/json Expires: - - Thu, 22 Aug 2024 20:10:44 GMT + - Mon, 26 Aug 2024 18:31:09 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -180,6 +218,8 @@ interactions: - DENY X-Oauth-Scopes: - '*' + X-Ratelimit-Limit: + - "10" status: 404 Not Found code: 404 duration: "" From bed7ce0a16c484da22b2cbc2ecade3dde156b488 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 26 Aug 2024 14:45:55 -0400 Subject: [PATCH 06/43] Changed the error message to relay invalid token for insufficient permission tests --- ...edIpAddresses_InsufficientPermissions.yaml | 100 +++++------------- 1 file changed, 24 insertions(+), 76 deletions(-) diff --git a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml index 70589d0c5..2d6e6f0b9 100644 --- a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml +++ b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml @@ -14,57 +14,36 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], - "page": 1, "pages": 1, "results": 1}' + body: '{"errors": [{"reason": "Invalid Token"}]}' 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: - - "310" - Content-Security-Policy: - - default-src 'none' + - "41" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:02 GMT + - Mon, 26 Aug 2024 18:41:47 GMT Pragma: - no-cache - Strict-Transport-Security: - - max-age=31536000 Vary: - Authorization, X-Filter - - Authorization, X-Filter X-Accepted-Oauth-Scopes: - ips:read_only - 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 + - unknown + status: 401 Unauthorized + code: 401 duration: "" - request: body: '{"region":"us-east"}' @@ -79,55 +58,32 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' + body: '{"errors": [{"reason": "Invalid Token"}]}' 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' + - "41" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:08 GMT + - Mon, 26 Aug 2024 18:41:48 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 + - unknown + status: 401 Unauthorized + code: 401 duration: "" - request: body: "" @@ -142,7 +98,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips/172.28.3.4 method: GET response: - body: '{"errors": [{"reason": "Not found"}]}' + body: '{"errors": [{"reason": "Invalid Token"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -150,18 +106,16 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' - Akamai-Internal-Account: - - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "37" + - "41" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:09 GMT + - Mon, 26 Aug 2024 18:41:48 GMT Pragma: - no-cache Vary: @@ -171,11 +125,9 @@ interactions: X-Frame-Options: - DENY X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "10" - status: 404 Not Found - code: 404 + - unknown + status: 401 Unauthorized + code: 401 duration: "" - request: body: "" @@ -190,7 +142,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips/172.28.3.4 method: DELETE response: - body: '{"errors": [{"reason": "Not found"}]}' + body: '{"errors": [{"reason": "Invalid Token"}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -198,18 +150,16 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' - Akamai-Internal-Account: - - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "37" + - "41" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:09 GMT + - Mon, 26 Aug 2024 18:41:48 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -217,9 +167,7 @@ interactions: X-Frame-Options: - DENY X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "10" - status: 404 Not Found - code: 404 + - unknown + status: 401 Unauthorized + code: 401 duration: "" From 4cc42a6a7a2e2f1eeb6671e7a1be9725a7fecd7a Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 26 Aug 2024 14:52:26 -0400 Subject: [PATCH 07/43] Updated the error message for Insufficient Permission tests to display appropriate error message along with code --- ...edIpAddresses_InsufficientPermissions.yaml | 60 +++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml index 2d6e6f0b9..764d3ac0b 100644 --- a/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml +++ b/test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml @@ -14,7 +14,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"errors": [{"reason": "Invalid Token"}]}' + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -22,16 +23,18 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "41" + - "97" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:41:47 GMT + - Thu, 22 Aug 2024 15:37:02 GMT Pragma: - no-cache Vary: @@ -41,9 +44,9 @@ interactions: X-Frame-Options: - DENY X-Oauth-Scopes: - - unknown - status: 401 Unauthorized - code: 401 + - '*' + status: 404 Not Found + code: 404 duration: "" - request: body: '{"region":"us-east"}' @@ -58,7 +61,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Invalid Token"}]}' + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -66,14 +70,16 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Content-Length: - - "41" + - "97" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:41:48 GMT + - Thu, 22 Aug 2024 15:37:02 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -81,9 +87,9 @@ interactions: X-Frame-Options: - DENY X-Oauth-Scopes: - - unknown - status: 401 Unauthorized - code: 401 + - '*' + status: 404 Not Found + code: 404 duration: "" - request: body: "" @@ -98,7 +104,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips/172.28.3.4 method: GET response: - body: '{"errors": [{"reason": "Invalid Token"}]}' + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -106,16 +113,18 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "41" + - "97" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:41:48 GMT + - Thu, 22 Aug 2024 15:37:03 GMT Pragma: - no-cache Vary: @@ -125,9 +134,9 @@ interactions: X-Frame-Options: - DENY X-Oauth-Scopes: - - unknown - status: 401 Unauthorized - code: 401 + - '*' + status: 404 Not Found + code: 404 duration: "" - request: body: "" @@ -142,7 +151,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips/172.28.3.4 method: DELETE response: - body: '{"errors": [{"reason": "Invalid Token"}]}' + body: '{"errors": [{"reason": "Account doesn''t have permission to access the + ''Reserved IPs'' feature."}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -150,16 +160,18 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "41" + - "97" Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:41:48 GMT + - Thu, 22 Aug 2024 15:37:03 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -167,7 +179,7 @@ interactions: X-Frame-Options: - DENY X-Oauth-Scopes: - - unknown - status: 401 Unauthorized - code: 401 + - '*' + status: 404 Not Found + code: 404 duration: "" From 11fd3cb75ff2d63741483ae61aa42fc2488284e4 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 26 Aug 2024 15:22:15 -0400 Subject: [PATCH 08/43] Made changes to Delete, List, Get, Reserve, EndtoEnd fixtures to record user with adequate permissions --- ...edIPAddresses_DeleteIPAddressVariants.yaml | 28 +- ...ervedIPAddresses_GetIPAddressVariants.yaml | 142 +++++++- ...edIPAddresses_ListIPAddressesVariants.yaml | 12 +- ...ReservedIPAddresses_ReserveIPVariants.yaml | 38 +- .../TestReservedIpAddresses_EndToEndTest.yaml | 342 +++++++++++++++++- 5 files changed, 508 insertions(+), 54 deletions(-) diff --git a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml index 99bf19d0f..e3f48da72 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml @@ -14,11 +14,11 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + body: '{"data": [{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, - {"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", + {"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], "page": 1, "pages": 1, "results": 2}' headers: @@ -45,7 +45,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:11 GMT + - Mon, 26 Aug 2024 19:11:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -79,7 +79,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.33.69.212 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 method: DELETE response: body: '{}' @@ -107,7 +107,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:11 GMT + - Mon, 26 Aug 2024 19:11:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -143,8 +143,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", + body: '{"data": [{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], "page": 1, "pages": 1, "results": 1}' headers: @@ -165,13 +165,13 @@ interactions: Connection: - keep-alive Content-Length: - - "310" + - "307" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:11 GMT + - Mon, 26 Aug 2024 19:12:05 GMT Pragma: - no-cache Strict-Transport-Security: @@ -205,7 +205,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.33.69.212 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -227,7 +227,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:11 GMT + - Mon, 26 Aug 2024 19:12:05 GMT Pragma: - no-cache Vary: @@ -275,7 +275,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:11 GMT + - Mon, 26 Aug 2024 19:12:05 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: diff --git a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml index 0f8e92017..87146839f 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml @@ -14,35 +14,165 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Additional Reserved IPv4 addresses require technical - justification. Please contact support describing your requirement."}]}' + body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.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: - - "147" + - "261" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:10 GMT + - Mon, 26 Aug 2024 19:11:49 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" - status: 400 Bad Request - code: 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/45.79.172.110 + method: GET + response: + body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.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: + - Mon, 26 Aug 2024 19:11:49 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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/INVALID_IP + method: GET + 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 + Connection: + - keep-alive + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 19:11:50 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 404 Not Found + code: 404 duration: "" diff --git a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml index fdc11bca4..ee7cb2878 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml @@ -14,13 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, - {"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], - "page": 1, "pages": 1, "results": 2}' + body: '{"data": [], "page": 1, "pages": 1, "results": 0}' headers: Access-Control-Allow-Credentials: - "true" @@ -39,13 +33,13 @@ interactions: Connection: - keep-alive Content-Length: - - "570" + - "49" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:09 GMT + - Mon, 26 Aug 2024 19:11:49 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml index 4a0d24b05..4bd4badaa 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -31,7 +31,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:10 GMT + - Mon, 26 Aug 2024 19:11:50 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -75,7 +75,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:10 GMT + - Mon, 26 Aug 2024 19:11:50 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -119,7 +119,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:10 GMT + - Mon, 26 Aug 2024 19:11:51 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -146,37 +146,55 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Additional Reserved IPv4 addresses require technical - justification. Please contact support describing your requirement."}]}' + body: '{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.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: - - "147" + - "258" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:10 GMT + - Mon, 26 Aug 2024 19:11:51 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" - status: 400 Bad Request - code: 400 + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 duration: "" - request: body: '{"region":"us-east"}' @@ -209,7 +227,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:11 GMT + - Mon, 26 Aug 2024 19:11:52 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: diff --git a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml b/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml index cc6e5f5ce..c90889934 100644 --- a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml +++ b/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml @@ -14,13 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "66.228.35.140", "gateway": "66.228.35.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-35-140.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, - {"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], - "page": 1, "pages": 1, "results": 2}' + body: '{"data": [], "page": 1, "pages": 1, "results": 0}' headers: Access-Control-Allow-Credentials: - "true" @@ -39,13 +33,13 @@ interactions: Connection: - keep-alive Content-Length: - - "570" + - "49" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:09 GMT + - Mon, 26 Aug 2024 19:11:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -82,35 +76,353 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"errors": [{"reason": "Additional Reserved IPv4 addresses require technical - justification. Please contact support describing your requirement."}]}' + body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.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: - - "147" + - "261" + Content-Security-Policy: + - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 18:31:09 GMT + - Mon, 26 Aug 2024 19:11:48 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" - status: 400 Bad Request - code: 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/45.79.172.110 + method: GET + response: + body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.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: + - Mon, 26 Aug 2024 19:11:48 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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?page=1 + method: GET + response: + body: '{"data": [{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], + "page": 1, "pages": 1, "results": 1}' + 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: + - "310" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 19:11:48 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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/45.79.172.110 + 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: + - Mon, 26 Aug 2024 19:11:49 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/45.79.172.110 + method: GET + 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 + Connection: + - keep-alive + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 19:11:49 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 404 Not Found + code: 404 + 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?page=1 + method: GET + response: + body: '{"data": [], "page": 1, "pages": 1, "results": 0}' + 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: + - "49" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 26 Aug 2024 19:11:49 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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: "" From 4d24fd13fc9be44a5430b6db08f149e2db4a0ed8 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 29 Aug 2024 12:01:39 -0400 Subject: [PATCH 09/43] changed variable name from id to address to keep it consistent with other functions --- network_reserved_ips.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/network_reserved_ips.go b/network_reserved_ips.go index 02ff1c7a7..419d1aed0 100644 --- a/network_reserved_ips.go +++ b/network_reserved_ips.go @@ -10,7 +10,7 @@ type ReserveIPOptions struct { } // GetReservedIPs retrieves a list of reserved IP addresses -func (c *Client) GetReservedIPs(ctx context.Context, opts *ListOptions) ([]InstanceIP, error) { +func (c *Client) ListReservedIPAddresses(ctx context.Context, opts *ListOptions) ([]InstanceIP, error) { e := formatAPIPath("networking/reserved/ips") response, err := getPaginatedResults[InstanceIP](ctx, c, e, opts) if err != nil { @@ -21,8 +21,8 @@ func (c *Client) GetReservedIPs(ctx context.Context, opts *ListOptions) ([]Insta } // GetReservedIPAddress retrieves details of a specific reserved IP address -func (c *Client) GetReservedIPAddress(ctx context.Context, id string) (*InstanceIP, error) { - e := formatAPIPath("networking/reserved/ips/%s", id) +func (c *Client) GetReservedIPAddress(ctx context.Context, ipAddress string) (*InstanceIP, error) { + e := formatAPIPath("networking/reserved/ips/%s", ipAddress) response, err := doGETRequest[InstanceIP](ctx, c, e) if err != nil { return nil, err From a265fd42755440b5db5e3315e0d2d02e5bbc515b Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 29 Aug 2024 12:04:49 -0400 Subject: [PATCH 10/43] Made changes to variable names, achanged logf statements to errorf and fatalf wherever necessary --- test/integration/network_reserved_ips_test.go | 404 ++++++++++-------- 1 file changed, 230 insertions(+), 174 deletions(-) diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 9b8548df0..4bb184fa3 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -2,149 +2,175 @@ package integration import ( "context" - "os" + "fmt" + "strings" + "testing" + "github.com/linode/linodego" . "github.com/linode/linodego" ) // TestReservedIPAddresses_InsufficientPermissions tests the behavior when a user account // doesn't have the can_reserve_ip flag enabled func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { - original := os.Getenv("LINODE_TOKEN") + original := validTestAPIKey dummyToken := "badtoken" - os.Setenv("LINODE_TOKEN", dummyToken) + validTestAPIKey = dummyToken - client, teardown := createTestClient(t, "fixtures/TestReservedIpAddresses_InsufficientPermissions") + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_InsufficientPermissions") defer teardown() - defer os.Setenv("LINODE_TOKEN", original) + defer func() { validTestAPIKey = original }() filter := "" - i, getReservedIpsError := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if getReservedIpsError != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", getReservedIpsError) + ips, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if listErr == nil { + t.Errorf("Expected error due to insufficient permissions, but got none %v", ips) + } else { + t.Logf("Correctly received error when listing IP addresses: %v", listErr) } - if len(i) == 0 { - t.Logf("Expected a list of ipaddresses, but got none %v", i) + if len(ips) != 0 { + t.Errorf("Expected no IP addresses due to insufficient permissions, but got some: %v", ips) } // Attempt to reserve an IP address - reservedIp, reserveIpError := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ Region: "us-east", }) - if reserveIpError != nil { - t.Logf("Failed to reserve IP: %v", reserveIpError) + if resErr == nil { + t.Errorf("Expected error when reserving IP due to insufficient permissions, but got none") } else { - t.Logf("Successfully reserved IP: %+v", reservedIp) + t.Logf("Correctly received %v and error when reserving IP: %v", resIP, resErr) } // Attempt to get a reserved IP address address := "172.28.3.4" - ipaddress, getReservedIpError := client.GetReservedIPAddress(context.Background(), address) - if getReservedIpError != nil { - t.Logf("Error getting ipaddress, expected struct, got %v and error %v", ipaddress, getReservedIpError) + ip, getErr := client.GetReservedIPAddress(context.Background(), address) + if getErr == nil { + t.Errorf("Expected error when getting IP address due to insufficient permissions, but got none") + } else { + t.Logf("Correctly received %v for IP Address and error when getting IP address: %v", ip, getErr) } // Attempt to delete a reserved IP address - addressToBeDeleted := "172.28.3.4" - deleterr := client.DeleteReservedIPAddress(context.Background(), addressToBeDeleted) - if deleterr != nil { - t.Logf("Error deleting reserved IP address: %v", deleterr) + delAddr := "172.28.3.4" + delErr := client.DeleteReservedIPAddress(context.Background(), delAddr) + if delErr == nil { + t.Errorf("Expected error when deleting IP address due to insufficient permissions, but got none") } else { - t.Logf("Successfully deleted reserved IP address: %s", addressToBeDeleted) + t.Logf("Correctly received error when deleting IP address: %v", delErr) } } // TestReservedIPAddresses_EndToEndTest performs an end-to-end test of the Reserved IP functionality // for users with the can_reserve_ip flag enabled func TestReservedIPAddresses_EndToEndTest(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestReservedIpAddresses_EndToEndTest") + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_EndToEndTest") defer teardown() filter := "" - ipList, listIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if listIpErr != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", listIpErr) - } else { - if len(ipList) == 0 { - t.Logf("The customer has not reserved an IP %v", ipList) - } + + ipList, err := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + fmt.Println(ipList) + + if err != nil { + t.Fatalf("Error listing IP addresses: %v", err) } + initialCount := len(ipList) + // Attempt to reserve an IP - reserveIP, reserveIpErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ Region: "us-east", }) - if reserveIpErr != nil { - t.Logf("Failed to reserve IP: %v", reserveIpErr) - } else { - t.Logf("Successfully reserved IP: %+v", reserveIP) + + if resErr != nil { + t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", resErr) } - if reserveIP != nil { - // Fetch the reserved IP - reservedIP, fetchIpErr := client.GetReservedIPAddress(context.Background(), reserveIP.Address) - if fetchIpErr != nil { - t.Logf("Error getting ipaddress, expected struct, got %v and error %v", reservedIP, fetchIpErr) - } + if resIP == nil { + t.Fatalf("Reserved IP is nil") + } - // Verify the list of IPs has increased - verifyList, verifyListIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if verifyListIpErr != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", verifyListIpErr) - } else { - if len(verifyList)-len(ipList) == 1 { - t.Log("Increase in IP list confirmed", verifyList) - } else { - t.Errorf("Increase in IP list not confirmed") - } - } + t.Logf("Successfully reserved IP: %+v", resIP) - // Delete the reserved IP - if reserveIP != nil { - deleteErr := client.DeleteReservedIPAddress(context.Background(), reserveIP.Address) - if deleteErr != nil { - t.Logf("Error deleting reserved IP address: %v", deleteErr) - } else { - t.Logf("Successfully deleted reserved IP address: %s", reserveIP.Address) - } - } + // Fetch the reserved IP + fetchedIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) + if fetchErr != nil { + t.Errorf("Error getting reserved IP address: %v", fetchErr) + } - // Verify the IP has been deleted - if reserveIP != nil { - verifyDeletedIP, fetchDeletedIpErr := client.GetReservedIPAddress(context.Background(), reserveIP.Address) - if fetchDeletedIpErr != nil { - t.Logf("Error getting ipaddress, expected struct, got %v and error %v", verifyDeletedIP, fetchDeletedIpErr) - } + if fetchedIP == nil { + t.Errorf("Retrieved reserved IP is nil") + } - verifyDeletedFromList, verifyDeletedFromListIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if verifyDeletedFromListIpErr != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", verifyDeletedFromListIpErr) - } else { - if len(verifyDeletedFromList) < len(verifyList) { - t.Log("IP address deletion confirmed", verifyDeletedFromList) - } else { - t.Errorf("Verification - Failed") - } - } - } + // Verify the list of IPs has increased + verifyList, verifyErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if verifyErr != nil { + t.Fatalf("Error listing IP addresses after reservation: %v", verifyErr) + } + + if len(verifyList) != initialCount+1 { + t.Errorf("Expected IP count to increase by 1, got %d, want %d", len(verifyList), initialCount+1) + } + + // Delete the reserved IP + delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) + if delErr != nil { + t.Fatalf("Error deleting reserved IP address: %v", delErr) + } + + // Verify the IP has been deleted + _, fetchDelErr := client.GetReservedIPAddress(context.Background(), resIP.Address) + if fetchDelErr == nil { + t.Errorf("Expected error when fetching deleted IP, got nil") + } + + verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if verifyDelErr != nil { + t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) + } + + if len(verifyDelList) != initialCount { + t.Errorf("Expected IP count to return to initial count, got %d, want %d", len(verifyDelList), initialCount) } } -// TestReservedIPAddresses_ListIPAddressesVariants tests various scenarios for listing IP addresses +// TestReservedIPAddresses_ListIPAddressesVariants tests filters for listing IP addresses func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") defer teardown() - filter := "" - ipList, listIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if listIpErr != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", listIpErr) - } else { - if len(ipList) == 0 { - t.Logf("The customer has not reserved an IP %v", ipList) + // Create ListOptions with the filter for reserved IPs in us-east region + listOptions := linodego.ListOptions{ + PageOptions: &linodego.PageOptions{ + Page: 0, + }, + Filter: "{\"reserved\":true,\"region\":\"us-east\"}", + } + + ipList, err := client.ListIPAddresses(context.Background(), &listOptions) + + if err != nil { + t.Fatalf("Error listing reserved IP addresses in us-east: %v", err) + } + + t.Logf("Retrieved %d reserved IP addresses in us-east", len(ipList)) + + for _, ip := range ipList { + if !ip.Reserved { + t.Errorf("Expected all IPs to be reserved, but found non-reserved IP: %s", ip.Address) } + if ip.Region != "us-east" { + t.Errorf("Expected all IPs to be in us-east region, but found IP in %s region: %s", ip.Region, ip.Address) + } + } + + if len(ipList) == 0 { + t.Log("No reserved IPs found in us-east region") + } else { + t.Logf("First reserved IP in us-east: %+v", ipList[0]) } } @@ -154,81 +180,108 @@ func TestReservedIPAddresses_GetIPAddressVariants(t *testing.T) { defer teardown() // Reserve an IP for testing - reserveIP, reserveIpErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ Region: "us-east", }) - if reserveIpErr != nil { - t.Logf("Failed to reserve IP: %v", reserveIpErr) - } else { - t.Logf("Successfully reserved IP: %+v", reserveIP) + + if resErr != nil { + t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", resErr) } - if reserveIP != nil { - // Test getting a valid reserved IP - validReservedIP, validFetchIpErr := client.GetReservedIPAddress(context.Background(), reserveIP.Address) - if validFetchIpErr != nil { - t.Logf("Error getting ipaddress, expected struct, got %v and error %v", validReservedIP, validFetchIpErr) - } + if resIP == nil { + t.Fatalf("Reserved IP is nil") + } + + t.Logf("Successfully reserved IP: %+v", resIP) - // Test getting an invalid IP - invalidReservedIP, invalidFetchIpErr := client.GetReservedIPAddress(context.Background(), "INVALID_IP") - if invalidFetchIpErr != nil { - t.Logf("Error getting ipaddress, expected struct, got %v and error %v", invalidReservedIP, invalidFetchIpErr) + // Test getting a valid reserved IP + validIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) + if fetchErr != nil { + t.Errorf("Error getting valid reserved IP address: %v", fetchErr) + } + + if validIP == nil { + t.Errorf("Retrieved valid reserved IP is nil") + } else { + if validIP.Address != resIP.Address { + t.Errorf("Retrieved IP address does not match reserved IP address. Got %s, want %s", validIP.Address, resIP.Address) } } + + // Test getting an invalid IP + invalidIP := "999.999.999.999" + _, invalidFetchErr := client.GetReservedIPAddress(context.Background(), invalidIP) + if invalidFetchErr == nil { + t.Errorf("Expected error when fetching invalid IP, got nil") + } + + // Clean up: Delete the reserved IP + delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) + if delErr != nil { + t.Errorf("Failed to delete reserved IP: %v", delErr) + } } // TestReservedIPAddresses_ReserveIPVariants tests various scenarios for reserving an IP address -func TestReservedIPAddresses_ReserveIPVariants(t *testing.T) { +func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ReserveIPVariants") defer teardown() + // Slice to keep track of all reserved IPs + var reservedIPs []string + + // Helper function to clean up reserved IPs + cleanupIPs := func() { + for _, ip := range reservedIPs { + err := client.DeleteReservedIPAddress(context.Background(), ip) + if err != nil { + t.Errorf("Failed to delete reserved IP %s: %v", ip, err) + } + } + } + defer cleanupIPs() + // Test reserving IP with omitted region - omitRegion, omitRegionErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{}) - if omitRegionErr != nil { - t.Logf("Failed to reserve IP: %v", omitRegionErr) - } else { - t.Logf("Successfully reserved IP: %+v", omitRegion) + _, omitErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{}) + if omitErr == nil { + t.Errorf("Expected error when reserving IP with omitted region, got nil") } // Test reserving IP with invalid region - invalidRegion, invalidRegionErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "us", - }) - if invalidRegionErr != nil { - t.Logf("Failed to reserve IP: %v", invalidRegionErr) - } else { - t.Logf("Successfully reserved IP: %+v", invalidRegion) + _, invalidErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us"}) + if invalidErr == nil { + t.Errorf("Expected error when reserving IP with invalid region, got nil") } // Test reserving IP with empty region - emptyRegion, emptyRegionErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "", - }) - if emptyRegionErr != nil { - t.Logf("Failed to reserve IP: %v", emptyRegionErr) - } else { - t.Logf("Successfully reserved IP: %+v", emptyRegion) + _, emptyErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: ""}) + if emptyErr == nil { + t.Errorf("Expected error when reserving IP with empty region, got nil") } - // Test valid IP reservation - validReservation, validReservationErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "us-east", - }) - if validReservationErr != nil { - t.Logf("Failed to reserve IP: %v", validReservationErr) - } else { - t.Logf("Successfully reserved IP: %+v", validReservation) + // Test valid IP reservations until limit is reached + for { + reservation, err := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) + if err != nil { + if strings.Contains(err.Error(), "Additional Reserved IPv4 addresses require technical justification. Please contact support describing your requirement.") { + t.Logf("Reservation limit reached after %d reservations", len(reservedIPs)) + break + } + t.Fatalf("Unexpected error when reserving IP: %v", err) + } + + if reservation == nil { + t.Fatalf("Valid reservation returned nil IP") + } + + reservedIPs = append(reservedIPs, reservation.Address) + t.Logf("Successfully reserved IP: %s", reservation.Address) } - // Test exceeding reservation limit - exceedReservationLimit, exceedReservationErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "us-east", - }) - if exceedReservationErr != nil { - t.Logf("Failed to reserve IP: %v", exceedReservationErr) - } else { - t.Logf("Successfully reserved IP: %+v", exceedReservationLimit) + // Verify that we can't reserve more IPs + _, exceedErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) + if exceedErr == nil { + t.Errorf("Expected error when exceeding reservation limit, got nil") } } @@ -237,48 +290,51 @@ func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_DeleteIPAddressVariants") defer teardown() + validRes, validErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) + if validErr != nil { + t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", validErr) + } + + if validRes == nil { + t.Fatalf("Valid reservation returned nil IP") + } + + t.Logf("Successfully reserved IP: %+v", validRes) + filter := "" - ipList, listIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if listIpErr != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", listIpErr) - } else { - if len(ipList) == 0 { - t.Logf("The customer has not reserved an IP %v", ipList) - } + ipList, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if listErr != nil { + t.Fatalf("Error listing IP addresses: %v", listErr) } - if len(ipList) > 0 { - ipToBeDeleted := ipList[len(ipList)-1] - deleteErr := client.DeleteReservedIPAddress(context.Background(), ipToBeDeleted.Address) - if deleteErr != nil { - t.Logf("Error deleting reserved IP address: %v", deleteErr) - } else { - t.Logf("Successfully deleted reserved IP address: %s", ipToBeDeleted.Address) - } + if len(ipList) == 0 { + t.Skip("No reserved IPs available for testing deletion") + } - // Verify deletion - verifyDeletedFromList, verifyDeletedFromListIpErr := client.GetReservedIPs(context.Background(), NewListOptions(0, filter)) - if verifyDeletedFromListIpErr != nil { - t.Logf("Error listing ipaddresses, expected struct, got error %v", verifyDeletedFromListIpErr) - } else { - if len(verifyDeletedFromList) < len(ipList) { - t.Log("IP address deletion confirmed", verifyDeletedFromList) - } else { - t.Errorf("Verification - Failed") - } - } + delErr := client.DeleteReservedIPAddress(context.Background(), validRes.Address) + if delErr != nil { + t.Fatalf("Failed to delete reserved IP address: %v", delErr) + } - verifyDeletedIP, fetchDeletedIpErr := client.GetReservedIPAddress(context.Background(), ipToBeDeleted.Address) - if fetchDeletedIpErr != nil { - t.Logf("IP address not found got %v and error %v", verifyDeletedIP, fetchDeletedIpErr) - } + // Verify deletion + verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if verifyDelErr != nil { + t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) + } - // Test deleting an unowned IP - deletingUnownedIPErr := client.DeleteReservedIPAddress(context.Background(), "255.255.255.4") - if deletingUnownedIPErr != nil { - t.Logf("Error deleting reserved IP address: %v", deletingUnownedIPErr) - } else { - t.Logf("Successfully deleted reserved IP address: %s", "255.255.255.4") - } + if len(verifyDelList) >= len(ipList) { + t.Errorf("IP address deletion not confirmed. Expected count < %d, got %d", len(ipList), len(verifyDelList)) + } + + _, fetchDelErr := client.GetReservedIPAddress(context.Background(), validRes.Address) + if fetchDelErr == nil { + t.Errorf("Expected error when fetching deleted IP, got nil") + } + + // Test deleting an unowned IP + unownedIP := "255.255.255.4" + delUnownedErr := client.DeleteReservedIPAddress(context.Background(), unownedIP) + if delUnownedErr == nil { + t.Errorf("Expected error when deleting unowned IP, got nil") } } From 49d14a617e0bfe169039cd5a6f79be29a924dbe8 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 29 Aug 2024 12:06:00 -0400 Subject: [PATCH 11/43] changed fixture file names to improve consistency, re-recorded fixtures with latest error messages --- ...edIPAddresses_DeleteIPAddressVariants.yaml | 95 +++++-- ...TestReservedIPAddresses_EndToEndTest.yaml} | 32 +-- ...ervedIPAddresses_GetIPAddressVariants.yaml | 79 +++++- ...dIPAddresses_InsufficientPermissions.yaml} | 0 ...edIPAddresses_ListIPAddressesVariants.yaml | 10 +- ...ReservedIPAddresses_ReserveIPVariants.yaml | 246 +++++++++++++++++- 6 files changed, 406 insertions(+), 56 deletions(-) rename test/integration/fixtures/{TestReservedIpAddresses_EndToEndTest.yaml => TestReservedIPAddresses_EndToEndTest.yaml} (94%) rename test/integration/fixtures/{TestReservedIpAddresses_InsufficientPermissions.yaml => TestReservedIPAddresses_InsufficientPermissions.yaml} (100%) diff --git a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml index e3f48da72..c55673c56 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml @@ -1,6 +1,69 @@ --- 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": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.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: + - "256" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 29 Aug 2024 15:39: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: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" - request: body: "" form: {} @@ -14,13 +77,10 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, - {"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + body: '{"data": [{"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], - "page": 1, "pages": 1, "results": 2}' + "page": 1, "pages": 1, "results": 1}' headers: Access-Control-Allow-Credentials: - "true" @@ -39,13 +99,13 @@ interactions: Connection: - keep-alive Content-Length: - - "570" + - "305" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:52 GMT + - Thu, 29 Aug 2024 15:39:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -79,7 +139,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.20.39 method: DELETE response: body: '{}' @@ -107,7 +167,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:52 GMT + - Thu, 29 Aug 2024 15:39:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -143,10 +203,7 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", - "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], - "page": 1, "pages": 1, "results": 1}' + body: '{"data": [], "page": 1, "pages": 1, "results": 0}' headers: Access-Control-Allow-Credentials: - "true" @@ -165,13 +222,13 @@ interactions: Connection: - keep-alive Content-Length: - - "307" + - "49" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:12:05 GMT + - Thu, 29 Aug 2024 15:39:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -205,7 +262,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.20.39 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -227,7 +284,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:12:05 GMT + - Thu, 29 Aug 2024 15:39:22 GMT Pragma: - no-cache Vary: @@ -275,7 +332,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:12:05 GMT + - Thu, 29 Aug 2024 15:39:35 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: diff --git a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml b/test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml similarity index 94% rename from test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml rename to test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml index c90889934..d0e273b45 100644 --- a/test/integration/fixtures/TestReservedIpAddresses_EndToEndTest.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml @@ -39,7 +39,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:48 GMT + - Thu, 29 Aug 2024 15:39:16 GMT Pragma: - no-cache Strict-Transport-Security: @@ -76,8 +76,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -103,7 +103,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:48 GMT + - Thu, 29 Aug 2024 15:39:19 GMT Pragma: - no-cache Strict-Transport-Security: @@ -136,11 +136,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 method: GET response: - body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -166,7 +166,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:48 GMT + - Thu, 29 Aug 2024 15:39:19 GMT Pragma: - no-cache Strict-Transport-Security: @@ -203,8 +203,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + body: '{"data": [{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], "page": 1, "pages": 1, "results": 1}' headers: @@ -231,7 +231,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:48 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -265,7 +265,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 method: DELETE response: body: '{}' @@ -293,7 +293,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:49 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -326,7 +326,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -348,7 +348,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:49 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Vary: @@ -402,7 +402,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:49 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml index 87146839f..6a4bf9cd1 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_GetIPAddressVariants.yaml @@ -14,8 +14,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -41,7 +41,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:49 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -74,11 +74,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.172.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 method: GET response: - body: '{"address": "45.79.172.110", "gateway": "45.79.172.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-172-110.ip.linodeusercontent.com", + body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -104,7 +104,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:49 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -138,7 +138,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/INVALID_IP + url: https://api.linode.com/v4beta/networking/reserved/ips/999.999.999.999 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -160,7 +160,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:50 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Vary: @@ -176,3 +176,64 @@ interactions: status: 404 Not Found code: 404 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.56.109.241 + 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, 29 Aug 2024 15:39:21 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/TestReservedIpAddresses_InsufficientPermissions.yaml b/test/integration/fixtures/TestReservedIPAddresses_InsufficientPermissions.yaml similarity index 100% rename from test/integration/fixtures/TestReservedIpAddresses_InsufficientPermissions.yaml rename to test/integration/fixtures/TestReservedIPAddresses_InsufficientPermissions.yaml diff --git a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml index ee7cb2878..5f411f028 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml @@ -11,10 +11,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 + X-Filter: + - '{"reserved":true,"region":"us-east"}' + url: https://api.linode.com/v4beta/networking/ips?page=1 method: GET response: - body: '{"data": [], "page": 1, "pages": 1, "results": 0}' + body: '{"page": 1, "pages": 1, "results": 0, "data": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -39,7 +41,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:49 GMT + - Thu, 29 Aug 2024 15:39:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -57,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "10" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml index 4bd4badaa..21a597d57 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -31,7 +31,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:50 GMT + - Thu, 29 Aug 2024 15:39:21 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -75,7 +75,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:50 GMT + - Thu, 29 Aug 2024 15:39:21 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -119,7 +119,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:51 GMT + - Thu, 29 Aug 2024 15:39:21 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -146,8 +146,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.33.69.212", "gateway": "45.33.69.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-69-212.ip.linodeusercontent.com", + body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -167,13 +167,76 @@ interactions: Connection: - keep-alive Content-Length: - - "258" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:51 GMT + - Thu, 29 Aug 2024 15:39:21 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"}' + 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.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.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: + - "256" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 29 Aug 2024 15:39:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -227,7 +290,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 26 Aug 2024 19:11:52 GMT + - Thu, 29 Aug 2024 15:39:21 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -241,3 +304,170 @@ interactions: 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: '{"errors": [{"reason": "Additional Reserved 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: + - "147" + Content-Type: + - application/json + Expires: + - Thu, 29 Aug 2024 15:39:21 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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.56.109.241 + 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, 29 Aug 2024 15:39: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: "" +- 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.20.39 + 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, 29 Aug 2024 15:39: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: "" From bd106fadafe1e8c4c6c8db1f707385b0d260ef84 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 29 Aug 2024 12:07:14 -0400 Subject: [PATCH 12/43] removed debugging fmt statement --- test/integration/network_reserved_ips_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 4bb184fa3..be93c3b5d 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -2,7 +2,6 @@ package integration import ( "context" - "fmt" "strings" "testing" @@ -72,7 +71,6 @@ func TestReservedIPAddresses_EndToEndTest(t *testing.T) { filter := "" ipList, err := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - fmt.Println(ipList) if err != nil { t.Fatalf("Error listing IP addresses: %v", err) From cd7fa480800aa683123263cc6d027370092fa3ea Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 3 Sep 2024 17:01:48 -0400 Subject: [PATCH 13/43] Made changes to reserve IP addresses before listing them using fitler feature. Removed for loop to reserve IPs till limit is reached. --- ...edIPAddresses_ListIPAddressesVariants.yaml | 260 +++++++- ...ReservedIPAddresses_ReserveIPVariants.yaml | 75 +-- test/integration/network_reserved_ips_test.go | 562 +++++++++--------- 3 files changed, 562 insertions(+), 335 deletions(-) diff --git a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml index 5f411f028..16dbaea0d 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml @@ -1,6 +1,132 @@ --- 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": "45.56.102.171", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-171.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: + - Tue, 03 Sep 2024 20:22:20 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"}' + 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.56.102.42", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-42.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: + - Tue, 03 Sep 2024 20:22:21 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: "" form: {} @@ -16,7 +142,13 @@ interactions: url: https://api.linode.com/v4beta/networking/ips?page=1 method: GET response: - body: '{"page": 1, "pages": 1, "results": 0, "data": []}' + body: '{"page": 1, "pages": 1, "results": 2, "data": [{"address": "45.56.102.42", + "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-56-102-42.ip.linodeusercontent.com", "linode_id": + null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, {"address": + "45.56.102.171", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-102-171.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -35,13 +167,13 @@ interactions: Connection: - keep-alive Content-Length: - - "49" + - "571" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:20 GMT + - Tue, 03 Sep 2024 20:22:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -65,3 +197,125 @@ interactions: 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.56.102.171 + 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 20:22:21 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/45.56.102.42 + 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 20:22: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/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml index 21a597d57..aa474a0c6 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -31,7 +31,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:21 GMT + - Tue, 03 Sep 2024 20:57:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -75,7 +75,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:21 GMT + - Tue, 03 Sep 2024 20:57:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -119,7 +119,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:21 GMT + - Tue, 03 Sep 2024 20:57:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -146,8 +146,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", + body: '{"address": "45.56.102.171", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-171.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -173,7 +173,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:21 GMT + - Tue, 03 Sep 2024 20:57:43 GMT Pragma: - no-cache Strict-Transport-Security: @@ -209,8 +209,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", + body: '{"address": "45.56.102.42", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-42.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -230,13 +230,13 @@ interactions: Connection: - keep-alive Content-Length: - - "256" + - "259" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:21 GMT + - Tue, 03 Sep 2024 20:57:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -290,52 +290,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:21 GMT - Pragma: - - no-cache - X-Accepted-Oauth-Scopes: - - ips:read_write - X-Frame-Options: - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "400" - 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: '{"errors": [{"reason": "Additional Reserved 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: - - "147" - Content-Type: - - application/json - Expires: - - Thu, 29 Aug 2024 15:39:21 GMT + - Tue, 03 Sep 2024 20:57:44 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -359,7 +314,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.102.171 method: DELETE response: body: '{}' @@ -387,7 +342,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Tue, 03 Sep 2024 20:57:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -420,7 +375,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.20.39 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.102.42 method: DELETE response: body: '{}' @@ -448,7 +403,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Tue, 03 Sep 2024 20:57:44 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index be93c3b5d..23a284227 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -2,7 +2,6 @@ package integration import ( "context" - "strings" "testing" @@ -12,213 +11,239 @@ import ( // TestReservedIPAddresses_InsufficientPermissions tests the behavior when a user account // doesn't have the can_reserve_ip flag enabled -func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { - original := validTestAPIKey - dummyToken := "badtoken" - validTestAPIKey = dummyToken - - client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_InsufficientPermissions") - defer teardown() - defer func() { validTestAPIKey = original }() - - filter := "" - ips, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - if listErr == nil { - t.Errorf("Expected error due to insufficient permissions, but got none %v", ips) - } else { - t.Logf("Correctly received error when listing IP addresses: %v", listErr) - } - - if len(ips) != 0 { - t.Errorf("Expected no IP addresses due to insufficient permissions, but got some: %v", ips) - } - - // Attempt to reserve an IP address - resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "us-east", - }) - if resErr == nil { - t.Errorf("Expected error when reserving IP due to insufficient permissions, but got none") - } else { - t.Logf("Correctly received %v and error when reserving IP: %v", resIP, resErr) - } - - // Attempt to get a reserved IP address - address := "172.28.3.4" - ip, getErr := client.GetReservedIPAddress(context.Background(), address) - if getErr == nil { - t.Errorf("Expected error when getting IP address due to insufficient permissions, but got none") - } else { - t.Logf("Correctly received %v for IP Address and error when getting IP address: %v", ip, getErr) - } - - // Attempt to delete a reserved IP address - delAddr := "172.28.3.4" - delErr := client.DeleteReservedIPAddress(context.Background(), delAddr) - if delErr == nil { - t.Errorf("Expected error when deleting IP address due to insufficient permissions, but got none") - } else { - t.Logf("Correctly received error when deleting IP address: %v", delErr) - } -} - -// TestReservedIPAddresses_EndToEndTest performs an end-to-end test of the Reserved IP functionality -// for users with the can_reserve_ip flag enabled -func TestReservedIPAddresses_EndToEndTest(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_EndToEndTest") - defer teardown() - - filter := "" - - ipList, err := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - - if err != nil { - t.Fatalf("Error listing IP addresses: %v", err) - } - - initialCount := len(ipList) - - // Attempt to reserve an IP - resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "us-east", - }) - - if resErr != nil { - t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", resErr) - } - - if resIP == nil { - t.Fatalf("Reserved IP is nil") - } - - t.Logf("Successfully reserved IP: %+v", resIP) - - // Fetch the reserved IP - fetchedIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) - if fetchErr != nil { - t.Errorf("Error getting reserved IP address: %v", fetchErr) - } - - if fetchedIP == nil { - t.Errorf("Retrieved reserved IP is nil") - } - - // Verify the list of IPs has increased - verifyList, verifyErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - if verifyErr != nil { - t.Fatalf("Error listing IP addresses after reservation: %v", verifyErr) - } - - if len(verifyList) != initialCount+1 { - t.Errorf("Expected IP count to increase by 1, got %d, want %d", len(verifyList), initialCount+1) - } - - // Delete the reserved IP - delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) - if delErr != nil { - t.Fatalf("Error deleting reserved IP address: %v", delErr) - } - - // Verify the IP has been deleted - _, fetchDelErr := client.GetReservedIPAddress(context.Background(), resIP.Address) - if fetchDelErr == nil { - t.Errorf("Expected error when fetching deleted IP, got nil") - } - - verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - if verifyDelErr != nil { - t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) - } - - if len(verifyDelList) != initialCount { - t.Errorf("Expected IP count to return to initial count, got %d, want %d", len(verifyDelList), initialCount) - } -} +// func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { +// original := validTestAPIKey +// dummyToken := "badtoken" +// validTestAPIKey = dummyToken + +// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_InsufficientPermissions") +// defer teardown() +// defer func() { validTestAPIKey = original }() + +// filter := "" +// ips, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) +// if listErr == nil { +// t.Errorf("Expected error due to insufficient permissions, but got none %v", ips) +// } else { +// t.Logf("Correctly received error when listing IP addresses: %v", listErr) +// } + +// if len(ips) != 0 { +// t.Errorf("Expected no IP addresses due to insufficient permissions, but got some: %v", ips) +// } + +// // Attempt to reserve an IP address +// resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ +// Region: "us-east", +// }) +// if resErr == nil { +// t.Errorf("Expected error when reserving IP due to insufficient permissions, but got none") +// } else { +// t.Logf("Correctly received %v and error when reserving IP: %v", resIP, resErr) +// } + +// // Attempt to get a reserved IP address +// address := "172.28.3.4" +// ip, getErr := client.GetReservedIPAddress(context.Background(), address) +// if getErr == nil { +// t.Errorf("Expected error when getting IP address due to insufficient permissions, but got none") +// } else { +// t.Logf("Correctly received %v for IP Address and error when getting IP address: %v", ip, getErr) +// } + +// // Attempt to delete a reserved IP address +// delAddr := "172.28.3.4" +// delErr := client.DeleteReservedIPAddress(context.Background(), delAddr) +// if delErr == nil { +// t.Errorf("Expected error when deleting IP address due to insufficient permissions, but got none") +// } else { +// t.Logf("Correctly received error when deleting IP address: %v", delErr) +// } +// } + +// // TestReservedIPAddresses_EndToEndTest performs an end-to-end test of the Reserved IP functionality +// // for users with the can_reserve_ip flag enabled +// func TestReservedIPAddresses_EndToEndTest(t *testing.T) { +// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_EndToEndTest") +// defer teardown() + +// filter := "" + +// ipList, err := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + +// if err != nil { +// t.Fatalf("Error listing IP addresses: %v", err) +// } + +// initialCount := len(ipList) + +// // Attempt to reserve an IP +// resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ +// Region: "us-east", +// }) + +// if resErr != nil { +// t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) +// } + +// if resIP == nil { +// t.Fatalf("Reserved IP is nil") +// } + +// t.Logf("Successfully reserved IP: %+v", resIP) + +// // Fetch the reserved IP +// fetchedIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) +// if fetchErr != nil { +// t.Errorf("Error getting reserved IP address: %v", fetchErr) +// } + +// if fetchedIP == nil { +// t.Errorf("Retrieved reserved IP is nil") +// } + +// // Verify the list of IPs has increased +// verifyList, verifyErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) +// if verifyErr != nil { +// t.Fatalf("Error listing IP addresses after reservation: %v", verifyErr) +// } + +// if len(verifyList) != initialCount+1 { +// t.Errorf("Expected IP count to increase by 1, got %d, want %d", len(verifyList), initialCount+1) +// } + +// // Delete the reserved IP +// delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) +// if delErr != nil { +// t.Fatalf("Error deleting reserved IP address: %v", delErr) +// } + +// // Verify the IP has been deleted +// _, fetchDelErr := client.GetReservedIPAddress(context.Background(), resIP.Address) +// if fetchDelErr == nil { +// t.Errorf("Expected error when fetching deleted IP, got nil") +// } + +// verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) +// if verifyDelErr != nil { +// t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) +// } + +// if len(verifyDelList) != initialCount { +// t.Errorf("Expected IP count to return to initial count, got %d, want %d", len(verifyDelList), initialCount) +// } +// } // TestReservedIPAddresses_ListIPAddressesVariants tests filters for listing IP addresses -func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") - defer teardown() - - // Create ListOptions with the filter for reserved IPs in us-east region - listOptions := linodego.ListOptions{ - PageOptions: &linodego.PageOptions{ - Page: 0, - }, - Filter: "{\"reserved\":true,\"region\":\"us-east\"}", - } - - ipList, err := client.ListIPAddresses(context.Background(), &listOptions) - - if err != nil { - t.Fatalf("Error listing reserved IP addresses in us-east: %v", err) - } - - t.Logf("Retrieved %d reserved IP addresses in us-east", len(ipList)) - - for _, ip := range ipList { - if !ip.Reserved { - t.Errorf("Expected all IPs to be reserved, but found non-reserved IP: %s", ip.Address) - } - if ip.Region != "us-east" { - t.Errorf("Expected all IPs to be in us-east region, but found IP in %s region: %s", ip.Region, ip.Address) - } - } - - if len(ipList) == 0 { - t.Log("No reserved IPs found in us-east region") - } else { - t.Logf("First reserved IP in us-east: %+v", ipList[0]) - } -} +// func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { +// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") +// defer teardown() + +// // Reserve two IP addresses in us-east region +// reservedIPs := make([]string, 2) +// for i := 0; i < 2; i++ { +// reserveIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ +// Region: "us-east", +// }) +// if err != nil { +// t.Fatalf("Failed to reserve IP %d: %v", i+1, err) +// } +// reservedIPs[i] = reserveIP.Address +// t.Logf("Successfully reserved IP %d: %s", i+1, reserveIP.Address) +// } + +// // Defer cleanup of reserved IPs +// defer func() { +// for _, ip := range reservedIPs { +// err := client.DeleteReservedIPAddress(context.Background(), ip) +// if err != nil { +// t.Errorf("Failed to delete reserved IP %s: %v", ip, err) +// } +// } +// }() + +// // Create ListOptions with the filter for reserved IPs in us-east region +// listOptions := linodego.ListOptions{ +// PageOptions: &linodego.PageOptions{ +// Page: 0, +// }, +// Filter: "{\"reserved\":true,\"region\":\"us-east\"}", +// } + +// ipList, err := client.ListIPAddresses(context.Background(), &listOptions) + +// if err != nil { +// t.Fatalf("Error listing reserved IP addresses in us-east: %v", err) +// } + +// t.Logf("Retrieved %d reserved IP addresses in us-east", len(ipList)) + +// // Check if at least the two reserved IPs are in the list +// foundReservedIPs := 0 +// for _, ip := range ipList { +// if !ip.Reserved { +// t.Errorf("Expected all IPs to be reserved, but found non-reserved IP: %s", ip.Address) +// } +// if ip.Region != "us-east" { +// t.Errorf("Expected all IPs to be in us-east region, but found IP in %s region: %s", ip.Region, ip.Address) +// } +// for _, reservedIP := range reservedIPs { +// if ip.Address == reservedIP { +// foundReservedIPs++ +// break +// } +// } +// } + +// } // TestReservedIPAddresses_GetIPAddressVariants tests various scenarios for getting a specific IP address -func TestReservedIPAddresses_GetIPAddressVariants(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_GetIPAddressVariants") - defer teardown() - - // Reserve an IP for testing - resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ - Region: "us-east", - }) - - if resErr != nil { - t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", resErr) - } - - if resIP == nil { - t.Fatalf("Reserved IP is nil") - } - - t.Logf("Successfully reserved IP: %+v", resIP) - - // Test getting a valid reserved IP - validIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) - if fetchErr != nil { - t.Errorf("Error getting valid reserved IP address: %v", fetchErr) - } - - if validIP == nil { - t.Errorf("Retrieved valid reserved IP is nil") - } else { - if validIP.Address != resIP.Address { - t.Errorf("Retrieved IP address does not match reserved IP address. Got %s, want %s", validIP.Address, resIP.Address) - } - } - - // Test getting an invalid IP - invalidIP := "999.999.999.999" - _, invalidFetchErr := client.GetReservedIPAddress(context.Background(), invalidIP) - if invalidFetchErr == nil { - t.Errorf("Expected error when fetching invalid IP, got nil") - } - - // Clean up: Delete the reserved IP - delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) - if delErr != nil { - t.Errorf("Failed to delete reserved IP: %v", delErr) - } -} +// func TestReservedIPAddresses_GetIPAddressVariants(t *testing.T) { +// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_GetIPAddressVariants") +// defer teardown() + +// // Reserve an IP for testing +// resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ +// Region: "us-east", +// }) + +// if resErr != nil { +// t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) +// } + +// if resIP == nil { +// t.Fatalf("Reserved IP is nil") +// } + +// t.Logf("Successfully reserved IP: %+v", resIP) + +// // Test getting a valid reserved IP +// validIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) +// if fetchErr != nil { +// t.Errorf("Error getting valid reserved IP address: %v", fetchErr) +// } + +// if validIP == nil { +// t.Errorf("Retrieved valid reserved IP is nil") +// } else { +// if validIP.Address != resIP.Address { +// t.Errorf("Retrieved IP address does not match reserved IP address. Got %s, want %s", validIP.Address, resIP.Address) +// } +// } + +// // Test getting an invalid IP +// invalidIP := "999.999.999.999" +// _, invalidFetchErr := client.GetReservedIPAddress(context.Background(), invalidIP) +// if invalidFetchErr == nil { +// t.Errorf("Expected error when fetching invalid IP, got nil") +// } + +// // Clean up: Delete the reserved IP +// delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) +// if delErr != nil { +// t.Errorf("Failed to delete reserved IP: %v", delErr) +// } +// } // TestReservedIPAddresses_ReserveIPVariants tests various scenarios for reserving an IP address func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { @@ -257,23 +282,16 @@ func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { t.Errorf("Expected error when reserving IP with empty region, got nil") } - // Test valid IP reservations until limit is reached - for { - reservation, err := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) + // Make 2 valid IP Reservations + for i := 0; i < 2; i++ { + reserveIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "us-east", + }) if err != nil { - if strings.Contains(err.Error(), "Additional Reserved IPv4 addresses require technical justification. Please contact support describing your requirement.") { - t.Logf("Reservation limit reached after %d reservations", len(reservedIPs)) - break - } - t.Fatalf("Unexpected error when reserving IP: %v", err) + t.Fatalf("Failed to reserve IP %d: %v", i+1, err) } - - if reservation == nil { - t.Fatalf("Valid reservation returned nil IP") - } - - reservedIPs = append(reservedIPs, reservation.Address) - t.Logf("Successfully reserved IP: %s", reservation.Address) + reservedIPs = append(reservedIPs, reserveIP.Address) + t.Logf("Successfully reserved IP %d: %s", i+1, reserveIP.Address) } // Verify that we can't reserve more IPs @@ -283,56 +301,56 @@ func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { } } -// TestReservedIPAddresses_DeleteIPAddressVariants tests various scenarios for deleting a reserved IP address -func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_DeleteIPAddressVariants") - defer teardown() - - validRes, validErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) - if validErr != nil { - t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", validErr) - } - - if validRes == nil { - t.Fatalf("Valid reservation returned nil IP") - } - - t.Logf("Successfully reserved IP: %+v", validRes) - - filter := "" - ipList, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - if listErr != nil { - t.Fatalf("Error listing IP addresses: %v", listErr) - } - - if len(ipList) == 0 { - t.Skip("No reserved IPs available for testing deletion") - } - - delErr := client.DeleteReservedIPAddress(context.Background(), validRes.Address) - if delErr != nil { - t.Fatalf("Failed to delete reserved IP address: %v", delErr) - } - - // Verify deletion - verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - if verifyDelErr != nil { - t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) - } - - if len(verifyDelList) >= len(ipList) { - t.Errorf("IP address deletion not confirmed. Expected count < %d, got %d", len(ipList), len(verifyDelList)) - } - - _, fetchDelErr := client.GetReservedIPAddress(context.Background(), validRes.Address) - if fetchDelErr == nil { - t.Errorf("Expected error when fetching deleted IP, got nil") - } - - // Test deleting an unowned IP - unownedIP := "255.255.255.4" - delUnownedErr := client.DeleteReservedIPAddress(context.Background(), unownedIP) - if delUnownedErr == nil { - t.Errorf("Expected error when deleting unowned IP, got nil") - } -} +// // TestReservedIPAddresses_DeleteIPAddressVariants tests various scenarios for deleting a reserved IP address +// func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { +// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_DeleteIPAddressVariants") +// defer teardown() + +// validRes, validErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) +// if validErr != nil { +// t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", validErr) +// } + +// if validRes == nil { +// t.Fatalf("Valid reservation returned nil IP") +// } + +// t.Logf("Successfully reserved IP: %+v", validRes) + +// filter := "" +// ipList, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) +// if listErr != nil { +// t.Fatalf("Error listing IP addresses: %v", listErr) +// } + +// if len(ipList) == 0 { +// t.Skip("No reserved IPs available for testing deletion") +// } + +// delErr := client.DeleteReservedIPAddress(context.Background(), validRes.Address) +// if delErr != nil { +// t.Fatalf("Failed to delete reserved IP address: %v", delErr) +// } + +// // Verify deletion +// verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) +// if verifyDelErr != nil { +// t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) +// } + +// if len(verifyDelList) >= len(ipList) { +// t.Errorf("IP address deletion not confirmed. Expected count < %d, got %d", len(ipList), len(verifyDelList)) +// } + +// _, fetchDelErr := client.GetReservedIPAddress(context.Background(), validRes.Address) +// if fetchDelErr == nil { +// t.Errorf("Expected error when fetching deleted IP, got nil") +// } + +// // Test deleting an unowned IP +// unownedIP := "255.255.255.4" +// delUnownedErr := client.DeleteReservedIPAddress(context.Background(), unownedIP) +// if delUnownedErr == nil { +// t.Errorf("Expected error when deleting unowned IP, got nil") +// } +// } From d52a33f1350b49432c1ea527b9f018c22eee6f63 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 3 Sep 2024 17:20:43 -0400 Subject: [PATCH 14/43] uncommenting unaffected tests --- test/integration/network_reserved_ips_test.go | 564 +++++++++--------- 1 file changed, 282 insertions(+), 282 deletions(-) diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 23a284227..05fa727af 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -11,239 +11,239 @@ import ( // TestReservedIPAddresses_InsufficientPermissions tests the behavior when a user account // doesn't have the can_reserve_ip flag enabled -// func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { -// original := validTestAPIKey -// dummyToken := "badtoken" -// validTestAPIKey = dummyToken - -// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_InsufficientPermissions") -// defer teardown() -// defer func() { validTestAPIKey = original }() - -// filter := "" -// ips, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) -// if listErr == nil { -// t.Errorf("Expected error due to insufficient permissions, but got none %v", ips) -// } else { -// t.Logf("Correctly received error when listing IP addresses: %v", listErr) -// } - -// if len(ips) != 0 { -// t.Errorf("Expected no IP addresses due to insufficient permissions, but got some: %v", ips) -// } - -// // Attempt to reserve an IP address -// resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ -// Region: "us-east", -// }) -// if resErr == nil { -// t.Errorf("Expected error when reserving IP due to insufficient permissions, but got none") -// } else { -// t.Logf("Correctly received %v and error when reserving IP: %v", resIP, resErr) -// } - -// // Attempt to get a reserved IP address -// address := "172.28.3.4" -// ip, getErr := client.GetReservedIPAddress(context.Background(), address) -// if getErr == nil { -// t.Errorf("Expected error when getting IP address due to insufficient permissions, but got none") -// } else { -// t.Logf("Correctly received %v for IP Address and error when getting IP address: %v", ip, getErr) -// } - -// // Attempt to delete a reserved IP address -// delAddr := "172.28.3.4" -// delErr := client.DeleteReservedIPAddress(context.Background(), delAddr) -// if delErr == nil { -// t.Errorf("Expected error when deleting IP address due to insufficient permissions, but got none") -// } else { -// t.Logf("Correctly received error when deleting IP address: %v", delErr) -// } -// } - -// // TestReservedIPAddresses_EndToEndTest performs an end-to-end test of the Reserved IP functionality -// // for users with the can_reserve_ip flag enabled -// func TestReservedIPAddresses_EndToEndTest(t *testing.T) { -// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_EndToEndTest") -// defer teardown() - -// filter := "" - -// ipList, err := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) - -// if err != nil { -// t.Fatalf("Error listing IP addresses: %v", err) -// } - -// initialCount := len(ipList) - -// // Attempt to reserve an IP -// resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ -// Region: "us-east", -// }) - -// if resErr != nil { -// t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) -// } - -// if resIP == nil { -// t.Fatalf("Reserved IP is nil") -// } - -// t.Logf("Successfully reserved IP: %+v", resIP) - -// // Fetch the reserved IP -// fetchedIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) -// if fetchErr != nil { -// t.Errorf("Error getting reserved IP address: %v", fetchErr) -// } - -// if fetchedIP == nil { -// t.Errorf("Retrieved reserved IP is nil") -// } - -// // Verify the list of IPs has increased -// verifyList, verifyErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) -// if verifyErr != nil { -// t.Fatalf("Error listing IP addresses after reservation: %v", verifyErr) -// } - -// if len(verifyList) != initialCount+1 { -// t.Errorf("Expected IP count to increase by 1, got %d, want %d", len(verifyList), initialCount+1) -// } - -// // Delete the reserved IP -// delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) -// if delErr != nil { -// t.Fatalf("Error deleting reserved IP address: %v", delErr) -// } - -// // Verify the IP has been deleted -// _, fetchDelErr := client.GetReservedIPAddress(context.Background(), resIP.Address) -// if fetchDelErr == nil { -// t.Errorf("Expected error when fetching deleted IP, got nil") -// } - -// verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) -// if verifyDelErr != nil { -// t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) -// } - -// if len(verifyDelList) != initialCount { -// t.Errorf("Expected IP count to return to initial count, got %d, want %d", len(verifyDelList), initialCount) -// } -// } +func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { + original := validTestAPIKey + dummyToken := "badtoken" + validTestAPIKey = dummyToken + + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_InsufficientPermissions") + defer teardown() + defer func() { validTestAPIKey = original }() + + filter := "" + ips, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if listErr == nil { + t.Errorf("Expected error due to insufficient permissions, but got none %v", ips) + } else { + t.Logf("Correctly received error when listing IP addresses: %v", listErr) + } + + if len(ips) != 0 { + t.Errorf("Expected no IP addresses due to insufficient permissions, but got some: %v", ips) + } + + // Attempt to reserve an IP address + resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + if resErr == nil { + t.Errorf("Expected error when reserving IP due to insufficient permissions, but got none") + } else { + t.Logf("Correctly received %v and error when reserving IP: %v", resIP, resErr) + } + + // Attempt to get a reserved IP address + address := "172.28.3.4" + ip, getErr := client.GetReservedIPAddress(context.Background(), address) + if getErr == nil { + t.Errorf("Expected error when getting IP address due to insufficient permissions, but got none") + } else { + t.Logf("Correctly received %v for IP Address and error when getting IP address: %v", ip, getErr) + } + + // Attempt to delete a reserved IP address + delAddr := "172.28.3.4" + delErr := client.DeleteReservedIPAddress(context.Background(), delAddr) + if delErr == nil { + t.Errorf("Expected error when deleting IP address due to insufficient permissions, but got none") + } else { + t.Logf("Correctly received error when deleting IP address: %v", delErr) + } +} + +// TestReservedIPAddresses_EndToEndTest performs an end-to-end test of the Reserved IP functionality +// for users with the can_reserve_ip flag enabled +func TestReservedIPAddresses_EndToEndTest(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_EndToEndTest") + defer teardown() + + filter := "" + + ipList, err := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + + if err != nil { + t.Fatalf("Error listing IP addresses: %v", err) + } + + initialCount := len(ipList) + + // Attempt to reserve an IP + resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + + if resErr != nil { + t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) + } + + if resIP == nil { + t.Fatalf("Reserved IP is nil") + } + + t.Logf("Successfully reserved IP: %+v", resIP) + + // Fetch the reserved IP + fetchedIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) + if fetchErr != nil { + t.Errorf("Error getting reserved IP address: %v", fetchErr) + } + + if fetchedIP == nil { + t.Errorf("Retrieved reserved IP is nil") + } + + // Verify the list of IPs has increased + verifyList, verifyErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if verifyErr != nil { + t.Fatalf("Error listing IP addresses after reservation: %v", verifyErr) + } + + if len(verifyList) != initialCount+1 { + t.Errorf("Expected IP count to increase by 1, got %d, want %d", len(verifyList), initialCount+1) + } + + // Delete the reserved IP + delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) + if delErr != nil { + t.Fatalf("Error deleting reserved IP address: %v", delErr) + } + + // Verify the IP has been deleted + _, fetchDelErr := client.GetReservedIPAddress(context.Background(), resIP.Address) + if fetchDelErr == nil { + t.Errorf("Expected error when fetching deleted IP, got nil") + } + + verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if verifyDelErr != nil { + t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) + } + + if len(verifyDelList) != initialCount { + t.Errorf("Expected IP count to return to initial count, got %d, want %d", len(verifyDelList), initialCount) + } +} // TestReservedIPAddresses_ListIPAddressesVariants tests filters for listing IP addresses -// func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { -// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") -// defer teardown() - -// // Reserve two IP addresses in us-east region -// reservedIPs := make([]string, 2) -// for i := 0; i < 2; i++ { -// reserveIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ -// Region: "us-east", -// }) -// if err != nil { -// t.Fatalf("Failed to reserve IP %d: %v", i+1, err) -// } -// reservedIPs[i] = reserveIP.Address -// t.Logf("Successfully reserved IP %d: %s", i+1, reserveIP.Address) -// } - -// // Defer cleanup of reserved IPs -// defer func() { -// for _, ip := range reservedIPs { -// err := client.DeleteReservedIPAddress(context.Background(), ip) -// if err != nil { -// t.Errorf("Failed to delete reserved IP %s: %v", ip, err) -// } -// } -// }() - -// // Create ListOptions with the filter for reserved IPs in us-east region -// listOptions := linodego.ListOptions{ -// PageOptions: &linodego.PageOptions{ -// Page: 0, -// }, -// Filter: "{\"reserved\":true,\"region\":\"us-east\"}", -// } - -// ipList, err := client.ListIPAddresses(context.Background(), &listOptions) - -// if err != nil { -// t.Fatalf("Error listing reserved IP addresses in us-east: %v", err) -// } - -// t.Logf("Retrieved %d reserved IP addresses in us-east", len(ipList)) - -// // Check if at least the two reserved IPs are in the list -// foundReservedIPs := 0 -// for _, ip := range ipList { -// if !ip.Reserved { -// t.Errorf("Expected all IPs to be reserved, but found non-reserved IP: %s", ip.Address) -// } -// if ip.Region != "us-east" { -// t.Errorf("Expected all IPs to be in us-east region, but found IP in %s region: %s", ip.Region, ip.Address) -// } -// for _, reservedIP := range reservedIPs { -// if ip.Address == reservedIP { -// foundReservedIPs++ -// break -// } -// } -// } - -// } +func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") + defer teardown() + + // Reserve two IP addresses in us-east region + reservedIPs := make([]string, 2) + for i := 0; i < 2; i++ { + reserveIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "us-east", + }) + if err != nil { + t.Fatalf("Failed to reserve IP %d: %v", i+1, err) + } + reservedIPs[i] = reserveIP.Address + t.Logf("Successfully reserved IP %d: %s", i+1, reserveIP.Address) + } + + // Defer cleanup of reserved IPs + defer func() { + for _, ip := range reservedIPs { + err := client.DeleteReservedIPAddress(context.Background(), ip) + if err != nil { + t.Errorf("Failed to delete reserved IP %s: %v", ip, err) + } + } + }() + + // Create ListOptions with the filter for reserved IPs in us-east region + listOptions := linodego.ListOptions{ + PageOptions: &linodego.PageOptions{ + Page: 0, + }, + Filter: "{\"reserved\":true,\"region\":\"us-east\"}", + } + + ipList, err := client.ListIPAddresses(context.Background(), &listOptions) + + if err != nil { + t.Fatalf("Error listing reserved IP addresses in us-east: %v", err) + } + + t.Logf("Retrieved %d reserved IP addresses in us-east", len(ipList)) + + // Check if at least the two reserved IPs are in the list + foundReservedIPs := 0 + for _, ip := range ipList { + if !ip.Reserved { + t.Errorf("Expected all IPs to be reserved, but found non-reserved IP: %s", ip.Address) + } + if ip.Region != "us-east" { + t.Errorf("Expected all IPs to be in us-east region, but found IP in %s region: %s", ip.Region, ip.Address) + } + for _, reservedIP := range reservedIPs { + if ip.Address == reservedIP { + foundReservedIPs++ + break + } + } + } + +} // TestReservedIPAddresses_GetIPAddressVariants tests various scenarios for getting a specific IP address -// func TestReservedIPAddresses_GetIPAddressVariants(t *testing.T) { -// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_GetIPAddressVariants") -// defer teardown() - -// // Reserve an IP for testing -// resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ -// Region: "us-east", -// }) - -// if resErr != nil { -// t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) -// } - -// if resIP == nil { -// t.Fatalf("Reserved IP is nil") -// } - -// t.Logf("Successfully reserved IP: %+v", resIP) - -// // Test getting a valid reserved IP -// validIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) -// if fetchErr != nil { -// t.Errorf("Error getting valid reserved IP address: %v", fetchErr) -// } - -// if validIP == nil { -// t.Errorf("Retrieved valid reserved IP is nil") -// } else { -// if validIP.Address != resIP.Address { -// t.Errorf("Retrieved IP address does not match reserved IP address. Got %s, want %s", validIP.Address, resIP.Address) -// } -// } - -// // Test getting an invalid IP -// invalidIP := "999.999.999.999" -// _, invalidFetchErr := client.GetReservedIPAddress(context.Background(), invalidIP) -// if invalidFetchErr == nil { -// t.Errorf("Expected error when fetching invalid IP, got nil") -// } - -// // Clean up: Delete the reserved IP -// delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) -// if delErr != nil { -// t.Errorf("Failed to delete reserved IP: %v", delErr) -// } -// } +func TestReservedIPAddresses_GetIPAddressVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_GetIPAddressVariants") + defer teardown() + + // Reserve an IP for testing + resIP, resErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{ + Region: "us-east", + }) + + if resErr != nil { + t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) + } + + if resIP == nil { + t.Fatalf("Reserved IP is nil") + } + + t.Logf("Successfully reserved IP: %+v", resIP) + + // Test getting a valid reserved IP + validIP, fetchErr := client.GetReservedIPAddress(context.Background(), resIP.Address) + if fetchErr != nil { + t.Errorf("Error getting valid reserved IP address: %v", fetchErr) + } + + if validIP == nil { + t.Errorf("Retrieved valid reserved IP is nil") + } else { + if validIP.Address != resIP.Address { + t.Errorf("Retrieved IP address does not match reserved IP address. Got %s, want %s", validIP.Address, resIP.Address) + } + } + + // Test getting an invalid IP + invalidIP := "999.999.999.999" + _, invalidFetchErr := client.GetReservedIPAddress(context.Background(), invalidIP) + if invalidFetchErr == nil { + t.Errorf("Expected error when fetching invalid IP, got nil") + } + + // Clean up: Delete the reserved IP + delErr := client.DeleteReservedIPAddress(context.Background(), resIP.Address) + if delErr != nil { + t.Errorf("Failed to delete reserved IP: %v", delErr) + } +} // TestReservedIPAddresses_ReserveIPVariants tests various scenarios for reserving an IP address func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { @@ -301,56 +301,56 @@ func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { } } -// // TestReservedIPAddresses_DeleteIPAddressVariants tests various scenarios for deleting a reserved IP address -// func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { -// client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_DeleteIPAddressVariants") -// defer teardown() - -// validRes, validErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) -// if validErr != nil { -// t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", validErr) -// } - -// if validRes == nil { -// t.Fatalf("Valid reservation returned nil IP") -// } - -// t.Logf("Successfully reserved IP: %+v", validRes) - -// filter := "" -// ipList, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) -// if listErr != nil { -// t.Fatalf("Error listing IP addresses: %v", listErr) -// } - -// if len(ipList) == 0 { -// t.Skip("No reserved IPs available for testing deletion") -// } - -// delErr := client.DeleteReservedIPAddress(context.Background(), validRes.Address) -// if delErr != nil { -// t.Fatalf("Failed to delete reserved IP address: %v", delErr) -// } - -// // Verify deletion -// verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) -// if verifyDelErr != nil { -// t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) -// } - -// if len(verifyDelList) >= len(ipList) { -// t.Errorf("IP address deletion not confirmed. Expected count < %d, got %d", len(ipList), len(verifyDelList)) -// } - -// _, fetchDelErr := client.GetReservedIPAddress(context.Background(), validRes.Address) -// if fetchDelErr == nil { -// t.Errorf("Expected error when fetching deleted IP, got nil") -// } - -// // Test deleting an unowned IP -// unownedIP := "255.255.255.4" -// delUnownedErr := client.DeleteReservedIPAddress(context.Background(), unownedIP) -// if delUnownedErr == nil { -// t.Errorf("Expected error when deleting unowned IP, got nil") -// } -// } +// TestReservedIPAddresses_DeleteIPAddressVariants tests various scenarios for deleting a reserved IP address +func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_DeleteIPAddressVariants") + defer teardown() + + validRes, validErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) + if validErr != nil { + t.Fatalf("Failed to reserve IP. This test should start with 0 reservations or reservations < limit. Error from the API: %v", validErr) + } + + if validRes == nil { + t.Fatalf("Valid reservation returned nil IP") + } + + t.Logf("Successfully reserved IP: %+v", validRes) + + filter := "" + ipList, listErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if listErr != nil { + t.Fatalf("Error listing IP addresses: %v", listErr) + } + + if len(ipList) == 0 { + t.Skip("No reserved IPs available for testing deletion") + } + + delErr := client.DeleteReservedIPAddress(context.Background(), validRes.Address) + if delErr != nil { + t.Fatalf("Failed to delete reserved IP address: %v", delErr) + } + + // Verify deletion + verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) + if verifyDelErr != nil { + t.Fatalf("Error listing IP addresses after deletion: %v", verifyDelErr) + } + + if len(verifyDelList) >= len(ipList) { + t.Errorf("IP address deletion not confirmed. Expected count < %d, got %d", len(ipList), len(verifyDelList)) + } + + _, fetchDelErr := client.GetReservedIPAddress(context.Background(), validRes.Address) + if fetchDelErr == nil { + t.Errorf("Expected error when fetching deleted IP, got nil") + } + + // Test deleting an unowned IP + unownedIP := "255.255.255.4" + delUnownedErr := client.DeleteReservedIPAddress(context.Background(), unownedIP) + if delUnownedErr == nil { + t.Errorf("Expected error when deleting unowned IP, got nil") + } +} From cb81bc2bc8f3350597fca33bab3ec3bcc9f0ca72 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 5 Sep 2024 14:04:42 -0400 Subject: [PATCH 15/43] Made changes to error messages, added mandatory checks and re-recorded fixtures to reflect new error messages --- network_reserved_ips.go | 2 +- ...edIPAddresses_DeleteIPAddressVariants.yaml | 28 +++++++------- .../TestReservedIPAddresses_EndToEndTest.yaml | 38 +++++++++---------- ...edIPAddresses_ListIPAddressesVariants.yaml | 38 +++++++++---------- test/integration/network_reserved_ips_test.go | 21 +++++----- 5 files changed, 64 insertions(+), 63 deletions(-) diff --git a/network_reserved_ips.go b/network_reserved_ips.go index 419d1aed0..66d058234 100644 --- a/network_reserved_ips.go +++ b/network_reserved_ips.go @@ -9,7 +9,7 @@ type ReserveIPOptions struct { Region string `json:"region"` } -// GetReservedIPs retrieves a list of reserved IP addresses +// ListReservedIPAddresses retrieves a list of reserved IP addresses func (c *Client) ListReservedIPAddresses(ctx context.Context, opts *ListOptions) ([]InstanceIP, error) { e := formatAPIPath("networking/reserved/ips") response, err := getPaginatedResults[InstanceIP](ctx, c, e, opts) diff --git a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml index c55673c56..a033a961f 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_DeleteIPAddressVariants.yaml @@ -14,8 +14,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", + body: '{"address": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -35,13 +35,13 @@ interactions: Connection: - keep-alive Content-Length: - - "256" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Thu, 05 Sep 2024 17:52:50 GMT Pragma: - no-cache Strict-Transport-Security: @@ -77,8 +77,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", + body: '{"data": [{"address": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], "page": 1, "pages": 1, "results": 1}' headers: @@ -99,13 +99,13 @@ interactions: Connection: - keep-alive Content-Length: - - "305" + - "313" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Thu, 05 Sep 2024 17:52:50 GMT Pragma: - no-cache Strict-Transport-Security: @@ -139,7 +139,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.20.39 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.178 method: DELETE response: body: '{}' @@ -167,7 +167,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Thu, 05 Sep 2024 17:52:50 GMT Pragma: - no-cache Strict-Transport-Security: @@ -228,7 +228,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Thu, 05 Sep 2024 17:52:50 GMT Pragma: - no-cache Strict-Transport-Security: @@ -262,7 +262,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.20.39 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.178 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -284,7 +284,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:22 GMT + - Thu, 05 Sep 2024 17:52:51 GMT Pragma: - no-cache Vary: @@ -332,7 +332,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:35 GMT + - Thu, 05 Sep 2024 17:52:51 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: diff --git a/test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml b/test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml index d0e273b45..1dcbe2b27 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_EndToEndTest.yaml @@ -39,7 +39,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:16 GMT + - Thu, 05 Sep 2024 17:52:47 GMT Pragma: - no-cache Strict-Transport-Security: @@ -76,8 +76,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", + body: '{"address": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -97,13 +97,13 @@ interactions: Connection: - keep-alive Content-Length: - - "261" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:19 GMT + - Thu, 05 Sep 2024 17:52:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -136,11 +136,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.178 method: GET response: - body: '{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", + body: '{"address": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -160,13 +160,13 @@ interactions: Connection: - keep-alive Content-Length: - - "261" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:19 GMT + - Thu, 05 Sep 2024 17:52:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -203,8 +203,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips?page=1 method: GET response: - body: '{"data": [{"address": "45.56.109.241", "gateway": "45.56.109.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-109-241.ip.linodeusercontent.com", + body: '{"data": [{"address": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}], "page": 1, "pages": 1, "results": 1}' headers: @@ -225,13 +225,13 @@ interactions: Connection: - keep-alive Content-Length: - - "310" + - "313" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:20 GMT + - Thu, 05 Sep 2024 17:52:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -265,7 +265,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.178 method: DELETE response: body: '{}' @@ -293,7 +293,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:20 GMT + - Thu, 05 Sep 2024 17:52:49 GMT Pragma: - no-cache Strict-Transport-Security: @@ -326,7 +326,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.109.241 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.178 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -348,7 +348,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:20 GMT + - Thu, 05 Sep 2024 17:52:49 GMT Pragma: - no-cache Vary: @@ -402,7 +402,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 29 Aug 2024 15:39:20 GMT + - Thu, 05 Sep 2024 17:52:49 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml index 16dbaea0d..bffe12226 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ListIPAddressesVariants.yaml @@ -14,8 +14,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.56.102.171", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-171.ip.linodeusercontent.com", + body: '{"address": "66.175.209.108", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-108.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -35,13 +35,13 @@ interactions: Connection: - keep-alive Content-Length: - - "261" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:22:20 GMT + - Thu, 05 Sep 2024 17:52:49 GMT Pragma: - no-cache Strict-Transport-Security: @@ -77,8 +77,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.56.102.42", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-42.ip.linodeusercontent.com", + body: '{"address": "66.175.209.141", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-141.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -98,13 +98,13 @@ interactions: Connection: - keep-alive Content-Length: - - "259" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:22:21 GMT + - Thu, 05 Sep 2024 17:52:49 GMT Pragma: - no-cache Strict-Transport-Security: @@ -142,12 +142,12 @@ interactions: url: https://api.linode.com/v4beta/networking/ips?page=1 method: GET response: - body: '{"page": 1, "pages": 1, "results": 2, "data": [{"address": "45.56.102.42", - "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": - "ipv4", "public": true, "rdns": "45-56-102-42.ip.linodeusercontent.com", "linode_id": + body: '{"page": 1, "pages": 1, "results": 2, "data": [{"address": "66.175.209.108", + "gateway": "66.175.209.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "66-175-209-108.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, {"address": - "45.56.102.171", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", "prefix": - 24, "type": "ipv4", "public": true, "rdns": "45-56-102-171.ip.linodeusercontent.com", + "66.175.209.141", "gateway": "66.175.209.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-141.ip.linodeusercontent.com", "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}]}' headers: Access-Control-Allow-Credentials: @@ -167,13 +167,13 @@ interactions: Connection: - keep-alive Content-Length: - - "571" + - "579" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:22:21 GMT + - Thu, 05 Sep 2024 17:52:49 GMT Pragma: - no-cache Strict-Transport-Security: @@ -207,7 +207,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.102.171 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.108 method: DELETE response: body: '{}' @@ -235,7 +235,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:22:21 GMT + - Thu, 05 Sep 2024 17:52:50 GMT Pragma: - no-cache Strict-Transport-Security: @@ -268,7 +268,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.56.102.42 + url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.141 method: DELETE response: body: '{}' @@ -296,7 +296,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:22:22 GMT + - Thu, 05 Sep 2024 17:52:50 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 05fa727af..4b0910e46 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -10,7 +10,7 @@ import ( ) // TestReservedIPAddresses_InsufficientPermissions tests the behavior when a user account -// doesn't have the can_reserve_ip flag enabled +// doesn't have the permission to use the Reserved IP feature func TestReservedIPAddresses_InsufficientPermissions(t *testing.T) { original := validTestAPIKey dummyToken := "badtoken" @@ -86,10 +86,6 @@ func TestReservedIPAddresses_EndToEndTest(t *testing.T) { t.Fatalf("Failed to reserve IP. This test expects the user to have 0 prior reservations and the ip_reservation_limit to be 2. Error from the API: %v", resErr) } - if resIP == nil { - t.Fatalf("Reserved IP is nil") - } - t.Logf("Successfully reserved IP: %+v", resIP) // Fetch the reserved IP @@ -99,7 +95,7 @@ func TestReservedIPAddresses_EndToEndTest(t *testing.T) { } if fetchedIP == nil { - t.Errorf("Retrieved reserved IP is nil") + t.Errorf("Expected %s but got nil indicating a failure in fetching the reserved IP", resIP.Address) } // Verify the list of IPs has increased @@ -121,7 +117,7 @@ func TestReservedIPAddresses_EndToEndTest(t *testing.T) { // Verify the IP has been deleted _, fetchDelErr := client.GetReservedIPAddress(context.Background(), resIP.Address) if fetchDelErr == nil { - t.Errorf("Expected error when fetching deleted IP, got nil") + t.Errorf("Expected error when fetching %s, got nil", resIP.Address) } verifyDelList, verifyDelErr := client.ListReservedIPAddresses(context.Background(), NewListOptions(0, filter)) @@ -139,9 +135,11 @@ func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ListIPAddressesVariants") defer teardown() + expected_ips := 2 + // Reserve two IP addresses in us-east region - reservedIPs := make([]string, 2) - for i := 0; i < 2; i++ { + reservedIPs := make([]string, expected_ips) + for i := 0; i < expected_ips; i++ { reserveIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ Region: "us-east", }) @@ -194,6 +192,9 @@ func TestReservedIPAddresses_ListIPAddressesVariants(t *testing.T) { } } } + if foundReservedIPs != expected_ips { + t.Errorf("Expected %d but found %d while listing reserved IP addresses", expected_ips, foundReservedIPs) + } } @@ -324,7 +325,7 @@ func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { } if len(ipList) == 0 { - t.Skip("No reserved IPs available for testing deletion") + t.Fatalf("No reserved IPs available for testing deletion") } delErr := client.DeleteReservedIPAddress(context.Background(), validRes.Address) From 456d0f269e86e270d97a022a890a8ea4e07bfbc5 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 3 Sep 2024 11:40:25 -0400 Subject: [PATCH 16/43] Added new middleware system (#571) --- client.go | 45 ++++++++++++++++--- client_http.go | 4 ++ client_test.go | 117 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 157 insertions(+), 9 deletions(-) diff --git a/client.go b/client.go index 348e71cc9..28433b766 100644 --- a/client.go +++ b/client.go @@ -136,7 +136,7 @@ type RequestParams struct { // Generic helper to execute HTTP requests using the net/http package // // nolint:unused, funlen, gocognit -func (c *httpClient) doRequest(ctx context.Context, method, url string, params RequestParams, mutators ...func(req *http.Request) error) error { +func (c *httpClient) doRequest(ctx context.Context, method, url string, params RequestParams) error { var ( req *http.Request bodyBuffer *bytes.Buffer @@ -150,7 +150,7 @@ func (c *httpClient) doRequest(ctx context.Context, method, url string, params R return err } - if err = c.applyMutators(req, mutators); err != nil { + if err = c.applyBeforeRequest(req); err != nil { return err } @@ -180,6 +180,12 @@ func (c *httpClient) doRequest(ctx context.Context, method, url string, params R return err } } + + // Apply after-response mutations + if err = c.applyAfterResponse(resp); err != nil { + return err + } + return nil } @@ -252,13 +258,26 @@ func (c *httpClient) createRequest(ctx context.Context, method, url string, para } // nolint:unused -func (c *httpClient) applyMutators(req *http.Request, mutators []func(req *http.Request) error) error { - for _, mutate := range mutators { +func (c *httpClient) applyBeforeRequest(req *http.Request) error { + for _, mutate := range c.onBeforeRequest { if err := mutate(req); err != nil { if c.debug && c.logger != nil { - c.logger.Errorf("failed to mutate request: %v", err) + c.logger.Errorf("failed to mutate before request: %v", err) + } + return fmt.Errorf("failed to mutate before request: %w", err) + } + } + return nil +} + +// nolint:unused +func (c *httpClient) applyAfterResponse(resp *http.Response) error { + for _, mutate := range c.onAfterResponse { + if err := mutate(resp); err != nil { + if c.debug && c.logger != nil { + c.logger.Errorf("failed to mutate after response: %v", err) } - return fmt.Errorf("failed to mutate request: %w", err) + return fmt.Errorf("failed to mutate after response: %w", err) } } return nil @@ -394,6 +413,20 @@ func (c *Client) OnAfterResponse(m func(response *Response) error) { }) } +// nolint:unused +func (c *httpClient) httpOnBeforeRequest(m func(*http.Request) error) *httpClient { + c.onBeforeRequest = append(c.onBeforeRequest, m) + + return c +} + +// nolint:unused +func (c *httpClient) httpOnAfterResponse(m func(*http.Response) error) *httpClient { + c.onAfterResponse = append(c.onAfterResponse, m) + + return c +} + // UseURL parses the individual components of the given API URL and configures the client // accordingly. For example, a valid URL. // For example: diff --git a/client_http.go b/client_http.go index 85058e6cf..7f16362c5 100644 --- a/client_http.go +++ b/client_http.go @@ -49,4 +49,8 @@ type httpClient struct { cachedEntryLock *sync.RWMutex //nolint:unused logger httpLogger + //nolint:unused + onBeforeRequest []func(*http.Request) error + //nolint:unused + onAfterResponse []func(*http.Response) error } diff --git a/client_test.go b/client_test.go index 2b29204d1..93b133f97 100644 --- a/client_test.go +++ b/client_test.go @@ -313,7 +313,42 @@ func TestDoRequest_FailedDecodeResponse(t *testing.T) { } } -func TestDoRequest_MutatorError(t *testing.T) { +func TestDoRequest_BeforeRequestSuccess(t *testing.T) { + var capturedRequest *http.Request + + handler := func(w http.ResponseWriter, r *http.Request) { + capturedRequest = r // Capture the request to inspect it later + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"message":"success"}`)) + } + server := httptest.NewServer(http.HandlerFunc(handler)) + defer server.Close() + + client := &httpClient{ + httpClient: server.Client(), + } + + // Define a mutator that successfully modifies the request + mutator := func(req *http.Request) error { + req.Header.Set("X-Custom-Header", "CustomValue") + return nil + } + + client.httpOnBeforeRequest(mutator) + + err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + if err != nil { + t.Fatalf("expected no error, got: %v", err) + } + + // Check if the header was successfully added to the captured request + if reqHeader := capturedRequest.Header.Get("X-Custom-Header"); reqHeader != "CustomValue" { + t.Fatalf("expected X-Custom-Header to be set to CustomValue, got: %v", reqHeader) + } +} + +func TestDoRequest_BeforeRequestError(t *testing.T) { handler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") @@ -330,8 +365,71 @@ func TestDoRequest_MutatorError(t *testing.T) { return errors.New("mutator error") } - err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}, mutator) - expectedErr := "failed to mutate request" + client.httpOnBeforeRequest(mutator) + + err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + expectedErr := "failed to mutate before request" + if err == nil || !strings.Contains(err.Error(), expectedErr) { + t.Fatalf("expected error %q, got: %v", expectedErr, err) + } +} + +func TestDoRequest_AfterResponseSuccess(t *testing.T) { + handler := func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"message":"success"}`)) + } + server := httptest.NewServer(http.HandlerFunc(handler)) + defer server.Close() + + // Create a custom RoundTripper to capture the response + tr := &testRoundTripper{ + Transport: server.Client().Transport, + } + client := &httpClient{ + httpClient: &http.Client{Transport: tr}, + } + + mutator := func(resp *http.Response) error { + resp.Header.Set("X-Modified-Header", "ModifiedValue") + return nil + } + + client.httpOnAfterResponse(mutator) + + err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + if err != nil { + t.Fatalf("expected no error, got: %v", err) + } + + // Check if the header was successfully added to the response + if respHeader := tr.Response.Header.Get("X-Modified-Header"); respHeader != "ModifiedValue" { + t.Fatalf("expected X-Modified-Header to be set to ModifiedValue, got: %v", respHeader) + } +} + +func TestDoRequest_AfterResponseError(t *testing.T) { + handler := func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"message":"success"}`)) + } + server := httptest.NewServer(http.HandlerFunc(handler)) + defer server.Close() + + client := &httpClient{ + httpClient: server.Client(), + } + + mutator := func(resp *http.Response) error { + return errors.New("mutator error") + } + + client.httpOnAfterResponse(mutator) + + err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + expectedErr := "failed to mutate after response" if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Fatalf("expected error %q, got: %v", expectedErr, err) } @@ -426,3 +524,16 @@ func removeTimestamps(log string) string { } return strings.Join(filteredLines, "\n") } + +type testRoundTripper struct { + Transport http.RoundTripper + Response *http.Response +} + +func (t *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + resp, err := t.Transport.RoundTrip(req) + if err == nil { + t.Response = resp + } + return resp, err +} From 1867029bc608d3fa64b061ac20307a0360cb8551 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 08:03:02 -0700 Subject: [PATCH 17/43] build(deps): bump golang.org/x/oauth2 from 0.22.0 to 0.23.0 (#574) * build(deps): bump golang.org/x/oauth2 from 0.22.0 to 0.23.0 Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.22.0 to 0.23.0. - [Commits](https://github.com/golang/oauth2/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Ran make tidy --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: ezilber-akamai --- go.mod | 2 +- go.sum | 4 ++-- k8s/go.mod | 2 +- k8s/go.sum | 4 ++-- test/go.mod | 2 +- test/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 2b4ef8318..ab8431531 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/jarcoal/httpmock v1.3.1 golang.org/x/net v0.28.0 - golang.org/x/oauth2 v0.22.0 + golang.org/x/oauth2 v0.23.0 golang.org/x/text v0.17.0 gopkg.in/ini.v1 v1.66.6 ) diff --git a/go.sum b/go.sum index 7491ec6f4..3e6284a76 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/k8s/go.mod b/k8s/go.mod index b9e7aa28a..6a889d321 100644 --- a/k8s/go.mod +++ b/k8s/go.mod @@ -29,7 +29,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect diff --git a/k8s/go.sum b/k8s/go.sum index e240af749..f805c9372 100644 --- a/k8s/go.sum +++ b/k8s/go.sum @@ -102,8 +102,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/test/go.mod b/test/go.mod index c3b6dedbc..316e5c934 100644 --- a/test/go.mod +++ b/test/go.mod @@ -8,7 +8,7 @@ require ( github.com/linode/linodego/k8s v0.0.0-00010101000000-000000000000 github.com/stretchr/testify v1.9.0 golang.org/x/net v0.28.0 - golang.org/x/oauth2 v0.22.0 + golang.org/x/oauth2 v0.23.0 k8s.io/client-go v0.29.4 ) diff --git a/test/go.sum b/test/go.sum index 96d01a529..12970593a 100644 --- a/test/go.sum +++ b/test/go.sum @@ -107,8 +107,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From af6a7bdf8668c366fd9d19970560bbb4d57ac6aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:49:28 -0400 Subject: [PATCH 18/43] build(deps): bump golang.org/x/text from 0.17.0 to 0.18.0 (#575) * build(deps): bump golang.org/x/text from 0.17.0 to 0.18.0 Bumps [golang.org/x/text](https://github.com/golang/text) from 0.17.0 to 0.18.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.17.0...v0.18.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * make tidy --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ye Chen --- go.mod | 2 +- go.sum | 4 ++-- k8s/go.mod | 2 +- k8s/go.sum | 4 ++-- test/go.mod | 2 +- test/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index ab8431531..5d14b6bb4 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/jarcoal/httpmock v1.3.1 golang.org/x/net v0.28.0 golang.org/x/oauth2 v0.23.0 - golang.org/x/text v0.17.0 + golang.org/x/text v0.18.0 gopkg.in/ini.v1 v1.66.6 ) diff --git a/go.sum b/go.sum index 3e6284a76..34fdd1af5 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/k8s/go.mod b/k8s/go.mod index 6a889d321..9675da007 100644 --- a/k8s/go.mod +++ b/k8s/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/k8s/go.sum b/k8s/go.sum index f805c9372..b9158ed16 100644 --- a/k8s/go.sum +++ b/k8s/go.sum @@ -137,8 +137,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/test/go.mod b/test/go.mod index 316e5c934..c89aa65a4 100644 --- a/test/go.mod +++ b/test/go.mod @@ -36,7 +36,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/test/go.sum b/test/go.sum index 12970593a..969ec019a 100644 --- a/test/go.sum +++ b/test/go.sum @@ -142,8 +142,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From b25e83d3eb442999fa312360a0f9d9d554515d7c Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:15:20 -0400 Subject: [PATCH 19/43] new: Add support LKE, Volume, NodeBalancer, and network transfer pricing endpoints (#573) * Add LKE types endpoints * Support base struct; add NB types endpoints * Add volume types * Add network transfer prices * Add price and region price structs * Revert IPv6 fixtures * Add missing fixtures --- base_types.go | 29 ++++++++ lke_types.go | 47 +++++++++++++ network_transfer_prices.go | 45 ++++++++++++ nodebalancer_types.go | 45 ++++++++++++ .../fixtures/TestLKEType_List.yaml | 70 +++++++++++++++++++ .../TestNetworkTransferPrice_List.yaml | 70 +++++++++++++++++++ .../fixtures/TestNodeBalancerType_List.yaml | 68 ++++++++++++++++++ .../fixtures/TestVolumeType_List.yaml | 68 ++++++++++++++++++ test/integration/lke_types_test.go | 43 ++++++++++++ .../network_transfer_prices_test.go | 40 +++++++++++ test/integration/nodebalancer_types_test.go | 40 +++++++++++ test/integration/volume_types_test.go | 40 +++++++++++ volumes_types.go | 45 ++++++++++++ 13 files changed, 650 insertions(+) create mode 100644 base_types.go create mode 100644 lke_types.go create mode 100644 network_transfer_prices.go create mode 100644 nodebalancer_types.go create mode 100644 test/integration/fixtures/TestLKEType_List.yaml create mode 100644 test/integration/fixtures/TestNetworkTransferPrice_List.yaml create mode 100644 test/integration/fixtures/TestNodeBalancerType_List.yaml create mode 100644 test/integration/fixtures/TestVolumeType_List.yaml create mode 100644 test/integration/lke_types_test.go create mode 100644 test/integration/network_transfer_prices_test.go create mode 100644 test/integration/nodebalancer_types_test.go create mode 100644 test/integration/volume_types_test.go create mode 100644 volumes_types.go diff --git a/base_types.go b/base_types.go new file mode 100644 index 000000000..dbaafe317 --- /dev/null +++ b/base_types.go @@ -0,0 +1,29 @@ +// This package contains various type-related base classes intended +// to be used in composition across type structures in this project. + +package linodego + +// baseType is a base struct containing the core fields of a resource type +// returned from the Linode API. +type baseType[PriceType any, RegionPriceType any] struct { + ID string `json:"id"` + Label string `json:"label"` + Price PriceType `json:"price"` + RegionPrices []RegionPriceType `json:"region_prices"` + Transfer int `json:"transfer"` +} + +// baseTypePrice is a base struct containing the core fields of a resource type's +// base price. +type baseTypePrice struct { + Hourly float64 `json:"hourly"` + Monthly float64 `json:"monthly"` +} + +// baseTypeRegionPrice is a base struct containing the core fields of a resource type's +// region-specific price. +type baseTypeRegionPrice struct { + baseTypePrice + + ID string `json:"id"` +} diff --git a/lke_types.go b/lke_types.go new file mode 100644 index 000000000..14273bbd1 --- /dev/null +++ b/lke_types.go @@ -0,0 +1,47 @@ +package linodego + +import ( + "context" +) + +// LKEType represents a single valid LKE type. +// NOTE: This typically corresponds to the availability of a cluster's +// control plane. +type LKEType struct { + baseType[LKETypePrice, LKETypeRegionPrice] +} + +// LKETypePrice represents the base hourly and monthly prices +// for an LKE type entry. +type LKETypePrice struct { + baseTypePrice +} + +// LKETypeRegionPrice represents the regional hourly and monthly prices +// for an LKE type entry. +type LKETypeRegionPrice struct { + baseTypeRegionPrice +} + +// ListLKETypes lists LKE types. This endpoint is cached by default. +func (c *Client) ListLKETypes(ctx context.Context, opts *ListOptions) ([]LKEType, error) { + e := "lke/types" + + endpoint, err := generateListCacheURL(e, opts) + if err != nil { + return nil, err + } + + if result := c.getCachedResponse(endpoint); result != nil { + return result.([]LKEType), nil + } + + response, err := getPaginatedResults[LKEType](ctx, c, e, opts) + if err != nil { + return nil, err + } + + c.addCachedResponse(endpoint, response, &cacheExpiryTime) + + return response, nil +} diff --git a/network_transfer_prices.go b/network_transfer_prices.go new file mode 100644 index 000000000..daa25e885 --- /dev/null +++ b/network_transfer_prices.go @@ -0,0 +1,45 @@ +package linodego + +import ( + "context" +) + +// NetworkTransferPrice represents a single valid network transfer price. +type NetworkTransferPrice struct { + baseType[NetworkTransferTypePrice, NetworkTransferTypeRegionPrice] +} + +// NetworkTransferTypePrice represents the base hourly and monthly prices +// for a network transfer price entry. +type NetworkTransferTypePrice struct { + baseTypePrice +} + +// NetworkTransferTypeRegionPrice represents the regional hourly and monthly prices +// for a network transfer price entry. +type NetworkTransferTypeRegionPrice struct { + baseTypeRegionPrice +} + +// ListNetworkTransferPrices lists network transfer prices. This endpoint is cached by default. +func (c *Client) ListNetworkTransferPrices(ctx context.Context, opts *ListOptions) ([]NetworkTransferPrice, error) { + e := "network-transfer/prices" + + endpoint, err := generateListCacheURL(e, opts) + if err != nil { + return nil, err + } + + if result := c.getCachedResponse(endpoint); result != nil { + return result.([]NetworkTransferPrice), nil + } + + response, err := getPaginatedResults[NetworkTransferPrice](ctx, c, e, opts) + if err != nil { + return nil, err + } + + c.addCachedResponse(endpoint, response, &cacheExpiryTime) + + return response, nil +} diff --git a/nodebalancer_types.go b/nodebalancer_types.go new file mode 100644 index 000000000..879665d43 --- /dev/null +++ b/nodebalancer_types.go @@ -0,0 +1,45 @@ +package linodego + +import ( + "context" +) + +// NodeBalancerType represents a single valid NodeBalancer type. +type NodeBalancerType struct { + baseType[NodeBalancerTypePrice, NodeBalancerTypeRegionPrice] +} + +// NodeBalancerTypePrice represents the base hourly and monthly prices +// for a NodeBalancer type entry. +type NodeBalancerTypePrice struct { + baseTypePrice +} + +// NodeBalancerTypeRegionPrice represents the regional hourly and monthly prices +// for a NodeBalancer type entry. +type NodeBalancerTypeRegionPrice struct { + baseTypeRegionPrice +} + +// ListNodeBalancerTypes lists NodeBalancer types. This endpoint is cached by default. +func (c *Client) ListNodeBalancerTypes(ctx context.Context, opts *ListOptions) ([]NodeBalancerType, error) { + e := "nodebalancers/types" + + endpoint, err := generateListCacheURL(e, opts) + if err != nil { + return nil, err + } + + if result := c.getCachedResponse(endpoint); result != nil { + return result.([]NodeBalancerType), nil + } + + response, err := getPaginatedResults[NodeBalancerType](ctx, c, e, opts) + if err != nil { + return nil, err + } + + c.addCachedResponse(endpoint, response, &cacheExpiryTime) + + return response, nil +} diff --git a/test/integration/fixtures/TestLKEType_List.yaml b/test/integration/fixtures/TestLKEType_List.yaml new file mode 100644 index 000000000..8025faeef --- /dev/null +++ b/test/integration/fixtures/TestLKEType_List.yaml @@ -0,0 +1,70 @@ +--- +version: 1 +interactions: +- 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/lke/types?page=1 + method: GET + response: + body: '{"data": [{"id": "lke-sa", "label": "LKE Standard Availability", "price": + {"hourly": 0.0, "monthly": 0.0}, "region_prices": [], "transfer": 0}, {"id": + "lke-ha", "label": "LKE High Availability", "price": {"hourly": 0.09, "monthly": + 60.0}, "region_prices": [{"id": "id-cgk", "hourly": 0.108, "monthly": 72.0}, + {"id": "br-gru", "hourly": 0.126, "monthly": 84.0}], "transfer": 0}], "page": + 1, "pages": 1, "results": 2}' + 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: + - "415" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 05 Sep 2024 17:47:57 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - '*' + 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: "" diff --git a/test/integration/fixtures/TestNetworkTransferPrice_List.yaml b/test/integration/fixtures/TestNetworkTransferPrice_List.yaml new file mode 100644 index 000000000..6ac929255 --- /dev/null +++ b/test/integration/fixtures/TestNetworkTransferPrice_List.yaml @@ -0,0 +1,70 @@ +--- +version: 1 +interactions: +- 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/network-transfer/prices?page=1 + method: GET + response: + body: '{"data": [{"id": "distributed_network_transfer", "label": "Distributed + Network Transfer", "price": {"hourly": 0.01, "monthly": null}, "region_prices": + [], "transfer": 0}, {"id": "network_transfer", "label": "Network Transfer", + "price": {"hourly": 0.005, "monthly": null}, "region_prices": [{"id": "id-cgk", + "hourly": 0.015, "monthly": null}, {"id": "br-gru", "hourly": 0.007, "monthly": + null}], "transfer": 0}], "page": 1, "pages": 1, "results": 2}' + 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: + - "448" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 04 Sep 2024 18:06:01 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - '*' + 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: "" diff --git a/test/integration/fixtures/TestNodeBalancerType_List.yaml b/test/integration/fixtures/TestNodeBalancerType_List.yaml new file mode 100644 index 000000000..e05e369b4 --- /dev/null +++ b/test/integration/fixtures/TestNodeBalancerType_List.yaml @@ -0,0 +1,68 @@ +--- +version: 1 +interactions: +- 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/nodebalancers/types?page=1 + method: GET + response: + body: '{"data": [{"id": "nodebalancer", "label": "NodeBalancer", "price": {"hourly": + 0.015, "monthly": 10.0}, "region_prices": [{"id": "id-cgk", "hourly": 0.018, + "monthly": 12.0}, {"id": "br-gru", "hourly": 0.021, "monthly": 14.0}], "transfer": + 0}], "page": 1, "pages": 1, "results": 1}' + 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: + - "279" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 04 Sep 2024 17:52:02 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - '*' + 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: "" diff --git a/test/integration/fixtures/TestVolumeType_List.yaml b/test/integration/fixtures/TestVolumeType_List.yaml new file mode 100644 index 000000000..25e3c3247 --- /dev/null +++ b/test/integration/fixtures/TestVolumeType_List.yaml @@ -0,0 +1,68 @@ +--- +version: 1 +interactions: +- 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/volumes/types?page=1 + method: GET + response: + body: '{"data": [{"id": "volume", "label": "Storage Volume", "price": {"hourly": + 0.00015, "monthly": 0.1}, "region_prices": [{"id": "id-cgk", "hourly": 0.00018, + "monthly": 0.12}, {"id": "br-gru", "hourly": 0.00021, "monthly": 0.14}], "transfer": + 0}], "page": 1, "pages": 1, "results": 1}' + 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: + - "280" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 04 Sep 2024 17:59:26 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - '*' + 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: "" diff --git a/test/integration/lke_types_test.go b/test/integration/lke_types_test.go new file mode 100644 index 000000000..1095e9cd9 --- /dev/null +++ b/test/integration/lke_types_test.go @@ -0,0 +1,43 @@ +package integration + +import ( + "context" + "testing" + + "github.com/linode/linodego" + "github.com/stretchr/testify/require" +) + +func TestLKEType_List(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestLKEType_List") + defer teardown() + + lkeTypes, err := client.ListLKETypes(context.Background(), nil) + require.NoError(t, err) + require.Greater(t, len(lkeTypes), 0) + + for _, lkeType := range lkeTypes { + validateLKEType(t, lkeType) + } +} + +func validateLKEType( + t *testing.T, + lkeType linodego.LKEType, +) { + require.NotEmpty(t, lkeType.ID) + require.NotEmpty(t, lkeType.Label) + + // NOTE: We use >= 0 here because this is treated as an additional + // cost on top of the base LKE cluster price, meaning SA has its + // prices set to 0. + require.GreaterOrEqual(t, lkeType.Price.Hourly, 0.0) + require.GreaterOrEqual(t, lkeType.Price.Monthly, 0.0) + require.GreaterOrEqual(t, lkeType.Transfer, 0) + + for _, regionPrice := range lkeType.RegionPrices { + require.NotEmpty(t, regionPrice.ID) + require.GreaterOrEqual(t, regionPrice.Hourly, 0.0) + require.GreaterOrEqual(t, regionPrice.Monthly, 0.0) + } +} diff --git a/test/integration/network_transfer_prices_test.go b/test/integration/network_transfer_prices_test.go new file mode 100644 index 000000000..641b7c4ea --- /dev/null +++ b/test/integration/network_transfer_prices_test.go @@ -0,0 +1,40 @@ +package integration + +import ( + "context" + "testing" + + "github.com/linode/linodego" + "github.com/stretchr/testify/require" +) + +func TestNetworkTransferPrice_List(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestNetworkTransferPrice_List") + defer teardown() + + prices, err := client.ListNetworkTransferPrices(context.Background(), nil) + require.NoError(t, err) + require.Greater(t, len(prices), 0) + + for _, price := range prices { + validateNetworkTransferPrice(t, price) + } +} + +func validateNetworkTransferPrice( + t *testing.T, + price linodego.NetworkTransferPrice, +) { + require.NotEmpty(t, price.ID) + require.NotEmpty(t, price.Label) + + // NOTE: We do not check for monthly prices here because it is + // explicitly set to null. + require.Greater(t, price.Price.Hourly, 0.0) + require.GreaterOrEqual(t, price.Transfer, 0) + + for _, regionPrice := range price.RegionPrices { + require.NotEmpty(t, regionPrice.ID) + require.Greater(t, regionPrice.Hourly, 0.0) + } +} diff --git a/test/integration/nodebalancer_types_test.go b/test/integration/nodebalancer_types_test.go new file mode 100644 index 000000000..f764e8e33 --- /dev/null +++ b/test/integration/nodebalancer_types_test.go @@ -0,0 +1,40 @@ +package integration + +import ( + "context" + "testing" + + "github.com/linode/linodego" + "github.com/stretchr/testify/require" +) + +func TestNodeBalancerType_List(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestNodeBalancerType_List") + defer teardown() + + nbTypes, err := client.ListNodeBalancerTypes(context.Background(), nil) + require.NoError(t, err) + require.Greater(t, len(nbTypes), 0) + + for _, nbType := range nbTypes { + validateNodeBalancerType(t, nbType) + } +} + +func validateNodeBalancerType( + t *testing.T, + nbType linodego.NodeBalancerType, +) { + require.NotEmpty(t, nbType.ID) + require.NotEmpty(t, nbType.Label) + + require.Greater(t, nbType.Price.Hourly, 0.0) + require.Greater(t, nbType.Price.Monthly, 0.0) + require.GreaterOrEqual(t, nbType.Transfer, 0) + + for _, regionPrice := range nbType.RegionPrices { + require.NotEmpty(t, regionPrice.ID) + require.Greater(t, regionPrice.Hourly, 0.0) + require.Greater(t, regionPrice.Monthly, 0.0) + } +} diff --git a/test/integration/volume_types_test.go b/test/integration/volume_types_test.go new file mode 100644 index 000000000..919ac8080 --- /dev/null +++ b/test/integration/volume_types_test.go @@ -0,0 +1,40 @@ +package integration + +import ( + "context" + "testing" + + "github.com/linode/linodego" + "github.com/stretchr/testify/require" +) + +func TestVolumeType_List(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestVolumeType_List") + defer teardown() + + volumeTypes, err := client.ListVolumeTypes(context.Background(), nil) + require.NoError(t, err) + require.Greater(t, len(volumeTypes), 0) + + for _, volumeType := range volumeTypes { + validateVolumeType(t, volumeType) + } +} + +func validateVolumeType( + t *testing.T, + volumeType linodego.VolumeType, +) { + require.NotEmpty(t, volumeType.ID) + require.NotEmpty(t, volumeType.Label) + + require.Greater(t, volumeType.Price.Hourly, 0.0) + require.Greater(t, volumeType.Price.Monthly, 0.0) + require.GreaterOrEqual(t, volumeType.Transfer, 0) + + for _, regionPrice := range volumeType.RegionPrices { + require.NotEmpty(t, regionPrice.ID) + require.Greater(t, regionPrice.Hourly, 0.0) + require.Greater(t, regionPrice.Monthly, 0.0) + } +} diff --git a/volumes_types.go b/volumes_types.go new file mode 100644 index 000000000..887a3c5aa --- /dev/null +++ b/volumes_types.go @@ -0,0 +1,45 @@ +package linodego + +import ( + "context" +) + +// VolumeType represents a single valid Volume type. +type VolumeType struct { + baseType[VolumeTypePrice, VolumeTypeRegionPrice] +} + +// VolumeTypePrice represents the base hourly and monthly prices +// for a volume type entry. +type VolumeTypePrice struct { + baseTypePrice +} + +// VolumeTypeRegionPrice represents the regional hourly and monthly prices +// for a volume type entry. +type VolumeTypeRegionPrice struct { + baseTypeRegionPrice +} + +// ListVolumeTypes lists Volume types. This endpoint is cached by default. +func (c *Client) ListVolumeTypes(ctx context.Context, opts *ListOptions) ([]VolumeType, error) { + e := "volumes/types" + + endpoint, err := generateListCacheURL(e, opts) + if err != nil { + return nil, err + } + + if result := c.getCachedResponse(endpoint); result != nil { + return result.([]VolumeType), nil + } + + response, err := getPaginatedResults[VolumeType](ctx, c, e, opts) + if err != nil { + return nil, err + } + + c.addCachedResponse(endpoint, response, &cacheExpiryTime) + + return response, nil +} From 3bb8dc095325c4c59362c0b431543db197b9bad9 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 16 Sep 2024 16:14:25 -0400 Subject: [PATCH 20/43] Add test case for ip limit exceed --- ...ReservedIPAddresses_ReserveIPVariants.yaml | 305 +----------------- test/integration/network_reserved_ips_test.go | 27 +- 2 files changed, 29 insertions(+), 303 deletions(-) diff --git a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml index aa474a0c6..313e5a87d 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -31,7 +31,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:57:42 GMT + - Mon, 16 Sep 2024 15:57:36 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -41,7 +41,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -75,7 +75,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:57:42 GMT + - Mon, 16 Sep 2024 15:57:36 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -85,7 +85,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -119,7 +119,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 03 Sep 2024 20:57:42 GMT + - Mon, 16 Sep 2024 15:57:36 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -129,300 +129,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "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.56.102.171", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-171.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: - - Tue, 03 Sep 2024 20:57: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: - - "400" - 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.56.102.42", "gateway": "45.56.102.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-102-42.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: - - Tue, 03 Sep 2024 20:57: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: - - "400" - 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: '{"errors": [{"reason": "Additional Reserved 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: - - "147" - Content-Type: - - application/json - Expires: - - Tue, 03 Sep 2024 20:57:44 GMT - Pragma: - - no-cache - X-Accepted-Oauth-Scopes: - - ips:read_write - X-Frame-Options: - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "400" - 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.56.102.171 - 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 20:57: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/45.56.102.42 - 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 20:57: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/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 4b0910e46..202e24fd6 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -2,6 +2,7 @@ package integration import ( "context" + "strings" "testing" @@ -294,11 +295,29 @@ func TestReservedIPAddresses_ReserveIPAddressVariants(t *testing.T) { reservedIPs = append(reservedIPs, reserveIP.Address) t.Logf("Successfully reserved IP %d: %s", i+1, reserveIP.Address) } +} + +func TestReservedIPAddresses_ExceedLimit(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ExceedLimit") + defer teardown() - // Verify that we can't reserve more IPs - _, exceedErr := client.ReserveIPAddress(context.Background(), ReserveIPOptions{Region: "us-east"}) - if exceedErr == nil { - t.Errorf("Expected error when exceeding reservation limit, got nil") + // Reserve IPs until the limit is reached and assert the error message + for i := 0; i < 100; i++ { + _, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: "us-east", + }) + if err != nil { + expectedErrorMessage := "[500] Could not reserve IP address" + if !strings.Contains(err.Error(), expectedErrorMessage) { + t.Errorf("Expected error message to contain '%s', but got: %v", expectedErrorMessage, err) + } else { + t.Logf("Failed to reserve IP %d as expected: %v", i+1, err) + } + break + } + if i == 99 { + t.Errorf("Expected to hit reservation limit, but did not reach it after 100 attempts") + } } } From ce34304b759a98de53d6e96614d6f4842a08e9c5 Mon Sep 17 00:00:00 2001 From: ykim-1 Date: Mon, 16 Sep 2024 09:39:20 -0700 Subject: [PATCH 21/43] add cleanup for TestReservedIPAddresses_ExceedLimit --- test/integration/network_reserved_ips_test.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 202e24fd6..8bce013c7 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -301,9 +301,23 @@ func TestReservedIPAddresses_ExceedLimit(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestReservedIPAddresses_ExceedLimit") defer teardown() + // Slice to keep track of all reserved IPs + var reservedIPs []string + + // Helper function to clean up reserved IPs + cleanupIPs := func() { + for _, ip := range reservedIPs { + err := client.DeleteReservedIPAddress(context.Background(), ip) + if err != nil { + t.Errorf("Failed to delete reserved IP %s: %v", ip, err) + } + } + } + defer cleanupIPs() + // Reserve IPs until the limit is reached and assert the error message for i := 0; i < 100; i++ { - _, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ Region: "us-east", }) if err != nil { @@ -315,6 +329,9 @@ func TestReservedIPAddresses_ExceedLimit(t *testing.T) { } break } + + reservedIPs = append(reservedIPs, reservedIP.Address) + if i == 99 { t.Errorf("Expected to hit reservation limit, but did not reach it after 100 attempts") } From 8627e4f2e41e20a748593f0c7ee5e266f652d5c9 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 16 Sep 2024 13:06:28 -0400 Subject: [PATCH 22/43] added interactions to fixture and changed the ecpected error message --- .../TestReservedIPAddresses_ExceedLimit.yaml | 296 ++++++++++++++++++ ...ReservedIPAddresses_ReserveIPVariants.yaml | 254 ++++++++++++++- test/integration/network_reserved_ips_test.go | 2 +- 3 files changed, 548 insertions(+), 4 deletions(-) create mode 100644 test/integration/fixtures/TestReservedIPAddresses_ExceedLimit.yaml diff --git a/test/integration/fixtures/TestReservedIPAddresses_ExceedLimit.yaml b/test/integration/fixtures/TestReservedIPAddresses_ExceedLimit.yaml new file mode 100644 index 000000000..57449d247 --- /dev/null +++ b/test/integration/fixtures/TestReservedIPAddresses_ExceedLimit.yaml @@ -0,0 +1,296 @@ +--- +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": "69.164.208.243", "gateway": "69.164.208.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "69-164-208-243.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: + - Mon, 16 Sep 2024 17:00: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: + - "800" + 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.130.88", "gateway": "45.79.130.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-130-88.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: + - Mon, 16 Sep 2024 17:00: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: + - "800" + 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: '{"errors": [{"reason": "Additional Reserved 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: + - "147" + Content-Type: + - application/json + Expires: + - Mon, 16 Sep 2024 17:00:22 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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/69.164.208.243 + 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: + - Mon, 16 Sep 2024 17:00: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: "" +- 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.130.88 + 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: + - Mon, 16 Sep 2024 17:00:23 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/TestReservedIPAddresses_ReserveIPVariants.yaml b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml index 313e5a87d..2ff00f7a0 100644 --- a/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml +++ b/test/integration/fixtures/TestReservedIPAddresses_ReserveIPVariants.yaml @@ -31,7 +31,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 16 Sep 2024 15:57:36 GMT + - Mon, 16 Sep 2024 17:00:20 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -75,7 +75,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 16 Sep 2024 15:57:36 GMT + - Mon, 16 Sep 2024 17:00:20 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -119,7 +119,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 16 Sep 2024 15:57:36 GMT + - Mon, 16 Sep 2024 17:00:20 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -133,3 +133,251 @@ interactions: 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": "69.164.208.243", "gateway": "69.164.208.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "69-164-208-243.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: + - Mon, 16 Sep 2024 17:00:21 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"}' + 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.130.88", "gateway": "45.79.130.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-130-88.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: + - Mon, 16 Sep 2024 17:00:21 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: "" + 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/69.164.208.243 + 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: + - Mon, 16 Sep 2024 17:00:21 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/45.79.130.88 + 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: + - Mon, 16 Sep 2024 17:00:21 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/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 8bce013c7..a9b8c8b88 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -321,7 +321,7 @@ func TestReservedIPAddresses_ExceedLimit(t *testing.T) { Region: "us-east", }) if err != nil { - expectedErrorMessage := "[500] Could not reserve IP address" + expectedErrorMessage := "[400] Additional Reserved IPv4 addresses require technical justification." if !strings.Contains(err.Error(), expectedErrorMessage) { t.Errorf("Expected error message to contain '%s', but got: %v", expectedErrorMessage, err) } else { From 663e79854a232b3867fe38434ef12d0870c81658 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 16 Sep 2024 17:05:42 -0400 Subject: [PATCH 23/43] Added note indicating feature is currently not available to all users --- network_reserved_ips.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/network_reserved_ips.go b/network_reserved_ips.go index 66d058234..56f343f82 100644 --- a/network_reserved_ips.go +++ b/network_reserved_ips.go @@ -5,11 +5,13 @@ import ( ) // ReserveIPOptions represents the options for reserving an IP address +// NOTE: Reserved IP feature may not currently be available to all users. type ReserveIPOptions struct { Region string `json:"region"` } // ListReservedIPAddresses retrieves a list of reserved IP addresses +// NOTE: Reserved IP feature may not currently be available to all users. func (c *Client) ListReservedIPAddresses(ctx context.Context, opts *ListOptions) ([]InstanceIP, error) { e := formatAPIPath("networking/reserved/ips") response, err := getPaginatedResults[InstanceIP](ctx, c, e, opts) @@ -21,6 +23,7 @@ func (c *Client) ListReservedIPAddresses(ctx context.Context, opts *ListOptions) } // GetReservedIPAddress retrieves details of a specific reserved IP address +// NOTE: Reserved IP feature may not currently be available to all users. func (c *Client) GetReservedIPAddress(ctx context.Context, ipAddress string) (*InstanceIP, error) { e := formatAPIPath("networking/reserved/ips/%s", ipAddress) response, err := doGETRequest[InstanceIP](ctx, c, e) @@ -32,6 +35,7 @@ func (c *Client) GetReservedIPAddress(ctx context.Context, ipAddress string) (*I } // ReserveIPAddress reserves a new IP address +// NOTE: Reserved IP feature may not currently be available to all users. func (c *Client) ReserveIPAddress(ctx context.Context, opts ReserveIPOptions) (*InstanceIP, error) { e := "networking/reserved/ips" response, err := doPOSTRequest[InstanceIP](ctx, c, e, opts) @@ -43,6 +47,7 @@ func (c *Client) ReserveIPAddress(ctx context.Context, opts ReserveIPOptions) (* } // DeleteReservedIPAddress deletes a reserved IP address +// NOTE: Reserved IP feature may not currently be available to all users. func (c *Client) DeleteReservedIPAddress(ctx context.Context, ipAddress string) error { e := formatAPIPath("networking/reserved/ips/%s", ipAddress) return doDELETERequest(ctx, c, e) From 138c1638ffe449e34b7f526b650efe6bf09c7e02 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 3 Sep 2024 15:32:47 -0400 Subject: [PATCH 24/43] added support for creating a linode with reserved IP address along with associated tests --- ...tInstance_CreateWithReservedIPAddress.yaml | 259 ++++++ ...e_CreateWithReservedIPAddressVariants.yaml | 748 ++++++++++++++++++ test/integration/instances_test.go | 162 ++++ 3 files changed, 1169 insertions(+) create mode 100644 test/integration/fixtures/TestInstance_CreateWithReservedIPAddress.yaml create mode 100644 test/integration/fixtures/TestInstance_CreateWithReservedIPAddressVariants.yaml 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/instances_test.go b/test/integration/instances_test.go index ce21abad0..5614e5d9e 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -3,6 +3,7 @@ package integration import ( "context" "encoding/base64" + "fmt" "strconv" "testing" @@ -589,6 +590,167 @@ func TestInstance_withPG(t *testing.T) { require.Equal(t, inst.PlacementGroup.PlacementGroupPolicy, pg.PlacementGroupPolicy) } +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) + } + }() + + instance, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + if err != nil { + t.Fatalf("Error creating instance with reserved IP: %s", err) + } + defer instanceTeardown() + + fmt.Println(instance.IPv4) + +} + +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", // You might want to make this configurable + Type: "g6-nanode-1", + Booted: linodego.Pointer(false), + Image: "linode/alpine3.17", + RootPass: randPassword(), // Consider generating this dynamically + 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) + } else { + fmt.Println("Deleted Linode!") + } + } + + return instance, teardown, nil +} + +func TestInstance_CreateWithReservedIPAddressVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithReservedIPAddressVariants") + 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) + } + }() + + // Test: Owned non-assigned reserved IP + instance, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + if err != nil { + t.Errorf("Unexpected error with owned non-assigned reserved IP: %v", err) + } else { + defer instanceTeardown() + t.Logf("Successfully created instance with owned non-assigned reserved IP: %d", instance.ID) + } + + // Test: Already assigned reserved IP + _, _, err = createInstanceWithReservedIP(t, client, reservedIP.Address) + if err == nil { + t.Errorf("Expected error with already assigned reserved IP, but got none") + } else { + t.Logf("Correctly received error when using already assigned IP: %v", err) + } + + // Test: Non-reserved address + _, _, err = createInstanceWithReservedIP(t, client, "192.0.2.1") + if err == nil { + t.Errorf("Expected error with non-reserved address, but got none") + } else { + t.Logf("Correctly received error when using non-reserved address: %v", err) + } + + // Test: Non-owned reserved address + _, _, err = createInstanceWithReservedIP(t, client, "198.51.100.1") + if err == nil { + t.Errorf("Expected error with non-owned reserved address, but got none") + } else { + t.Logf("Correctly received error when using non-owned reserved address: %v", err) + } + + // Test: Empty IP address + _, _, err = createInstanceWithReservedIP(t, client, "") + if err == nil { + t.Errorf("Expected error with empty IP address, but got none") + } else { + t.Logf("Correctly received error when using empty IP address: %v", err) + } + + // Test: Null IP address + instance, instanceTeardown, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + opts.Ipv4 = nil + }) + if err != nil { + t.Errorf("Unexpected error with null IP address: %v", err) + } else { + defer instanceTeardown() + t.Logf("Successfully created instance with null IP address: %d", instance.ID) + } + + // Test: Multiple IP addresses + _, _, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + opts.Ipv4 = []string{reservedIP.Address, "192.0.2.2"} + }) + if err == nil { + t.Errorf("Expected error with multiple IP addresses, but got none") + } else { + t.Logf("Correctly received error when using multiple IP addresses: %v", err) + } + + // Test: Omit IPv4 field + instance, instanceTeardown, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + opts.Ipv4 = nil + }) + if err != nil { + t.Errorf("Unexpected error when omitting IPv4 field: %v", err) + } else { + defer instanceTeardown() + t.Logf("Successfully created instance without IPv4 field: %d", instance.ID) + } +} + func createInstance(t *testing.T, client *linodego.Client, enableCloudFirewall bool, modifiers ...instanceModifier) (*linodego.Instance, error) { if t != nil { t.Helper() From 4b44bd818ee38f753fe4c41f32097c27b921f959 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 5 Sep 2024 12:39:22 -0400 Subject: [PATCH 25/43] Added support for adding additional reserved IP to linodes along with the corresponding tests and fixtures --- instances.go | 12 + .../TestInstance_AddReservedIPToInstance.yaml | 397 ++++++ ...tance_AddReservedIPToInstanceVariants.yaml | 1109 +++++++++++++++++ test/integration/instances_test.go | 267 +++- 4 files changed, 1783 insertions(+), 2 deletions(-) create mode 100644 test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml create mode 100644 test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml diff --git a/instances.go b/instances.go index 92eb6629a..107fc5a14 100644 --- a/instances.go +++ b/instances.go @@ -166,6 +166,12 @@ type InstanceCreateOptions struct { Group string `json:"group,omitempty"` } +type InstanceReserveAdditionalIPOptions struct { + Type string `json:"type"` + Public bool `json:"public"` + Address string `json:"address"` +} + // InstanceCreatePlacementGroupOptions represents the placement group // to create this Linode under. type InstanceCreatePlacementGroupOptions struct { @@ -437,3 +443,9 @@ func (c *Client) simpleInstanceAction(ctx context.Context, action string, linode ) return err } + +func (c *Client) AddReservedIPToInstance(ctx context.Context, linodeID int, opts InstanceReserveAdditionalIPOptions) error { + endpoint := formatAPIPath("linode/instances/%d/ips", linodeID) + _, err := doPOSTRequest[InstanceReserveAdditionalIPOptions, any](ctx, c, endpoint, opts) + return err +} diff --git a/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml b/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml new file mode 100644 index 000000000..85e750b1a --- /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":"testpassword123"}' + 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": 63470553, "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": ["50.116.59.47"], "ipv6": "2600:3c03::f03c:95ff:fe82:2efe/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": "2de7315a707667a7c71b3d49128ca98acf87f82b", "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: + - "837" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 04 Sep 2024 16:01: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"}' + 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": "104.237.144.216", "gateway": "104.237.144.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "104-237-144-216.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: + - "267" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 04 Sep 2024 16:01:39 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: '{"type":"ipv4","public":true,"address":"104.237.144.216"}' + 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/63470553/ips + method: POST + response: + body: '{"address": "104.237.144.216", "gateway": "104.237.144.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "104-237-144-216.ip.linodeusercontent.com", + "linode_id": 63470553, "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: + - "271" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 04 Sep 2024 16:01: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: + - "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/63470553/ips + method: GET + response: + body: '{"ipv4": {"public": [{"address": "50.116.59.47", "gateway": "50.116.59.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "50-116-59-47.ip.linodeusercontent.com", "linode_id": 63470553, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "104.237.144.216", + "gateway": "104.237.144.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "104-237-144-216.ip.linodeusercontent.com", + "linode_id": 63470553, "region": "us-east", "vpc_nat_1_1": null, "reserved": + true}], "private": [], "shared": [], "reserved": [], "vpc": []}, "ipv6": {"slaac": + {"address": "2600:3c03::f03c:95ff:fe82:2efe", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 63470553, "region": "us-east", "public": true}, "link_local": {"address": "fe80::f03c:95ff:fe82:2efe", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 63470553, "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: + - Wed, 04 Sep 2024 16:01:39 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: + - "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/104.237.144.216 + 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: + - Wed, 04 Sep 2024 16:01:39 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/63470553 + 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: + - Wed, 04 Sep 2024 16:01: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: "" diff --git a/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml b/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml new file mode 100644 index 000000000..3325b64f7 --- /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":"testpassword123"}' + 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": 63516682, "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": ["172.104.5.214"], "ipv6": "2600:3c03::f03c:95ff:fe3d:79a1/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": "c0d068bd9102c6aa9a5fb4f351fb2cd8f363f21b", "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, 05 Sep 2024 16:30:16 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": "66.175.209.108", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-108.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, 05 Sep 2024 16:30: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: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"66.175.209.108"}' + 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/63516682/ips + method: POST + response: + body: '{"address": "66.175.209.108", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-108.ip.linodeusercontent.com", + "linode_id": 63516682, "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: + - "268" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 05 Sep 2024 16:30: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: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":false,"address":"66.175.209.108"}' + 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/63516682/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, 05 Sep 2024 16:30:17 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.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, 05 Sep 2024 16:30: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: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"66.175.209.178"}' + 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, 05 Sep 2024 16:30:17 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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.175.209.178 + 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, 05 Sep 2024 16:30: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: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"66.175.209.108"}' + 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, 05 Sep 2024 16:30:18 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + status: 404 Not Found + code: 404 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"66.175.209.108"}' + 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/63516682/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, 05 Sep 2024 16:30:18 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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/63516682/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, 05 Sep 2024 16:30:18 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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.96.11", "gateway": "172.105.96.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-96-11.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: + - "265" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Thu, 05 Sep 2024 16:30: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: + - "400" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"address":"172.105.96.11"}' + 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/63516682/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, 05 Sep 2024 16:30:18 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv6","public":true,"address":"66.175.209.108"}' + 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/63516682/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, 05 Sep 2024 16:30:18 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"type":"ipv4","public":false,"address":"66.175.209.108"}' + 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/63516682/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, 05 Sep 2024 16:30:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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/63516682/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, 05 Sep 2024 16:30:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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/63516682/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, 05 Sep 2024 16:30:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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/63516682/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, 05 Sep 2024 16:30:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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/63516682/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, 05 Sep 2024 16:30:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "400" + 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.96.11 + 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, 05 Sep 2024 16:30:19 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/66.175.209.108 + 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, 05 Sep 2024 16:30:20 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/63516682 + 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, 05 Sep 2024 16:30:23 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: "" diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index 5614e5d9e..6d0280a4c 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -626,11 +626,11 @@ func createInstanceWithReservedIP( createOpts := linodego.InstanceCreateOptions{ Label: "go-test-ins-reserved-ip-" + randLabel(), - Region: "us-east", // You might want to make this configurable + Region: "us-east", Type: "g6-nanode-1", Booted: linodego.Pointer(false), Image: "linode/alpine3.17", - RootPass: randPassword(), // Consider generating this dynamically + RootPass: randPassword(), Interfaces: []linodego.InstanceConfigInterfaceCreateOptions{ { Purpose: linodego.InterfacePurposePublic, @@ -853,3 +853,266 @@ func setupInstanceWithoutDisks(t *testing.T, fixturesYaml string, enableCloudFir } return client, instance, config, teardown, 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: "testpassword123", + }) + 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.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Public: true, + Address: reservedIP.Address, + } + err = client.AddReservedIPToInstance(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) + } else { + t.Logf("Successfully added reserved IP %s to instance %d", reservedIP.Address, instance.ID) + } +} + +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: "testpassword123", + }) + 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.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Public: true, + Address: reservedIP.Address, + } + err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + if err != nil { + t.Fatalf("Error adding reserved IP to instance: %v", err) + } + t.Logf("Successfully added reserved IP %s to instance %d", reservedIP.Address, instance.ID) + + // Test: Omit public field + omitPublicOpts := linodego.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Address: reservedIP.Address, + // Public field is omitted here + } + err = client.AddReservedIPToInstance(context.Background(), instance.ID, omitPublicOpts) + if err == nil { + t.Fatalf("Expected error when adding reserved IP with omitted public field, but got none") + } else { + t.Logf("Correctly received error when adding reserved IP with omitted public field: %v", err) + } + + // 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) + } else { + t.Logf("Successfully reserved IP: %s", resIP.Address) + } + + // Add IP address to the Linode + err = client.AddReservedIPToInstance(context.Background(), linodeID, linodego.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Public: true, + Address: resIP.Address, + }) + if err != nil { + t.Logf("Correctly received error when adding %s to Linode at IPMax limit: %v", resIP.Address, err) + } + + // 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.AddReservedIPToInstance(context.Background(), nonOwnedInstanceID, opts) + if err == nil { + t.Errorf("Expected error when adding reserved IP to non-owned Linode, but got none") + } + t.Logf("Correctly received error when adding reserved IP to non-owned Linode: %v", err) + + // Test: Already assigned reserved IP + err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + if err == nil { + t.Errorf("Expected error when adding already assigned reserved IP, but got none") + } + t.Logf("Correctly received error when adding already assigned reserved IP: %v", err) + + // Test: Non-owned reserved IP + err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + 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") + } + t.Logf("Correctly received error when adding non-owned reserved IP: %v", err) + + // 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.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + 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") + } + t.Logf("Correctly received error when adding reserved IP in different datacenter: %v", err) + + // Test: IPv6 type + err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + Type: "ipv6", + Public: true, + Address: reservedIP.Address, + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with type ipv6, but got none") + } + t.Logf("Correctly received error when adding reserved IP with type ipv6: %v", err) + + // Test: Public field set to false + opts.Public = false + err = client.AddReservedIPToInstance(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") + } + t.Logf("Correctly received error when adding reserved IP with public field set to false: %v", err) + + // Test: Integer as address + err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + 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") + } + t.Logf("Correctly received error when adding reserved IP with integer as address: %v", err) + + // Test: Empty address + err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Public: true, + Address: "", + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with empty address, but got none") + } + t.Logf("Correctly received error when adding reserved IP with empty address: %v", err) + + // Test: Null address + err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Public: true, + }) + if err == nil { + t.Errorf("Expected error when adding reserved IP with null address, but got none") + } + t.Logf("Correctly received error when adding reserved IP with null address: %v", err) + + // Test: Omit address field + err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + Type: "ipv4", + Public: true, + }) + if err == nil { + t.Errorf("Expected error when omitting address field, but got none") + } + t.Logf("Correctly received error when omitting address field: %v", err) +} From 35610a055f6b80597436e5316065d7bd9954dd47 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 10 Sep 2024 17:56:41 -0400 Subject: [PATCH 26/43] added ipv4 field in the InstanceCreateOptions struct --- instances.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/instances.go b/instances.go index 107fc5a14..da94eb272 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"` } type InstanceReserveAdditionalIPOptions struct { From 809b40710ea5921e60b4695ae9c84688d2e02258 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 12 Sep 2024 15:31:16 -0400 Subject: [PATCH 27/43] moved InstanceReservedIPOptions and the method to AddReservedIPToInsatance to instance_ips.go --- instance_ips.go | 16 ++++++++++++++++ instances.go | 12 ------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/instance_ips.go b/instance_ips.go index 568be05eb..a8d21da57 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) AddReservedIPToInstance(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 da94eb272..d94431acf 100644 --- a/instances.go +++ b/instances.go @@ -168,12 +168,6 @@ type InstanceCreateOptions struct { Ipv4 []string `json:"ipv4,omitempty"` } -type InstanceReserveAdditionalIPOptions struct { - Type string `json:"type"` - Public bool `json:"public"` - Address string `json:"address"` -} - // InstanceCreatePlacementGroupOptions represents the placement group // to create this Linode under. type InstanceCreatePlacementGroupOptions struct { @@ -445,9 +439,3 @@ func (c *Client) simpleInstanceAction(ctx context.Context, action string, linode ) return err } - -func (c *Client) AddReservedIPToInstance(ctx context.Context, linodeID int, opts InstanceReserveAdditionalIPOptions) error { - endpoint := formatAPIPath("linode/instances/%d/ips", linodeID) - _, err := doPOSTRequest[InstanceReserveAdditionalIPOptions, any](ctx, c, endpoint, opts) - return err -} From b559ee8d718fbdb4209f9eddc8fa76e9734ba36d Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 12 Sep 2024 15:58:30 -0400 Subject: [PATCH 28/43] Split the variants tests of createInstanceWithReservedIP into individual test funcitons and removed debugging log statements --- test/integration/instances_test.go | 169 ++++++++++++++++------------- 1 file changed, 95 insertions(+), 74 deletions(-) diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index 6d0280a4c..fd135bd35 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -3,7 +3,6 @@ package integration import ( "context" "encoding/base64" - "fmt" "strconv" "testing" @@ -606,14 +605,12 @@ func TestInstance_CreateWithReservedIPAddress(t *testing.T) { } }() - instance, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) if err != nil { t.Fatalf("Error creating instance with reserved IP: %s", err) } defer instanceTeardown() - fmt.Println(instance.IPv4) - } func createInstanceWithReservedIP( @@ -653,19 +650,16 @@ func createInstanceWithReservedIP( teardown := func() { if terr := client.DeleteInstance(context.Background(), instance.ID); terr != nil { t.Errorf("Error deleting test Instance: %s", terr) - } else { - fmt.Println("Deleted Linode!") } } return instance, teardown, nil } -func TestInstance_CreateWithReservedIPAddressVariants(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithReservedIPAddressVariants") +func TestInstance_CreateWithOwnedNonAssignedReservedIP(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithOwnedNonAssignedReservedIP") 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) @@ -677,77 +671,121 @@ func TestInstance_CreateWithReservedIPAddressVariants(t *testing.T) { } }() - // Test: Owned non-assigned reserved IP - instance, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) if err != nil { t.Errorf("Unexpected error with owned non-assigned reserved IP: %v", err) } else { defer instanceTeardown() - t.Logf("Successfully created instance with owned non-assigned reserved IP: %d", instance.ID) } +} - // Test: Already assigned reserved IP +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) + if err != nil { + t.Fatalf("Failed to create initial instance: %v", err) + } + defer instanceTeardown() + + // Now try to create another instance with the same IP _, _, err = createInstanceWithReservedIP(t, client, reservedIP.Address) if err == nil { t.Errorf("Expected error with already assigned reserved IP, but got none") - } else { - t.Logf("Correctly received error when using already assigned IP: %v", err) } +} - // Test: Non-reserved address - _, _, err = createInstanceWithReservedIP(t, client, "192.0.2.1") +func TestInstance_CreateWithNonReservedAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonReservedAddress") + defer teardown() + + _, _, err := createInstanceWithReservedIP(t, client, "192.0.2.1") if err == nil { t.Errorf("Expected error with non-reserved address, but got none") - } else { - t.Logf("Correctly received error when using non-reserved address: %v", err) } +} - // Test: Non-owned reserved address - _, _, err = createInstanceWithReservedIP(t, client, "198.51.100.1") +func TestInstance_CreateWithNonOwnedReservedAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonOwnedReservedAddress") + defer teardown() + + _, _, err := createInstanceWithReservedIP(t, client, "198.51.100.1") if err == nil { t.Errorf("Expected error with non-owned reserved address, but got none") - } else { - t.Logf("Correctly received error when using non-owned reserved address: %v", err) } +} - // Test: Empty IP address - _, _, err = createInstanceWithReservedIP(t, client, "") +func TestInstance_CreateWithEmptyIPAddress(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithEmptyIPAddress") + defer teardown() + + _, _, err := createInstanceWithReservedIP(t, client, "") if err == nil { t.Errorf("Expected error with empty IP address, but got none") - } else { - t.Logf("Correctly received error when using empty IP address: %v", err) } +} - // Test: Null IP address - instance, instanceTeardown, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { +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 }) if err != nil { t.Errorf("Unexpected error with null IP address: %v", err) } else { defer instanceTeardown() - t.Logf("Successfully created instance with null IP address: %d", instance.ID) } +} + +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) + } + }() - // Test: Multiple IP addresses _, _, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { opts.Ipv4 = []string{reservedIP.Address, "192.0.2.2"} }) if err == nil { t.Errorf("Expected error with multiple IP addresses, but got none") - } else { - t.Logf("Correctly received error when using multiple IP addresses: %v", err) } +} + +func TestInstance_CreateWithoutIPv4Field(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithoutIPv4Field") + defer teardown() - // Test: Omit IPv4 field - instance, instanceTeardown, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { opts.Ipv4 = nil }) if err != nil { t.Errorf("Unexpected error when omitting IPv4 field: %v", err) } else { defer instanceTeardown() - t.Logf("Successfully created instance without IPv4 field: %d", instance.ID) } } @@ -863,7 +901,7 @@ func TestInstance_AddReservedIPToInstance(t *testing.T) { Region: "us-east", Type: "g6-nanode-1", Label: "test-instance-for-ip-reservation", - RootPass: "testpassword123", + RootPass: randPassword(), }) if err != nil { t.Fatalf("Error creating test instance: %v", err) @@ -888,12 +926,12 @@ func TestInstance_AddReservedIPToInstance(t *testing.T) { }() // Add the reserved IP to the instance - opts := linodego.InstanceReserveAdditionalIPOptions{ + opts := linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: reservedIP.Address, } - err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) if err != nil { t.Fatalf("Error adding reserved IP to instance: %v", err) } @@ -914,8 +952,6 @@ func TestInstance_AddReservedIPToInstance(t *testing.T) { if !found { t.Errorf("Reserved IP %s was not found in instance's IP addresses", reservedIP.Address) - } else { - t.Logf("Successfully added reserved IP %s to instance %d", reservedIP.Address, instance.ID) } } @@ -928,7 +964,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { Region: "us-east", Type: "g6-nanode-1", Label: "test-instance-for-ip-reservation", - RootPass: "testpassword123", + RootPass: randPassword(), }) if err != nil { t.Fatalf("Error creating test instance: %v", err) @@ -953,28 +989,25 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { }() // Test: Add reserved IP to instance with valid parameters - opts := linodego.InstanceReserveAdditionalIPOptions{ + opts := linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: reservedIP.Address, } - err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) if err != nil { t.Fatalf("Error adding reserved IP to instance: %v", err) } - t.Logf("Successfully added reserved IP %s to instance %d", reservedIP.Address, instance.ID) // Test: Omit public field - omitPublicOpts := linodego.InstanceReserveAdditionalIPOptions{ + omitPublicOpts := linodego.InstanceReserveIPOptions{ Type: "ipv4", Address: reservedIP.Address, // Public field is omitted here } - err = client.AddReservedIPToInstance(context.Background(), instance.ID, omitPublicOpts) + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, omitPublicOpts) if err == nil { t.Fatalf("Expected error when adding reserved IP with omitted public field, but got none") - } else { - t.Logf("Correctly received error when adding reserved IP with omitted public field: %v", err) } // Assume we have a Linode that has been created without a reserved IP address and IPMAX set to 1 @@ -986,18 +1019,16 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { }) if err != nil { t.Fatalf("Failed to reserve IP: %v", err) - } else { - t.Logf("Successfully reserved IP: %s", resIP.Address) } // Add IP address to the Linode - err = client.AddReservedIPToInstance(context.Background(), linodeID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), linodeID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: resIP.Address, }) - if err != nil { - t.Logf("Correctly received error when adding %s to Linode at IPMax limit: %v", resIP.Address, err) + 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 @@ -1008,21 +1039,19 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { // Test: Non-owned Linode ID nonOwnedInstanceID := 888888 // Replace with an actual non-owned Linode ID - err = client.AddReservedIPToInstance(context.Background(), nonOwnedInstanceID, opts) + _, err = client.AddReservedIPToInstance(context.Background(), nonOwnedInstanceID, opts) if err == nil { t.Errorf("Expected error when adding reserved IP to non-owned Linode, but got none") } - t.Logf("Correctly received error when adding reserved IP to non-owned Linode: %v", err) // Test: Already assigned reserved IP - err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) if err == nil { t.Errorf("Expected error when adding already assigned reserved IP, but got none") } - t.Logf("Correctly received error when adding already assigned reserved IP: %v", err) // Test: Non-owned reserved IP - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: "198.51.100.1", // Assume this is a non-owned reserved IP @@ -1030,7 +1059,6 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { if err == nil { t.Errorf("Expected error when adding non-owned reserved IP, but got none") } - t.Logf("Correctly received error when adding non-owned reserved IP: %v", err) // Test: Reserved IP in different datacenter // Reserve an IP address @@ -1045,7 +1073,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { t.Errorf("Error deleting reserved IP: %v", err) } }() - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: diffDataCentreIP.Address, // Assume this IP is in a different datacenter @@ -1053,10 +1081,9 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { if err == nil { t.Errorf("Expected error when adding reserved IP in different datacenter, but got none") } - t.Logf("Correctly received error when adding reserved IP in different datacenter: %v", err) // Test: IPv6 type - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv6", Public: true, Address: reservedIP.Address, @@ -1064,18 +1091,16 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { if err == nil { t.Errorf("Expected error when adding reserved IP with type ipv6, but got none") } - t.Logf("Correctly received error when adding reserved IP with type ipv6: %v", err) // Test: Public field set to false opts.Public = false - err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, err = client.AddReservedIPToInstance(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") } - t.Logf("Correctly received error when adding reserved IP with public field set to false: %v", err) // Test: Integer as address - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: "12345", // Invalid IP format @@ -1083,10 +1108,9 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { if err == nil { t.Errorf("Expected error when adding reserved IP with integer as address, but got none") } - t.Logf("Correctly received error when adding reserved IP with integer as address: %v", err) // Test: Empty address - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: "", @@ -1094,25 +1118,22 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { if err == nil { t.Errorf("Expected error when adding reserved IP with empty address, but got none") } - t.Logf("Correctly received error when adding reserved IP with empty address: %v", err) // Test: Null address - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(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") } - t.Logf("Correctly received error when adding reserved IP with null address: %v", err) // Test: Omit address field - err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveAdditionalIPOptions{ + _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, }) if err == nil { t.Errorf("Expected error when omitting address field, but got none") } - t.Logf("Correctly received error when omitting address field: %v", err) } From 402c77ad48435519d6bd9d38e4abbb4e4ef09903 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 12 Sep 2024 16:02:56 -0400 Subject: [PATCH 29/43] Re-recorded fixtures after splitting variants test into individual test functions, made changes to error messages --- .../TestInstance_AddReservedIPToInstance.yaml | 78 ++--- ...tance_AddReservedIPToInstanceVariants.yaml | 156 ++++----- ...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 +++++++++++++++ .../TestInstance_CreateWithoutIPv4Field.yaml | 134 ++++++++ 10 files changed, 1526 insertions(+), 117 deletions(-) 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_CreateWithoutIPv4Field.yaml diff --git a/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml b/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml index 85e750b1a..8ff4312cc 100644 --- a/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml +++ b/test/integration/fixtures/TestInstance_AddReservedIPToInstance.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"region":"us-east","type":"g6-nanode-1","label":"test-instance-for-ip-reservation","root_pass":"testpassword123"}' + 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: @@ -14,17 +14,17 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 63470553, "label": "test-instance-for-ip-reservation", "group": + 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": ["50.116.59.47"], "ipv6": "2600:3c03::f03c:95ff:fe82:2efe/128", + "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": "2de7315a707667a7c71b3d49128ca98acf87f82b", "has_user_data": + true, "tags": [], "host_uuid": "aab21dc7e975cd72af77bb1dee30b501acd7d3b9", "has_user_data": false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": - null}' + null, "capabilities": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -43,13 +43,13 @@ interactions: Connection: - keep-alive Content-Length: - - "837" + - "858" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 04 Sep 2024 16:01:38 GMT + - Thu, 12 Sep 2024 19:53:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -85,8 +85,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "104.237.144.216", "gateway": "104.237.144.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "104-237-144-216.ip.linodeusercontent.com", + 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: @@ -106,13 +106,13 @@ interactions: Connection: - keep-alive Content-Length: - - "267" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 04 Sep 2024 16:01:39 GMT + - Thu, 12 Sep 2024 19:53:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -129,14 +129,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"type":"ipv4","public":true,"address":"104.237.144.216"}' + body: '{"type":"ipv4","public":true,"address":"45.79.150.200"}' form: {} headers: Accept: @@ -145,12 +145,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63470553/ips + url: https://api.linode.com/v4beta/linode/instances/63837282/ips method: POST response: - body: '{"address": "104.237.144.216", "gateway": "104.237.144.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "104-237-144-216.ip.linodeusercontent.com", - "linode_id": 63470553, "region": "us-east", "vpc_nat_1_1": null, "reserved": + 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: @@ -170,13 +170,13 @@ interactions: Connection: - keep-alive Content-Length: - - "271" + - "265" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 04 Sep 2024 16:01:39 GMT + - Thu, 12 Sep 2024 19:53:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -193,7 +193,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -209,22 +209,22 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63470553/ips + url: https://api.linode.com/v4beta/linode/instances/63837282/ips method: GET response: - body: '{"ipv4": {"public": [{"address": "50.116.59.47", "gateway": "50.116.59.1", + 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": "50-116-59-47.ip.linodeusercontent.com", "linode_id": 63470553, "region": - "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "104.237.144.216", - "gateway": "104.237.144.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": - "ipv4", "public": true, "rdns": "104-237-144-216.ip.linodeusercontent.com", - "linode_id": 63470553, "region": "us-east", "vpc_nat_1_1": null, "reserved": - true}], "private": [], "shared": [], "reserved": [], "vpc": []}, "ipv6": {"slaac": - {"address": "2600:3c03::f03c:95ff:fe82:2efe", "gateway": "fe80::1", "subnet_mask": - "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 63470553, "region": "us-east", "public": true}, "link_local": {"address": "fe80::f03c:95ff:fe82:2efe", + "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": 63470553, "region": "us-east", "public": + "type": "ipv6", "rdns": null, "linode_id": 63837282, "region": "us-east", "public": false}, "global": []}}' headers: Access-Control-Allow-Credentials: @@ -248,7 +248,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Sep 2024 16:01:39 GMT + - Thu, 12 Sep 2024 19:53:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -267,7 +267,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -283,7 +283,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/104.237.144.216 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.150.200 method: DELETE response: body: '{}' @@ -311,7 +311,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Sep 2024 16:01:39 GMT + - Thu, 12 Sep 2024 19:53:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -344,7 +344,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63470553 + url: https://api.linode.com/v4beta/linode/instances/63837282 method: DELETE response: body: '{}' @@ -372,7 +372,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Sep 2024 16:01:41 GMT + - Thu, 12 Sep 2024 19:53:10 GMT Pragma: - no-cache Strict-Transport-Security: @@ -389,7 +389,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml b/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml index 3325b64f7..6239225d6 100644 --- a/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml +++ b/test/integration/fixtures/TestInstance_AddReservedIPToInstanceVariants.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"region":"us-east","type":"g6-nanode-1","label":"test-instance-for-ip-reservation","root_pass":"testpassword123"}' + 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: @@ -14,15 +14,15 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 63516682, "label": "test-instance-for-ip-reservation", "group": + 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": ["172.104.5.214"], "ipv6": "2600:3c03::f03c:95ff:fe3d:79a1/128", + "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": "c0d068bd9102c6aa9a5fb4f351fb2cd8f363f21b", "has_user_data": + true, "tags": [], "host_uuid": "aab21dc7e975cd72af77bb1dee30b501acd7d3b9", "has_user_data": false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": null, "capabilities": []}' headers: @@ -49,7 +49,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:16 GMT + - Thu, 12 Sep 2024 19:48:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -85,8 +85,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "66.175.209.108", "gateway": "66.175.209.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-108.ip.linodeusercontent.com", + 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: @@ -106,13 +106,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "258" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:17 GMT + - Thu, 12 Sep 2024 19:48:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -129,14 +129,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"type":"ipv4","public":true,"address":"66.175.209.108"}' + body: '{"type":"ipv4","public":true,"address":"23.92.21.220"}' form: {} headers: Accept: @@ -145,12 +145,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: - body: '{"address": "66.175.209.108", "gateway": "66.175.209.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-108.ip.linodeusercontent.com", - "linode_id": 63516682, "region": "us-east", "vpc_nat_1_1": null, "reserved": + 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: @@ -170,13 +170,13 @@ interactions: Connection: - keep-alive Content-Length: - - "268" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:17 GMT + - Thu, 12 Sep 2024 19:48:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -193,14 +193,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"type":"ipv4","public":false,"address":"66.175.209.108"}' + body: '{"type":"ipv4","public":false,"address":"23.92.21.220"}' form: {} headers: Accept: @@ -209,7 +209,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Cannot reserve a private address.", "field": "address"}]}' @@ -229,7 +229,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:17 GMT + - Thu, 12 Sep 2024 19:48:41 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -239,7 +239,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -256,8 +256,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "66.175.209.178", "gateway": "66.175.209.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-209-178.ip.linodeusercontent.com", + 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: @@ -277,13 +277,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:17 GMT + - Thu, 12 Sep 2024 19:48:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -300,14 +300,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"type":"ipv4","public":true,"address":"66.175.209.178"}' + body: '{"type":"ipv4","public":true,"address":"45.79.150.200"}' form: {} headers: Accept: @@ -337,7 +337,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:17 GMT + - Thu, 12 Sep 2024 19:48:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -347,7 +347,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -361,7 +361,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.178 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.150.200 method: DELETE response: body: '{}' @@ -389,7 +389,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -413,7 +413,7 @@ interactions: code: 200 duration: "" - request: - body: '{"type":"ipv4","public":true,"address":"66.175.209.108"}' + body: '{"type":"ipv4","public":true,"address":"23.92.21.220"}' form: {} headers: Accept: @@ -442,7 +442,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -452,12 +452,12 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 404 Not Found code: 404 duration: "" - request: - body: '{"type":"ipv4","public":true,"address":"66.175.209.108"}' + body: '{"type":"ipv4","public":true,"address":"23.92.21.220"}' form: {} headers: Accept: @@ -466,7 +466,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Address must be currently unassigned.", "field": @@ -487,7 +487,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -497,7 +497,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -511,7 +511,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Address must be reserved and must be currently @@ -532,7 +532,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -542,7 +542,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -559,8 +559,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.96.11", "gateway": "172.105.96.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-96-11.ip.linodeusercontent.com", + 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: @@ -581,13 +581,13 @@ interactions: Connection: - keep-alive Content-Length: - - "265" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:43 GMT Pragma: - no-cache Strict-Transport-Security: @@ -604,14 +604,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"type":"ipv4","public":true,"address":"172.105.96.11"}' + body: '{"type":"ipv4","public":true,"address":"172.105.0.89"}' form: {} headers: Accept: @@ -620,7 +620,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Address must belong to same region as linode.", @@ -641,7 +641,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -651,12 +651,12 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" - request: - body: '{"type":"ipv6","public":true,"address":"66.175.209.108"}' + body: '{"type":"ipv6","public":true,"address":"23.92.21.220"}' form: {} headers: Accept: @@ -665,7 +665,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Only addresses of type ipv4 are currently supported."}, @@ -686,7 +686,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:18 GMT + - Thu, 12 Sep 2024 19:48:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -696,12 +696,12 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" - request: - body: '{"type":"ipv4","public":false,"address":"66.175.209.108"}' + body: '{"type":"ipv4","public":false,"address":"23.92.21.220"}' form: {} headers: Accept: @@ -710,7 +710,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Cannot reserve a private address.", "field": "address"}]}' @@ -730,7 +730,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:19 GMT + - Thu, 12 Sep 2024 19:48:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -740,7 +740,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -754,7 +754,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": @@ -775,7 +775,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:19 GMT + - Thu, 12 Sep 2024 19:48:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -785,7 +785,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -799,7 +799,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": @@ -820,7 +820,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:19 GMT + - Thu, 12 Sep 2024 19:48:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -830,7 +830,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -844,7 +844,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": @@ -865,7 +865,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:19 GMT + - Thu, 12 Sep 2024 19:48:44 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -875,7 +875,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -889,7 +889,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682/ips + url: https://api.linode.com/v4beta/linode/instances/63837167/ips method: POST response: body: '{"errors": [{"reason": "Must provide a valid reserved address", "field": @@ -910,7 +910,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:19 GMT + - Thu, 12 Sep 2024 19:48:44 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -920,7 +920,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" status: 400 Bad Request code: 400 duration: "" @@ -934,7 +934,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.96.11 + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.0.89 method: DELETE response: body: '{}' @@ -962,7 +962,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:19 GMT + - Thu, 12 Sep 2024 19:48:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -995,7 +995,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/66.175.209.108 + url: https://api.linode.com/v4beta/networking/reserved/ips/23.92.21.220 method: DELETE response: body: '{}' @@ -1023,7 +1023,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:20 GMT + - Thu, 12 Sep 2024 19:48:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1056,7 +1056,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/63516682 + url: https://api.linode.com/v4beta/linode/instances/63837167 method: DELETE response: body: '{}' @@ -1084,7 +1084,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 05 Sep 2024 16:30:23 GMT + - Thu, 12 Sep 2024 19:48:46 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1101,7 +1101,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK 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_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: "" From 30eeda7bd62d9ee1abde5855255f7450c8e641bc Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Fri, 13 Sep 2024 12:17:08 -0400 Subject: [PATCH 30/43] added teardown funcitnality to handle accidental instance creations --- test/integration/instances_test.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index fd135bd35..d09894eb7 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -702,9 +702,10 @@ func TestInstance_CreateWithAlreadyAssignedReservedIP(t *testing.T) { defer instanceTeardown() // Now try to create another instance with the same IP - _, _, err = createInstanceWithReservedIP(t, client, reservedIP.Address) + _, secondInstanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) if err == nil { t.Errorf("Expected error with already assigned reserved IP, but got none") + defer secondInstanceTeardown() } } @@ -712,9 +713,10 @@ func TestInstance_CreateWithNonReservedAddress(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonReservedAddress") defer teardown() - _, _, err := createInstanceWithReservedIP(t, client, "192.0.2.1") + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "192.0.2.1") if err == nil { t.Errorf("Expected error with non-reserved address, but got none") + defer instanceTeardown() } } @@ -722,9 +724,10 @@ func TestInstance_CreateWithNonOwnedReservedAddress(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonOwnedReservedAddress") defer teardown() - _, _, err := createInstanceWithReservedIP(t, client, "198.51.100.1") + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "198.51.100.1") if err == nil { t.Errorf("Expected error with non-owned reserved address, but got none") + defer instanceTeardown() } } @@ -732,9 +735,10 @@ func TestInstance_CreateWithEmptyIPAddress(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithEmptyIPAddress") defer teardown() - _, _, err := createInstanceWithReservedIP(t, client, "") + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "") if err == nil { t.Errorf("Expected error with empty IP address, but got none") + defer instanceTeardown() } } @@ -767,11 +771,12 @@ func TestInstance_CreateWithMultipleIPAddresses(t *testing.T) { } }() - _, _, err = createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { + _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { opts.Ipv4 = []string{reservedIP.Address, "192.0.2.2"} }) if err == nil { t.Errorf("Expected error with multiple IP addresses, but got none") + defer instanceTeardown() } } From 8909bd6e661ee619fe5e6b437323003fd4d50e70 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Fri, 13 Sep 2024 12:56:55 -0400 Subject: [PATCH 31/43] removed unnecessary defer keyword from test functions --- test/integration/instances_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index d09894eb7..d5c992642 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -675,7 +675,7 @@ func TestInstance_CreateWithOwnedNonAssignedReservedIP(t *testing.T) { if err != nil { t.Errorf("Unexpected error with owned non-assigned reserved IP: %v", err) } else { - defer instanceTeardown() + instanceTeardown() } } @@ -705,7 +705,7 @@ func TestInstance_CreateWithAlreadyAssignedReservedIP(t *testing.T) { _, secondInstanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) if err == nil { t.Errorf("Expected error with already assigned reserved IP, but got none") - defer secondInstanceTeardown() + secondInstanceTeardown() } } @@ -716,7 +716,7 @@ func TestInstance_CreateWithNonReservedAddress(t *testing.T) { _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "192.0.2.1") if err == nil { t.Errorf("Expected error with non-reserved address, but got none") - defer instanceTeardown() + instanceTeardown() } } @@ -727,7 +727,7 @@ func TestInstance_CreateWithNonOwnedReservedAddress(t *testing.T) { _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "198.51.100.1") if err == nil { t.Errorf("Expected error with non-owned reserved address, but got none") - defer instanceTeardown() + instanceTeardown() } } @@ -738,7 +738,7 @@ func TestInstance_CreateWithEmptyIPAddress(t *testing.T) { _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "") if err == nil { t.Errorf("Expected error with empty IP address, but got none") - defer instanceTeardown() + instanceTeardown() } } @@ -752,7 +752,7 @@ func TestInstance_CreateWithNullIPAddress(t *testing.T) { if err != nil { t.Errorf("Unexpected error with null IP address: %v", err) } else { - defer instanceTeardown() + instanceTeardown() } } @@ -776,7 +776,7 @@ func TestInstance_CreateWithMultipleIPAddresses(t *testing.T) { }) if err == nil { t.Errorf("Expected error with multiple IP addresses, but got none") - defer instanceTeardown() + instanceTeardown() } } @@ -790,7 +790,7 @@ func TestInstance_CreateWithoutIPv4Field(t *testing.T) { if err != nil { t.Errorf("Unexpected error when omitting IPv4 field: %v", err) } else { - defer instanceTeardown() + instanceTeardown() } } From 9b1590920a626c4fe3f64fdb1c54a943d3562155 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 17 Sep 2024 16:01:11 -0400 Subject: [PATCH 32/43] moved tests related to creating a linode with reserved IP and adding additonal reserved IPs to a linode to a separate file --- test/Makefile | 2 +- .../integration/instance_reserved_ips_test.go | 456 ++++++++++++++++++ test/integration/instances_test.go | 451 ----------------- 3 files changed, 457 insertions(+), 452 deletions(-) create mode 100644 test/integration/instance_reserved_ips_test.go diff --git a/test/Makefile b/test/Makefile index 2c1832fdb..a7d0d67eb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ testint: @LINODE_FIXTURE_MODE="play" \ - LINODE_TOKEN="awesometokenawesometokenawesometoken" \ + LINODE_TOKEN="9f08d4534157252421c964c7b9bf53dd545a242c1f7ef4fe1ada1701366acf7f" \ LINODE_API_VERSION="v4beta" \ GO111MODULE="on" \ go test -v ./integration $(ARGS) diff --git a/test/integration/instance_reserved_ips_test.go b/test/integration/instance_reserved_ips_test.go new file mode 100644 index 000000000..03a483458 --- /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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: true, + }) + if err == nil { + t.Errorf("Expected error when omitting address field, but got none") + } +} diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index d5c992642..ce21abad0 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -589,211 +589,6 @@ func TestInstance_withPG(t *testing.T) { require.Equal(t, inst.PlacementGroup.PlacementGroupPolicy, pg.PlacementGroupPolicy) } -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) - if err != nil { - t.Fatalf("Error creating instance with reserved IP: %s", err) - } - defer instanceTeardown() - -} - -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) - if err != nil { - t.Errorf("Unexpected error with owned non-assigned reserved IP: %v", err) - } else { - instanceTeardown() - } -} - -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) - if err != nil { - t.Fatalf("Failed to create initial instance: %v", err) - } - defer instanceTeardown() - - // Now try to create another instance with the same IP - _, secondInstanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) - if err == nil { - t.Errorf("Expected error with already assigned reserved IP, but got none") - secondInstanceTeardown() - } -} - -func TestInstance_CreateWithNonReservedAddress(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonReservedAddress") - defer teardown() - - _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "192.0.2.1") - if err == nil { - t.Errorf("Expected error with non-reserved address, but got none") - instanceTeardown() - } -} - -func TestInstance_CreateWithNonOwnedReservedAddress(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithNonOwnedReservedAddress") - defer teardown() - - _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "198.51.100.1") - if err == nil { - t.Errorf("Expected error with non-owned reserved address, but got none") - instanceTeardown() - } -} - -func TestInstance_CreateWithEmptyIPAddress(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestInstance_CreateWithEmptyIPAddress") - defer teardown() - - _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "") - if err == nil { - t.Errorf("Expected error with empty IP address, but got none") - instanceTeardown() - } -} - -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 - }) - if err != nil { - t.Errorf("Unexpected error with null IP address: %v", err) - } else { - instanceTeardown() - } -} - -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"} - }) - if err == nil { - t.Errorf("Expected error with multiple IP addresses, but got none") - instanceTeardown() - } -} - -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 - }) - if err != nil { - t.Errorf("Unexpected error when omitting IPv4 field: %v", err) - } else { - instanceTeardown() - } -} - func createInstance(t *testing.T, client *linodego.Client, enableCloudFirewall bool, modifiers ...instanceModifier) (*linodego.Instance, error) { if t != nil { t.Helper() @@ -896,249 +691,3 @@ func setupInstanceWithoutDisks(t *testing.T, fixturesYaml string, enableCloudFir } return client, instance, config, teardown, 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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(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.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ - Type: "ipv4", - Public: true, - }) - if err == nil { - t.Errorf("Expected error when omitting address field, but got none") - } -} From 97ccd6b0a37dbde39e488091b7d762c889736717 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 17 Sep 2024 16:18:44 -0400 Subject: [PATCH 33/43] Removing the sensitive token from the previous commit --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index a7d0d67eb..2c1832fdb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ testint: @LINODE_FIXTURE_MODE="play" \ - LINODE_TOKEN="9f08d4534157252421c964c7b9bf53dd545a242c1f7ef4fe1ada1701366acf7f" \ + LINODE_TOKEN="awesometokenawesometokenawesometoken" \ LINODE_API_VERSION="v4beta" \ GO111MODULE="on" \ go test -v ./integration $(ARGS) From 290752930db333356a7a65c6836305bbe8e150ef Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 24 Sep 2024 16:03:43 -0400 Subject: [PATCH 34/43] made changes to maintain consistency and improve readability --- instance_ips.go | 2 +- instances.go | 2 +- .../integration/instance_reserved_ips_test.go | 36 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/instance_ips.go b/instance_ips.go index a8d21da57..7a5ad62c6 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -152,7 +152,7 @@ func (c *Client) DeleteInstanceIPAddress(ctx context.Context, linodeID int, ipAd } // Function to add additional reserved IPV4 addresses to an existing linode -func (c *Client) AddReservedIPToInstance(ctx context.Context, linodeID int, opts InstanceReserveIPOptions) (*InstanceIP, error) { +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 { diff --git a/instances.go b/instances.go index d94431acf..31876598f 100644 --- a/instances.go +++ b/instances.go @@ -165,7 +165,7 @@ 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"` + IPv4 []string `json:"ipv4,omitempty"` } // InstanceCreatePlacementGroupOptions represents the placement group diff --git a/test/integration/instance_reserved_ips_test.go b/test/integration/instance_reserved_ips_test.go index 03a483458..e1f55af61 100644 --- a/test/integration/instance_reserved_ips_test.go +++ b/test/integration/instance_reserved_ips_test.go @@ -53,7 +53,7 @@ func createInstanceWithReservedIP( IPAMAddress: "", }, }, - Ipv4: []string{reservedIP}, + IPv4: []string{reservedIP}, } for _, modifier := range modifiers { @@ -164,7 +164,7 @@ func TestInstance_CreateWithNullIPAddress(t *testing.T) { defer teardown() _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { - opts.Ipv4 = nil + opts.IPv4 = nil }) defer instanceTeardown() if err != nil { @@ -188,7 +188,7 @@ func TestInstance_CreateWithMultipleIPAddresses(t *testing.T) { }() _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { - opts.Ipv4 = []string{reservedIP.Address, "192.0.2.2"} + opts.IPv4 = []string{reservedIP.Address, "192.0.2.2"} }) defer instanceTeardown() if err == nil { @@ -201,7 +201,7 @@ func TestInstance_CreateWithoutIPv4Field(t *testing.T) { defer teardown() _, instanceTeardown, err := createInstanceWithReservedIP(t, client, "", func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { - opts.Ipv4 = nil + opts.IPv4 = nil }) defer instanceTeardown() if err != nil { @@ -248,7 +248,7 @@ func TestInstance_AddReservedIPToInstance(t *testing.T) { Public: true, Address: reservedIP.Address, } - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, opts) if err != nil { t.Fatalf("Error adding reserved IP to instance: %v", err) } @@ -311,7 +311,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { Public: true, Address: reservedIP.Address, } - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, opts) if err != nil { t.Fatalf("Error adding reserved IP to instance: %v", err) } @@ -322,7 +322,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { Address: reservedIP.Address, // Public field is omitted here } - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, omitPublicOpts) + _, 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") } @@ -339,7 +339,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { } // Add IP address to the Linode - _, err = client.AddReservedIPToInstance(context.Background(), linodeID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), linodeID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: resIP.Address, @@ -356,19 +356,19 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { // Test: Non-owned Linode ID nonOwnedInstanceID := 888888 // Replace with an actual non-owned Linode ID - _, err = client.AddReservedIPToInstance(context.Background(), nonOwnedInstanceID, opts) + _, 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.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, 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.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, 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 @@ -390,7 +390,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { t.Errorf("Error deleting reserved IP: %v", err) } }() - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: diffDataCentreIP.Address, // Assume this IP is in a different datacenter @@ -400,7 +400,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { } // Test: IPv6 type - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv6", Public: true, Address: reservedIP.Address, @@ -411,13 +411,13 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { // Test: Public field set to false opts.Public = false - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, opts) + _, 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.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: "12345", // Invalid IP format @@ -427,7 +427,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { } // Test: Empty address - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, Address: "", @@ -437,7 +437,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { } // Test: Null address - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, }) @@ -446,7 +446,7 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { } // Test: Omit address field - _, err = client.AddReservedIPToInstance(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ + _, err = client.AssignInstanceReservedIP(context.Background(), instance.ID, linodego.InstanceReserveIPOptions{ Type: "ipv4", Public: true, }) From 39323ef4762f27b5bce769ed67bb105ca0ff5344 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 30 Sep 2024 13:00:28 -0400 Subject: [PATCH 35/43] added tests for deletion of linode created with reserved IP address --- .../TestInstance_DeleteInstanceVariants.yaml | 651 ++++++++++++++++++ .../integration/instance_reserved_ips_test.go | 87 +++ 2 files changed, 738 insertions(+) create mode 100644 test/integration/fixtures/TestInstance_DeleteInstanceVariants.yaml diff --git a/test/integration/fixtures/TestInstance_DeleteInstanceVariants.yaml b/test/integration/fixtures/TestInstance_DeleteInstanceVariants.yaml new file mode 100644 index 000000000..479ad6177 --- /dev/null +++ b/test/integration/fixtures/TestInstance_DeleteInstanceVariants.yaml @@ -0,0 +1,651 @@ +--- +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": "69.164.211.224", "gateway": "69.164.211.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "69-164-211-224.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: + - Mon, 30 Sep 2024 16:52:04 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-c1t2pb490c1p","root_pass":"TxEZAoyb0\u003eH7P\\[l0L\u003ccr?9y[UD5u\u003eH(Rv6v}A0u]9L1j0w0:4|E$6^]39M[K4yx","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["69.164.211.224"]}' + 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": 64649882, "label": "go-test-ins-reserved-ip-c1t2pb490c1p", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["69.164.211.224"], "ipv6": "2600:3c03::f03c:95ff:feb1:d75c/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": "091414d3185b27660e1fe9157da7bcc48d9f51cd", "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: + - Mon, 30 Sep 2024 16:52:06 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/64649882 + 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: + - Mon, 30 Sep 2024 16:52: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/networking/reserved/ips/69.164.211.224 + method: GET + response: + body: '{"address": "69.164.211.224", "gateway": "69.164.211.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "69-164-211-224.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: + - Mon, 30 Sep 2024 16:52:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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":"test-instance-freed-ip","root_pass":"Bqlo\u003e*1IBe57500Tc50e0\u003eNqESxQ4Z!Ea,\u0026+h`\u003e\u00264l2$0XD`QM(t`2uO/(a66Wyj","ipv4":["69.164.211.224"]}' + 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": 64649889, "label": "test-instance-freed-ip", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["69.164.211.224"], "ipv6": "2600:3c03::f03c:95ff:feb1:d72f/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": "a452b4b8a90dc1c3f7a916bd423079b94bd11772", "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: + - "849" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 30 Sep 2024 16:52: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: + - "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/69.164.211.224 + method: GET + response: + body: '{"address": "69.164.211.224", "gateway": "69.164.211.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "69-164-211-224.ip.linodeusercontent.com", + "linode_id": 64649889, "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: + - "268" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 30 Sep 2024 16:52:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + 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":"ephemeral-ip-test","root_pass":"?b7~}tJqzQ8/GsT1\u003c1BS3Zn9R67nhsA[kZ@g=X3}B-^z88x\u003eRG^08CzOp*2\\:97g"}' + 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": 64649890, "label": "ephemeral-ip-test", "group": "", "status": "provisioning", + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "type": + "g6-nanode-1", "ipv4": ["69.164.215.150"], "ipv6": "2600:3c03::f03c:95ff:feb1:d7eb/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": "58a354ebdb494a9193cafdc0920899b2b5ce7333", "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: + - "844" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 30 Sep 2024 16:52: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: "" + 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/64649890 + 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: + - Mon, 30 Sep 2024 16:52:11 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/64649889 + 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: + - Mon, 30 Sep 2024 16:52:13 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/69.164.211.224 + 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: + - Mon, 30 Sep 2024 16:52:13 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/instance_reserved_ips_test.go b/test/integration/instance_reserved_ips_test.go index e1f55af61..ded8c81af 100644 --- a/test/integration/instance_reserved_ips_test.go +++ b/test/integration/instance_reserved_ips_test.go @@ -454,3 +454,90 @@ func TestInstance_AddReservedIPToInstanceVariants(t *testing.T) { t.Errorf("Expected error when omitting address field, but got none") } } + +func TestInstance_DeleteInstanceVariants(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestInstance_DeleteInstanceVariants") + defer teardown() + + // Create a Linode with a reserved IP + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: "us-east"}) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + t.Logf("Successfully reserved IP address") + defer func() { + err := client.DeleteReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Errorf("Failed to delete reserved IP: %v", err) + } + }() + + instance, _, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + if err != nil { + t.Fatalf("Error creating instance with reserved IP: %s", err) + } + t.Logf("Successfully created linode with reserved IP") + + // Delete a Linode with a reserved IP + err = client.DeleteInstance(context.Background(), instance.ID) + if err != nil { + t.Fatalf("Failed to delete Linode with reserved IP: %v", err) + } + t.Logf("Successfully deleted linode!") + + // Verify the reserved IP is retained after Linode deletion + retainedIP, err := client.GetReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Fatalf("Failed to get reserved IP after Linode deletion: %v", err) + } + if !retainedIP.Reserved || retainedIP.LinodeID != 0 { + t.Errorf("Reserved IP not retained correctly after Linode deletion") + } + t.Logf("Reserved IP retained after Linode deletion") + + // Reassign the freed reserved IP to a new Linode + newInstance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ + Region: "us-east", + Type: "g6-nanode-1", + Label: "test-instance-freed-ip", + RootPass: randPassword(), + IPv4: []string{reservedIP.Address}, + }) + if err != nil { + t.Fatalf("Failed to create new instance with freed reserved IP: %v", err) + } + t.Logf("Created instance with freed reserved IP with id = %d", newInstance.ID) + + defer func() { + if err := client.DeleteInstance(context.Background(), newInstance.ID); err != nil { + t.Errorf("Error deleting new test Instance: %s", err) + } + }() + + // Verify the IP is assigned to the new Linode + reassignedIP, err := client.GetReservedIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Fatalf("Failed to get reassigned reserved IP: %v", err) + } + if reassignedIP.LinodeID == 0 || reassignedIP.LinodeID != newInstance.ID { + t.Errorf("Reserved IP not correctly reassigned to new Linode") + } + t.Logf("Reserved IP successfully reassigned to new Linode") + + // PERMUTATION 4: Delete a Linode with an ephemeral IP + ephemeralInstance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ + Region: "us-east", + Type: "g6-nanode-1", + Label: "ephemeral-ip-test", + RootPass: randPassword(), + }) + if err != nil { + t.Fatalf("Failed to create Linode with ephemeral IP: %v", err) + } + + err = client.DeleteInstance(context.Background(), ephemeralInstance.ID) + if err != nil { + t.Fatalf("Failed to delete Linode with ephemeral IP: %v", err) + } + t.Logf("Successfully deleted Linode with ephemeral IP") +} From c9a70b8ea2718ee19c3ee4c57eb75df426a80556 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 30 Sep 2024 17:17:19 -0400 Subject: [PATCH 36/43] added test for verifying the status of the reserved field when listing addresses of a linode --- ...resses_GetInstanceIPReservationStatus.yaml | 534 ++++++++++++++++++ test/integration/network_reserved_ips_test.go | 74 +++ 2 files changed, 608 insertions(+) create mode 100644 test/integration/TestReservedIPAddresses_GetInstanceIPReservationStatus.yaml diff --git a/test/integration/TestReservedIPAddresses_GetInstanceIPReservationStatus.yaml b/test/integration/TestReservedIPAddresses_GetInstanceIPReservationStatus.yaml new file mode 100644 index 000000000..1ca7cdb20 --- /dev/null +++ b/test/integration/TestReservedIPAddresses_GetInstanceIPReservationStatus.yaml @@ -0,0 +1,534 @@ +--- +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": "69.164.211.224", "gateway": "69.164.211.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "69-164-211-224.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: + - Mon, 30 Sep 2024 21:11: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-iciv55fz7379","root_pass":"i.L9In8UuA1\\''+xrW8@HG0[hE91\\?29:40@tkUGG\u003ek:.3c63nRR9!jYIc7j.=Nfm","image":"linode/alpine3.17","interfaces":[{"purpose":"public"}],"booted":false,"ipv4":["69.164.211.224"]}' + 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": 64660675, "label": "go-test-ins-reserved-ip-iciv55fz7379", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["69.164.211.224"], "ipv6": "2600:3c03::f03c:95ff:feb1:6cca/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": "b3417256e635b83e03311cd43bf9303dacc5a75d", "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: + - Mon, 30 Sep 2024 21:11:20 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/64660675/ips + method: GET + response: + body: '{"ipv4": {"public": [{"address": "69.164.211.224", "gateway": "69.164.211.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "69-164-211-224.ip.linodeusercontent.com", "linode_id": 64660675, "region": + "us-east", "vpc_nat_1_1": null, "reserved": true}], "private": [], "shared": + [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2600:3c03::f03c:95ff:feb1:6cca", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 64660675, "region": "us-east", "public": + true}, "link_local": {"address": "fe80::f03c:95ff:feb1:6cca", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 64660675, "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-Length: + - "817" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 30 Sep 2024 21:11:20 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + 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: '{"region":"us-east","type":"g6-nanode-1","label":"test-instance-ephemeral-ip","root_pass":"*Y3,P,1;B~2r=8G5}s|Pbe8xI\u003e^02uXO0ur964HOd\u003c2{vHsf-^8Utz\u0026ZB64oMxW\u0026"}' + 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": 64660677, "label": "test-instance-ephemeral-ip", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.56.102.65"], "ipv6": "2600:3c03::f03c:95ff:feb1:6c9d/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": "f3bbdb58fa73e88a3294e17d587a130138658c53", "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: + - "851" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 30 Sep 2024 21:11:20 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/64660677/ips + method: GET + response: + body: '{"ipv4": {"public": [{"address": "45.56.102.65", "gateway": "45.56.102.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "45-56-102-65.ip.linodeusercontent.com", "linode_id": 64660677, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}], "private": [], "shared": + [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2600:3c03::f03c:95ff:feb1:6c9d", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 64660677, "region": "us-east", "public": + true}, "link_local": {"address": "fe80::f03c:95ff:feb1:6c9d", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 64660677, "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-Length: + - "813" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 30 Sep 2024 21:11:21 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + 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/linode/instances/64660677 + 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: + - Mon, 30 Sep 2024 21:11:22 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/64660675 + 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: + - Mon, 30 Sep 2024 21:11:25 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/69.164.211.224 + 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: + - Mon, 30 Sep 2024 21:11:25 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/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index a9b8c8b88..0e90cb350 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -391,3 +391,77 @@ func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { t.Errorf("Expected error when deleting unowned IP, got nil") } } + +func TestReservedIPAddresses_GetInstanceIPReservationStatus(t *testing.T) { + client, teardown := createTestClient(t, "TestReservedIPAddresses_GetInstanceIPReservationStatus") + defer teardown() + + // Create a Linode with a reserved IP + 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) + } + }() + + instanceWithReservedIP, instanceTeardown, err := createInstanceWithReservedIP(t, client, reservedIP.Address) + if err != nil { + t.Fatalf("Error creating instance with reserved IP: %s", err) + } + defer instanceTeardown() + + // Make GET request for the Linode with reserved IP + instanceAddresses, err := client.GetInstanceIPAddresses(context.Background(), instanceWithReservedIP.ID) + if err != nil { + t.Fatalf("Failed to get instance info for Linode with reserved IP: %v", err) + } + + // Check if the 'reserved' field is set to true + foundReserved := false + for _, ip := range instanceAddresses.IPv4.Public { + if ip.Address == reservedIP.Address { + if !ip.Reserved { + t.Errorf("Expected 'Reserved' field to be true for reserved IP %s, but it was false", ip.Address) + } + foundReserved = true + break + } + } + if !foundReserved { + t.Errorf("Reserved IP %s not found in instance's public IP addresses", reservedIP.Address) + } + + // Create a Linode with an ephemeral IP + instanceWithEphemeralIP, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ + Region: "us-east", + Type: "g6-nanode-1", + Label: "test-instance-ephemeral-ip", + RootPass: randPassword(), + }) + if err != nil { + t.Fatalf("Failed to create Linode with ephemeral IP: %v", err) + } + defer func() { + if err := client.DeleteInstance(context.Background(), instanceWithEphemeralIP.ID); err != nil { + t.Errorf("Error deleting test Instance with ephemeral IP: %s", err) + } + }() + + // Make GET request for the Linode with ephemeral IP + ephemeralInstanceAddresses, err := client.GetInstanceIPAddresses(context.Background(), instanceWithEphemeralIP.ID) + if err != nil { + t.Fatalf("Failed to get instance IP addresses for Linode with ephemeral IP: %v", err) + } + + // Check that all public IPs have 'Reserved' field set to false + for _, ip := range ephemeralInstanceAddresses.IPv4.Public { + if ip.Reserved { + t.Errorf("Expected 'Reserved' field to be false for ephemeral IP %s, but it was true", ip.Address) + } + } + +} From 2752177d8614e3926b79263f8db02d8cb83612b6 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 7 Oct 2024 13:27:23 -0400 Subject: [PATCH 37/43] Added support for existing resources to support reserved IP feature and corresponding tests --- network_ips.go | 22 +- test/integration/network_ips_test.go | 627 +++++++++++++++++++++++++++ 2 files changed, 648 insertions(+), 1 deletion(-) diff --git a/network_ips.go b/network_ips.go index f872cdb0a..450e87523 100644 --- a/network_ips.go +++ b/network_ips.go @@ -7,7 +7,8 @@ import ( // IPAddressUpdateOptions fields are those accepted by UpdateToken type IPAddressUpdateOptions struct { // The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to a default value provided by Linode if set to nil. - RDNS *string `json:"rdns"` + Reserved bool `json:"reserved"` + RDNS *string `json:"rdns,omitempty"` } // LinodeIPAssignment stores an assignment between an IP address and a Linode instance. @@ -16,6 +17,14 @@ type LinodeIPAssignment struct { LinodeID int `json:"linode_id"` } +type LinodeReserveIPOptions struct { + Type string `json:"type"` + Public bool `json:"public"` + Reserved bool `json:"reserved,omitempty"` + Region string `json:"region,omitempty"` + LinodeID int `json:"linode_id,omitempty"` +} + // LinodesAssignIPsOptions fields are those accepted by InstancesAssignIPs. type LinodesAssignIPsOptions struct { Region string `json:"region"` @@ -88,3 +97,14 @@ func (c *Client) ShareIPAddresses(ctx context.Context, opts IPAddressesShareOpti _, err := doPOSTRequest[InstanceIP](ctx, c, e, opts) return err } + +// AllocateReserveIP allocates a new IPv4 address to the Account, with the option to reserve it +// and optionally assign it to a Linode. +func (c *Client) AllocateReserveIP(ctx context.Context, opts LinodeReserveIPOptions) (*InstanceIP, error) { + e := "networking/ips" + result, err := doPOSTRequest[InstanceIP](ctx, c, e, opts) + if err != nil { + return nil, err + } + return result, nil +} diff --git a/test/integration/network_ips_test.go b/test/integration/network_ips_test.go index b61b5c346..123155586 100644 --- a/test/integration/network_ips_test.go +++ b/test/integration/network_ips_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/linode/linodego" . "github.com/linode/linodego" ) @@ -43,6 +44,33 @@ func TestIPAddress_GetFound(t *testing.T) { if i.Address != address { t.Errorf("Expected a specific ipaddress, but got a different one %v", i) } + + // Test for fetching reserved IP + // First, create a reserved IP + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{ + Region: instance.Region, + }) + 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) + } + }() + + // Now get the reserved IP + newReservedIP, err := client.GetIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Fatalf("Error getting reserved IP address: %v", err) + } + if newReservedIP.Address != reservedIP.Address { + t.Errorf("Expected IP address %s, but got %s", reservedIP.Address, i.Address) + } + if !newReservedIP.Reserved { + t.Errorf("Expected reserved IP to have Reserved=true, but got false") + } } func TestIPAddresses_List_smoke(t *testing.T) { @@ -92,6 +120,38 @@ func TestIPAddresses_List_smoke(t *testing.T) { t.Fatalf("expected empty rdns for ipv6 address; got %s", ip.RDNS) } } + + reservedFilter := "{\"reserved\":true}" + reservedIpAddresses, err := client.ListIPAddresses(context.Background(), NewListOptions(0, reservedFilter)) + if err != nil { + t.Errorf("Error listing ipaddresses, expected struct, got error %v", err) + } + if len(i) == 0 { + t.Errorf("Expected a list of ipaddresses, but got none %v", reservedIpAddresses) + } + + // Verify that all IPs in the reserved list are actually reserved + for _, ip := range reservedIpAddresses { + if !ip.Reserved { + t.Errorf("IP %s is in the reserved list but has Reserved field set to false", ip.Address) + } + } + + unreservedFilter := "{\"reserved\":false}" + unreservedIpAddresses, err := client.ListIPAddresses(context.Background(), NewListOptions(0, unreservedFilter)) + if err != nil { + t.Errorf("Error listing ipaddresses, expected struct, got error %v", err) + } + if len(i) == 0 { + t.Errorf("Expected a list of ipaddresses, but got none %v", unreservedIpAddresses) + } + + // Verify that all IPs in the reserved list are actually unreserved + for _, ip := range unreservedIpAddresses { + if ip.Reserved { + t.Errorf("IP %s is in the non-reserved list but has Reserved field set to true", ip.Address) + } + } } func TestIPAddresses_Instance_Get(t *testing.T) { @@ -132,6 +192,184 @@ func TestIPAddress_Update(t *testing.T) { if err != nil { t.Error(err) } + + // Test for updated behavior + + createReservedIP := func() (string, error) { + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: instance.Region}) + if err != nil { + return "", err + } + return reservedIP.Address, nil + } + + // Scenario 1: Convert ephemeral IP to reserved IP + + ephemeralIP := instance.IPv4[0].String() + updateOpts = IPAddressUpdateOptions{ + Reserved: true, + } + updatedIP, err := client.UpdateIPAddress(context.Background(), ephemeralIP, updateOpts) + if err != nil { + t.Fatalf("Failed to convert ephemeral IP to reserved: %v", err) + } + if !updatedIP.Reserved { + t.Errorf("Expected IP to be reserved, but it's not") + } + + // Scenario 2: Convert reserved IP to reserved IP (no-op) + + reservedIP, err := createReservedIP() + if err != nil { + t.Fatalf("Failed to create reserved IP: %v", err) + } + defer client.DeleteReservedIPAddress(context.Background(), reservedIP) + + updateOpts = IPAddressUpdateOptions{ + Reserved: true, + } + updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) + if err != nil { + t.Fatalf("Failed to update reserved IP: %v", err) + } + if !updatedIP.Reserved { + t.Errorf("Expected IP to remain reserved, but it's not") + } + + // Scenario 3: Convert reserved to ephemeral + + ephemeralIP = instance.IPv4[0].String() + updateOpts = IPAddressUpdateOptions{ + Reserved: false, + } + updatedIP, err = client.UpdateIPAddress(context.Background(), ephemeralIP, updateOpts) + if err != nil { + t.Fatalf("Failed to update ephemeral IP: %v", err) + } + if updatedIP.Reserved { + t.Errorf("Expected IP to remain ephemeral, but it's reserved") + } + + // Scenario 4: Convert assigned reserved IP to ephemeral + reservedIP, err = createReservedIP() + if err != nil { + t.Fatalf("Failed to create reserved IP: %v", err) + } + defer client.DeleteReservedIPAddress(context.Background(), reservedIP) + + // Assign the reserved IP to the instance + assignOpts := LinodesAssignIPsOptions{ + Region: instance.Region, + Assignments: []LinodeIPAssignment{ + { + Address: reservedIP, + LinodeID: instance.ID, + }, + }, + } + err = client.InstancesAssignIPs(context.Background(), assignOpts) + if err != nil { + t.Fatalf("Failed to assign reserved IP: %v", err) + } + + updateOpts = IPAddressUpdateOptions{ + Reserved: false, + } + updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) + if err != nil { + t.Fatalf("Failed to convert assigned reserved IP to ephemeral: %v", err) + } + if updatedIP.Reserved { + t.Errorf("Expected IP to be converted to ephemeral, but it's still reserved") + } + + // Sceanrio 5: Cannot set RDNS for unassigned reserved IP + + unassignedResIP, unassignedResIpErr := createReservedIP() + if unassignedResIpErr != nil { + t.Fatalf("Failed to create reserved IP: %v", unassignedResIpErr) + } + + updateOpts = IPAddressUpdateOptions{ + Reserved: true, + RDNS: String("sample rdns"), + } + _, err = client.UpdateIPAddress(context.Background(), unassignedResIP, updateOpts) + if err == nil { + t.Fatalf("Expected error when setting RDNS for unassigned reserved IP, but got none") + } + + // Sceanrio 6: Try to reserve an IP at MAX reserve IP limit + + reservedIP, err = createReservedIP() + if err == nil { + t.Fatalf("Expected error indicating MAX IP Reservation limit has been reached, got nil") + } else { + updateOpts = IPAddressUpdateOptions{ + Reserved: true, + } + _, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) + if err == nil { + t.Fatalf("Expected error when setting RDNS for unassigned reserved IP, but got none") + } + } + + client.DeleteReservedIPAddress(context.Background(), unassignedResIP) + + // Scenario 6: Convert unassigned reserved IP to reserved (no-op) + + reservedIP, err = createReservedIP() + if err != nil { + t.Fatalf("Failed to create reserved IP: %v", err) + } + + updateOpts = IPAddressUpdateOptions{ + Reserved: true, + } + updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) + if err != nil { + t.Fatalf("Failed to update unassigned reserved IP: %v", err) + } + if !updatedIP.Reserved || updatedIP.LinodeID != 0 { + t.Errorf("Expected IP to remain unassigned reserved, but got: %+v", updatedIP) + } + + client.DeleteReservedIPAddress(context.Background(), reservedIP) + + // Scenario 7: Convert unassigned reserved IP to unassigned (delete) + + reservedIP, err = createReservedIP() + if err != nil { + t.Fatalf("Failed to create reserved IP: %v", err) + } + + updateOpts = IPAddressUpdateOptions{ + Reserved: false, + } + _, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) + if err != nil { + t.Fatalf("Failed to convert unassigned reserved IP to unassigned: %v", err) + } + + // Verify the IP has been deleted + _, err = client.GetIPAddress(context.Background(), reservedIP) + if err == nil { + t.Errorf("Expected IP to be deleted, but it still exists") + } + + // Scenario 10: Cannot convert non-owned reserved IP + + invalidResIp := "123.72.121.76" + + updateOpts = IPAddressUpdateOptions{ + Reserved: false, + } + + updatedIP, err = client.UpdateIPAddress(context.Background(), invalidResIp, updateOpts) + if err == nil { + t.Fatalf("Expected error indicating the IP address is invalid, got nil") + } + } // TestIPAddress_Instance_Delete requires the customer account to have @@ -281,3 +519,392 @@ func TestIPAddress_Instance_Share(t *testing.T) { t.Errorf("failed to find assigned ip") } + +func TestIPAddress_Instance_Allocate(t *testing.T) { + client, instance, _, teardown, err := setupInstanceWithoutDisks(t, "fixtures/TestIPAddress_Instance_Allocate", true) + defer teardown() + if err != nil { + t.Fatal(err) + } + + // Scenario 1: Valid request + + opts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + Region: instance.Region, + LinodeID: instance.ID, + } + validIp, err := client.AllocateReserveIP(context.Background(), opts) + // defer cleanUpIPAllocation(t, client, validIp.Address) + if err != nil { + t.Fatalf("Expected successful IP reservation, got error: %v", err) + } + if !validIp.Reserved || validIp.LinodeID != instance.ID { + t.Errorf("Unexpected IP reservation result: %+v", validIp) + } + + // Scenario 2: Non-owned Linode + nonOwnedLinodeOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + Region: instance.Region, + LinodeID: 99999, // Assume this is a non-owned Linode ID + } + _, nonOwnedLinodeErr := client.AllocateReserveIP(context.Background(), nonOwnedLinodeOpts) + if nonOwnedLinodeErr == nil { + t.Fatal("Expected error for non-owned Linode, got nil") + } + + // Scenario 3: Omit Linode ID + + omitLinodeIDOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + Region: instance.Region, + } + omitLinodeIDip, omitLinodeErr := client.AllocateReserveIP(context.Background(), omitLinodeIDOpts) + if omitLinodeErr != nil { + t.Fatalf("Expected successful unassigned IP reservation, got error: %v", omitLinodeErr) + } + if !omitLinodeIDip.Reserved || omitLinodeIDip.LinodeID != 0 || omitLinodeIDip.Region != instance.Region { + t.Errorf("Unexpected unassigned IP reservation result: %+v", omitLinodeIDip) + } + + // Scenario 4: Account at reserved IP limit + + resLimitoOpts := linodego.LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + Region: instance.Region, + LinodeID: instance.ID, + } + _, resLimitErr := client.AllocateReserveIP(context.Background(), resLimitoOpts) + if resLimitErr == nil { + t.Fatal("Expected error for account at reserved IP limit, got nil") + } + + cleanUpReserveIPAllocation(t, client, validIp.Address) + cleanUpReserveIPAllocation(t, client, omitLinodeIDip.Address) + + // // Scenario 5: Linode at IPMax limit + + // opts = linodego.LinodeReserveIPOptions{ + // Type: "ipv4", + // Public: true, + // Reserved: true, + // Region: instance.Region, + // LinodeID: 64863869, + // } + // _, err = client.AllocateReserveIP(context.Background(), opts) + // if err == nil { + // t.Fatal("Expected error for Linode at IPMax limit, got nil") + // } + + // Scenario 6: Omit Region + + omitRegionOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + LinodeID: instance.ID, + } + omitRegionip, omitRegionErr := client.AllocateReserveIP(context.Background(), omitRegionOpts) + // defer cleanUpIPAllocation(t, client, omitRegionip.Address) + if omitRegionErr != nil { + t.Fatalf("Expected successful IP reservation without region, got error: %v", omitRegionErr) + } + if !omitRegionip.Reserved || omitRegionip.LinodeID != instance.ID { + t.Errorf("Unexpected IP reservation result without region: %+v", omitRegionip) + } + + cleanUpReserveIPAllocation(t, client, omitRegionip.Address) + + // Scenario 7: Omit both Region and Linode ID + + omitRegionAndLinodeIDopts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + } + _, omitRegionAndLinodeIDerr := client.AllocateReserveIP(context.Background(), omitRegionAndLinodeIDopts) + + if omitRegionAndLinodeIDerr == nil { + t.Fatal("Expected error when omitting both region and Linode ID, got nil") + } + + // Scenario 8: Reserved true, Public false + + publicFalseOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: false, + Reserved: true, + Region: instance.Region, + LinodeID: instance.ID, + } + _, publicFalseErr := client.AllocateReserveIP(context.Background(), publicFalseOpts) + if publicFalseErr == nil { + t.Fatal("Expected error for reserved true and public false, got nil") + } + + // Scenario 9: Reserved false + + reservedFalseOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: false, + Region: instance.Region, + LinodeID: instance.ID, + } + reservedFalseIp, reservedFalseErr := client.AllocateReserveIP(context.Background(), reservedFalseOpts) + if reservedFalseErr != nil { + t.Fatalf("Expected successful ephemeral IP assignment, got error: %v", reservedFalseErr) + } + if reservedFalseIp.Reserved || reservedFalseIp.LinodeID != instance.ID { + t.Errorf("Unexpected ephemeral IP assignment result: %+v", reservedFalseIp) + } + + cleanUpIPAllocation(t, client, instance.ID, reservedFalseIp.Address) + + // Scenario 10: Omit Reserved field + + omitReservedOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Region: instance.Region, + LinodeID: instance.ID, + } + omitReservedip, omitReservedErr := client.AllocateReserveIP(context.Background(), omitReservedOpts) + if omitReservedErr != nil { + t.Fatalf("Expected successful IP assignment, got error: %v", omitReservedErr) + } + if omitReservedip.Reserved || omitReservedip.LinodeID != instance.ID { + t.Errorf("Unexpected IP assignment result: %+v", omitReservedip) + } + + cleanUpIPAllocation(t, client, instance.ID, omitReservedip.Address) + + // Scenario 11: Omit Linode ID, Reserved false + + omitOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: false, + Region: instance.Region, + } + _, omitOptsErr := client.AllocateReserveIP(context.Background(), omitOpts) + if omitOptsErr == nil { + t.Fatal("Expected error when omitting Linode ID and setting reserved to false, got nil") + } + + // Scenario 12: Omit Linode ID and Reserved fields + + omitIDResopts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Region: instance.Region, + } + _, omitIDResErr := client.AllocateReserveIP(context.Background(), omitIDResopts) + if omitIDResErr == nil { + t.Fatal("Expected error when omitting Linode ID and reserved fields, got nil") + } + + // Scenario 13: Reserved true, Type IPv6 + + typeIPv6opts := LinodeReserveIPOptions{ + Type: "ipv6", + Public: true, + Reserved: true, + Region: instance.Region, + LinodeID: instance.ID, + } + _, typeIPv6Err := client.AllocateReserveIP(context.Background(), typeIPv6opts) + if typeIPv6Err == nil { + t.Fatal("Expected error for reserved true and type IPv6, got nil") + } + + // Scenario 14: Reserved false, Type IPv6 + + resFalseIPv6opts := LinodeReserveIPOptions{ + Type: "ipv6", + Public: true, + Reserved: false, + Region: instance.Region, + LinodeID: instance.ID, + } + _, resFalseIPv6Err := client.AllocateReserveIP(context.Background(), resFalseIPv6opts) + if resFalseIPv6Err == nil { + t.Fatalf("Expected unsuccessful IPv6 assignment, got nil") + } + + // Scenario 15: Region mismatch + + regionMismatchOpts := LinodeReserveIPOptions{ + Type: "ipv4", + Public: true, + Reserved: true, + Region: "us-west", // Assume this is different from instance.Region + LinodeID: instance.ID, + } + _, regionMismatchErr := client.AllocateReserveIP(context.Background(), regionMismatchOpts) + if regionMismatchErr == nil { + t.Fatal("Expected error for region mismatch, got nil") + } + +} + +func cleanUpReserveIPAllocation(t *testing.T, client *linodego.Client, address string) { + err := client.DeleteReservedIPAddress(context.Background(), address) + if err != nil { + t.Logf("Failed to delete reserved IP %s: %v", address, err) + } +} + +func cleanUpIPAllocation(t *testing.T, client *linodego.Client, linodeID int, address string) { + err := client.DeleteInstanceIPAddress(context.Background(), linodeID, address) + if err != nil { + t.Logf("Failed to delete reserved IP %s: %v", address, err) + } +} + +func TestIPAddress_Instance_ReserveIP_Assign(t *testing.T) { + client, teardown := createTestClient(t, "fixtures/TestIPAddress_Instance_ReserveIP_Assign") + defer teardown() + + // Create two Linodes for testing + linode1, err := createInstance(t, client, true) + if err != nil { + t.Fatalf("Error creating first test Linode: %s", err) + } + defer func() { + if err := client.DeleteInstance(context.Background(), linode1.ID); err != nil { + t.Errorf("Error deleting first test Linode: %s", err) + } + }() + + linode2, err := createInstance(t, client, true) + if err != nil { + t.Fatalf("Error creating second test Linode: %s", err) + } + defer func() { + if err := client.DeleteInstance(context.Background(), linode2.ID); err != nil { + t.Errorf("Error deleting second test Linode: %s", err) + } + }() + + // Scenario 1: Assign unassigned reserved IP to existing Linode + + reservedIP, err := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: linode1.Region}) + if err != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + defer cleanUpReserveIPAllocation(t, client, reservedIP.Address) + + err = client.InstancesAssignIPs(context.Background(), LinodesAssignIPsOptions{ + Region: linode1.Region, + Assignments: []LinodeIPAssignment{ + { + Address: reservedIP.Address, + LinodeID: linode1.ID, + }, + }, + }) + if err != nil { + t.Fatalf("Failed to assign reserved IP: %v", err) + } + + // Verify assignment + ip, err := client.GetIPAddress(context.Background(), reservedIP.Address) + if err != nil { + t.Fatalf("Failed to get IP address info: %v", err) + } + if !ip.Reserved || ip.LinodeID != linode1.ID { + t.Errorf("Unexpected IP assignment result: %+v", ip) + } + + // Scenario 2: Reassign reserved IP to different Linode + + reassignIP, reassignIPerr := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: linode1.Region}) + if reassignIPerr != nil { + t.Fatalf("Failed to reserve IP: %v", err) + } + + // Assign to first Linode + assignErr := client.InstancesAssignIPs(context.Background(), LinodesAssignIPsOptions{ + Region: linode1.Region, + Assignments: []LinodeIPAssignment{ + { + Address: reassignIP.Address, + LinodeID: linode1.ID, + }, + }, + }) + if assignErr != nil { + t.Fatalf("Failed to assign reserved IP to first Linode: %v", assignErr) + } + + // Reassign to second Linode + reassignErr := client.InstancesAssignIPs(context.Background(), LinodesAssignIPsOptions{ + Region: linode2.Region, + Assignments: []LinodeIPAssignment{ + { + Address: reassignIP.Address, + LinodeID: linode2.ID, + }, + }, + }) + if reassignErr != nil { + t.Fatalf("Failed to reassign reserved IP: %v", reassignErr) + } + + // Verify reassignment + ipAddress, getIpErr := client.GetIPAddress(context.Background(), reassignIP.Address) + if getIpErr != nil { + t.Fatalf("Failed to get IP address info: %v", getIpErr) + } + if !ipAddress.Reserved || ipAddress.LinodeID != linode2.ID { + t.Errorf("Unexpected IP reassignment result: %+v", ipAddress) + } + + cleanUpReserveIPAllocation(t, client, reassignIP.Address) + + // Scenario 3: Attempt to assign non-owned reserved IP + + invalidIpErr := client.InstancesAssignIPs(context.Background(), LinodesAssignIPsOptions{ + Region: linode1.Region, + Assignments: []LinodeIPAssignment{ + { + Address: "192.0.2.1", // Assume this is a non-owned IP + LinodeID: linode1.ID, + }, + }, + }) + if invalidIpErr == nil { + t.Fatal("Expected error when assigning non-owned reserved IP, got nil") + } + + // Scenario 4: Attempt to assign owned reserved IP to non-owned Linode + + validResIP, validResIPerr := client.ReserveIPAddress(context.Background(), linodego.ReserveIPOptions{Region: linode1.Region}) + if validResIPerr != nil { + t.Fatalf("Failed to reserve IP: %v", validResIPerr) + } + defer cleanUpReserveIPAllocation(t, client, validResIP.Address) + + invalidLinodeErr := client.InstancesAssignIPs(context.Background(), LinodesAssignIPsOptions{ + Region: linode1.Region, + Assignments: []LinodeIPAssignment{ + { + Address: validResIP.Address, + LinodeID: 99999, // Assume this is a non-owned Linode ID + }, + }, + }) + if invalidLinodeErr == nil { + t.Fatal("Expected error when assigning to non-owned Linode, got nil") + } +} From 30435e2ab9b66c26bea9cf916fc5550381b6a463 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 7 Oct 2024 13:29:34 -0400 Subject: [PATCH 38/43] Updated fixtures with required interactions for reserved IP feature and recorded new ones for allocating and assigning reserved IPs --- .../fixtures/TestIPAddress_GetFound.yaml | 752 ++++--- .../TestIPAddress_Instance_Allocate.yaml | 1560 +++++++++++++ ...stIPAddress_Instance_ReserveIP_Assign.yaml | 1372 ++++++++++++ .../fixtures/TestIPAddress_Update.yaml | 1788 ++++++++++++--- .../fixtures/TestIPAddresses_List.yaml | 1992 +++++++++++++---- 5 files changed, 6518 insertions(+), 946 deletions(-) create mode 100644 test/integration/fixtures/TestIPAddress_Instance_Allocate.yaml create mode 100644 test/integration/fixtures/TestIPAddress_Instance_ReserveIP_Assign.yaml diff --git a/test/integration/fixtures/TestIPAddress_GetFound.yaml b/test/integration/fixtures/TestIPAddress_GetFound.yaml index ac8811353..c2b32cfb8 100644 --- a/test/integration/fixtures/TestIPAddress_GetFound.yaml +++ b/test/integration/fixtures/TestIPAddress_GetFound.yaml @@ -15,262 +15,278 @@ interactions: method: GET response: body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata"], "status": "ok", "resolvers": {"ipv4": "172.105.34.5, 172.105.35.5, - 172.105.36.5, 172.105.37.5, 172.105.38.5, 172.105.39.5, 172.105.40.5, 172.105.41.5, - 172.105.42.5, 172.105.43.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "ca-central", "label": "Toronto, CA", "country": "ca", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.105.34.5, 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, + 172.105.39.5, 172.105.40.5, 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": + "2400:8904::f03c:91ff:fea5:659, 2400:8904::f03c:91ff:fea5:9282, 2400:8904::f03c:91ff:fea5:b9b3, + 2400:8904::f03c:91ff:fea5:925a, 2400:8904::f03c:91ff:fea5:22cb, 2400:8904::f03c:91ff:fea5:227a, + 2400:8904::f03c:91ff:fea5:924c, 2400:8904::f03c:91ff:fea5:f7e2, 2400:8904::f03c:91ff:fea5:2205, + 2400:8904::f03c:91ff:fea5:9207"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, 172.105.5.5, 172.105.6.5, 172.105.7.5, 172.105.8.5, 172.105.9.5, 172.105.10.5, - 172.105.11.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + 172.105.11.5", "ipv6": "2600:3c04::f03c:91ff:fea9:f63, 2600:3c04::f03c:91ff:fea9:f6d, + 2600:3c04::f03c:91ff:fea9:f80, 2600:3c04::f03c:91ff:fea9:f0f, 2600:3c04::f03c:91ff:fea9:f99, + 2600:3c04::f03c:91ff:fea9:fbd, 2600:3c04::f03c:91ff:fea9:fdd, 2600:3c04::f03c:91ff:fea9:fe2, + 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, 172.105.168.5, - 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, 172.105.181.5, - 172.105.161.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, + 172.105.168.5, 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, + 172.105.181.5, 172.105.161.5", "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, + 2400:8907::f03c:92ff:fe6e:1c58, 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, + 2400:8907::f03c:92ff:fe6e:c219, 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, + 2400:8907::f03c:92ff:fe6e:e6b, 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans"], "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, - 139.144.192.61, 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, - 139.144.192.66, 139.144.192.52, 139.144.192.68", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": - "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, + 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, + 139.144.192.68", "ipv6": "2600:3c05::f03c:93ff:feb6:43b6, 2600:3c05::f03c:93ff:feb6:4365, + 2600:3c05::f03c:93ff:feb6:43c2, 2600:3c05::f03c:93ff:feb6:e441, 2600:3c05::f03c:93ff:feb6:94ef, + 2600:3c05::f03c:93ff:feb6:94ba, 2600:3c05::f03c:93ff:feb6:94a8, 2600:3c05::f03c:93ff:feb6:9413, + 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": - "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, 2600:3c06::f03c:93ff:fed0:e572, + 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, 2600:3c06::f03c:93ff:fed0:e511, + 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, 2600:3c06::f03c:93ff:fed0:e529, + 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": + "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, + 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, + 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, + 2600:3c07::f03c:93ff:fef2:2ec7, 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, + 2600:3c07::f03c:93ff:fef2:0de0, 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, + 2600:3c07::f03c:93ff:fef2:0d82, 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "status": - "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, 172.232.32.17, 172.232.32.18, - 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, 172.232.32.11, 172.232.32.12", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-sea", "label": - "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, 172.232.160.15, 172.232.160.18, - 172.232.160.8, 172.232.160.12, 172.232.160.11, 172.232.160.14, 172.232.160.16", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "br-gru", "label": - "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.233.0.4, 172.233.0.9, 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, - 172.233.0.10, 172.233.0.6, 172.233.0.8, 172.233.0.11", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": - "nl", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, - 172.233.33.35, 172.233.33.39, 172.233.33.34, 172.233.33.33, 172.233.33.31, 172.233.33.30, - 172.233.33.37, 172.233.33.32", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": "se", "capabilities": + "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, + 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, 172.232.160.11, + 172.232.160.14, 172.232.160.16", "ipv6": "2600:3c0a::f03c:93ff:fe54:c6da, 2600:3c0a::f03c:93ff:fe54:c691, + 2600:3c0a::f03c:93ff:fe54:c68d, 2600:3c0a::f03c:93ff:fe54:c61e, 2600:3c0a::f03c:93ff:fe54:c653, + 2600:3c0a::f03c:93ff:fe54:c64c, 2600:3c0a::f03c:93ff:fe54:c68a, 2600:3c0a::f03c:93ff:fe54:c697, + 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, 172.232.128.22, - 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, 172.232.128.21, - 172.232.128.27", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, 172.233.111.25, - 172.233.111.19, 172.233.111.12, 172.233.111.26, 172.233.111.16, 172.233.111.18, - 172.233.111.9", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": "in", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, - 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": - "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.233.64.44, 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, - 172.233.64.41, 172.233.64.39, 172.233.64.42, 172.233.64.45, 172.233.64.38", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "it-mil", "label": - "Milan, IT", "country": "it", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, - 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": - "Miami, FL", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, 172.233.0.7, + 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, 172.233.0.8, + 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, 2600:3c0d::f03c:93ff:fe3d:51a7, + 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, 2600:3c0d::f03c:93ff:fe3d:51fe, + 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, 2600:3c0d::f03c:93ff:fe3d:5170, + 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.33.36, + 172.233.33.38, 172.233.33.35, 172.233.33.39, 172.233.33.34, 172.233.33.33, 172.233.33.31, + 172.233.33.30, 172.233.33.37, 172.233.33.32", "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, + 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, 2600:3c0e::f03c:93ff:fe9d:2d96, + 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, 2600:3c0e::f03c:93ff:fe9d:2d68, + 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, 2600:3c0e::f03c:93ff:fe9d:2d5c"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": + "se", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.128.24, + 172.232.128.26, 172.232.128.20, 172.232.128.22, 172.232.128.25, 172.232.128.19, + 172.232.128.23, 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, + 2600:3c09::f03c:93ff:fea9:4d63, 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, + 2600:3c09::f03c:93ff:fea9:4d99, 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, + 2600:3c09::f03c:93ff:fea9:4d69, 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": + "es", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.111.6, + 172.233.111.17, 172.233.111.21, 172.233.111.25, 172.233.111.19, 172.233.111.12, + 172.233.111.26, 172.233.111.16, 172.233.111.18, 172.233.111.9", "ipv6": "2a01:7e02::f03c:93ff:feea:b585, + 2a01:7e02::f03c:93ff:feea:b5ab, 2a01:7e02::f03c:93ff:feea:b5c6, 2a01:7e02::f03c:93ff:feea:b592, + 2a01:7e02::f03c:93ff:feea:b5aa, 2a01:7e02::f03c:93ff:feea:b5d3, 2a01:7e02::f03c:93ff:feea:b5d7, + 2a01:7e02::f03c:93ff:feea:b528, 2a01:7e02::f03c:93ff:feea:b522, 2a01:7e02::f03c:93ff:feea:b51a"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": + "in", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, - 172.233.160.28, 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "id-cgk", "label": - "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.232.224.23, 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, - 172.232.224.24, 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-lax", "label": - "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, - 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, 172.233.128.44", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": - "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.236.0.46, 172.236.0.50, - 172.236.0.47, 172.236.0.53, 172.236.0.52, 172.236.0.45, 172.236.0.49, 172.236.0.51, - 172.236.0.54, 172.236.0.48", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, + 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", + "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, + 2600:3c08::f03c:93ff:fe7c:11a7, 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, + 2600:3c08::f03c:93ff:fe7c:11f9, 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, + 2600:3c08::f03c:93ff:fe7c:1164"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": + "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, 172.233.64.43, + 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, 172.233.64.42, + 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, 2400:8905::f03c:93ff:fe9d:b012, + 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, 2400:8905::f03c:93ff:fe9d:259f, + 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, 2400:8905::f03c:93ff:fe9d:b0ce, + 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, + 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, + 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", "ipv6": "2600:3c0b::f03c:93ff:feba:d513, + 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, 2600:3c0b::f03c:93ff:feba:d5fb, + 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, 2600:3c0b::f03c:93ff:feba:d5d5, + 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, 2600:3c0b::f03c:93ff:feba:d529"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-mia", "label": "Miami, FL", "country": + "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.160.34, + 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, 172.233.160.28, + 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, + 2a01:7e04::f03c:93ff:fead:d37f, 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, + 2a01:7e04::f03c:93ff:fead:d316, 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, + 2a01:7e04::f03c:93ff:fead:d395, 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": + "id", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, + 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, + 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", "ipv6": "2600:3c0c::f03c:93ff:feed:a90b, + 2600:3c0c::f03c:93ff:feed:a9a5, 2600:3c0c::f03c:93ff:feed:a935, 2600:3c0c::f03c:93ff:feed:a930, + 2600:3c0c::f03c:93ff:feed:a95c, 2600:3c0c::f03c:93ff:feed:a9ad, 2600:3c0c::f03c:93ff:feed:a9f2, + 2600:3c0c::f03c:93ff:feed:a9ff, 2600:3c0c::f03c:93ff:feed:a9c8, 2600:3c0c::f03c:93ff:feed:a96b"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, + 172.233.128.37, 172.233.128.34, 172.233.128.36, 172.233.128.33, 172.233.128.39, + 172.233.128.43, 172.233.128.44", "ipv6": "2a01:7e03::f03c:93ff:feb1:b789, 2a01:7e03::f03c:93ff:feb1:b717, + 2a01:7e03::f03c:93ff:feb1:b707, 2a01:7e03::f03c:93ff:feb1:b7ab, 2a01:7e03::f03c:93ff:feb1:b7e2, + 2a01:7e03::f03c:93ff:feb1:b709, 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, + 2a01:7e03::f03c:93ff:feb1:b76e, 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.236.32.23, 172.236.32.35, 172.236.32.30, 172.236.32.28, 172.236.32.32, - 172.236.32.33, 172.236.32.27, 172.236.32.37, 172.236.32.29, 172.236.32.34", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-central", - "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": + Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": + "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": + "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": + "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": + "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, 2600:3c00::8, + 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, 173.230.155.5, - 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, - 74.207.242.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": - "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": - {"ipv4": "74.207.231.5, 173.230.128.5, 173.230.129.5, 173.230.136.5, 173.230.140.5, - 66.228.59.5, 66.228.62.5, 50.116.35.5, 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, + 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, + 74.207.241.5, 74.207.242.5", "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, + 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, + 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": + "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, + 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, + 50.116.41.5, 23.239.18.5", "ipv6": "2600:3c02::3, 2600:3c02::5, 2600:3c02::4, + 2600:3c02::6, 2600:3c02::c, 2600:3c02::7, 2600:3c02::2, 2600:3c02::9, 2600:3c02::8, + 2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], "status": - "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, - 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, 207.192.69.5", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, - 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, 109.74.192.20, 109.74.193.20, - 109.74.194.20", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-south", "label": "Singapore, SG", "country": - "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": - {"ipv4": "139.162.11.5, 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, - 139.162.21.5, 139.162.27.5, 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU - Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5, - 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, 139.162.135.5, 139.162.136.5, - 139.162.137.5, 139.162.138.5, 139.162.139.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", - "label": "Tokyo, JP", "country": "jp", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": - {"ipv4": "139.162.66.5, 139.162.67.5, 139.162.68.5, 139.162.69.5, 139.162.70.5, - 139.162.71.5, 139.162.72.5, 139.162.73.5, 139.162.74.5, 139.162.75.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}], "page": 1, "pages": 1, "results": 27}' + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, + 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, + 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, + 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": + "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": + "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, + 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, + 2a01:7e00::3, 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, + 2a01:7e00::4, 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, + 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, + 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "2400:8901::5, 2400:8901::4, + 2400:8901::b, 2400:8901::3, 2400:8901::9, 2400:8901::2, 2400:8901::8, 2400:8901::7, + 2400:8901::c, 2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 30}' headers: Access-Control-Allow-Credentials: - "true" @@ -282,6 +298,8 @@ interactions: - '*' 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: @@ -291,7 +309,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:44 GMT + - Wed, 02 Oct 2024 19:11:51 GMT Pragma: - no-cache Strict-Transport-Security: @@ -310,14 +328,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-g4i782rea04u","firewall_id":640265,"booted":false}' + body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-4fbae521k2a1","booted":false}' form: {} headers: Accept: @@ -329,16 +347,17 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61169660, "label": "go-test-ins-wo-disk-g4i782rea04u", "group": + body: '{"id": 64761254, "label": "go-test-ins-wo-disk-4fbae521k2a1", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.105.55.47"], "ipv6": "1234::5678/128", - "image": null, "region": "ap-west", "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": - true, "available": false, "schedule": {"day": null, "window": null}, "last_successful": - null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": - "aeb2357ce09e1cb483d94ee0d025f3b254c93dfc", "has_user_data": false, "placement_group": - null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["172.105.55.196"], "ipv6": "2400:8904::f03c:95ff:fe7e:b0ec/128", + "image": null, "region": "ap-west", "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": "b87012b659b947e3d8e73fccf7a05a0eaa29cc4d", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -350,18 +369,20 @@ interactions: - '*' 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: - - "785" + - "859" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:44 GMT + - Wed, 02 Oct 2024 19:11:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -385,7 +406,7 @@ interactions: code: 200 duration: "" - request: - body: '{"label":"go-test-conf-ww37y7em7j73","devices":{},"interfaces":null}' + body: '{"label":"go-test-conf-l70l72h89gjp","devices":{},"interfaces":null}' form: {} headers: Accept: @@ -394,11 +415,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61169660/configs + url: https://api.linode.com/v4beta/linode/instances/64761254/configs method: POST response: - body: '{"id": 64385514, "label": "go-test-conf-ww37y7em7j73", "helpers": {"updatedb_disabled": - true, "distro": true, "modules_dep": true, "network": true, "devtmpfs_automount": + body: '{"id": 68045903, "label": "go-test-conf-l70l72h89gjp", "helpers": {"updatedb_disabled": + true, "distro": true, "modules_dep": true, "network": false, "devtmpfs_automount": true}, "kernel": "linode/latest-64bit", "comments": "", "memory_limit": 0, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "root_device": "/dev/sda", "devices": {"sda": null, "sdb": null, "sdc": null, "sdd": null, "sde": null, @@ -415,18 +436,20 @@ interactions: - '*' 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: - - "539" + - "540" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:45 GMT + - Wed, 02 Oct 2024 19:11:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -443,7 +466,135 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "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/ips/172.105.55.196 + method: GET + response: + body: '{"address": "172.105.55.196", "gateway": "172.105.55.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-55-196.ip.linodeusercontent.com", + "linode_id": 64761254, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}' + 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: + - "269" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 02 Oct 2024 19:11:52 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips: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: '{"region":"ap-west"}' + 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.125.41", "gateway": "45.79.125.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-125-41.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Wed, 02 Oct 2024 19:11:53 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 @@ -459,12 +610,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.55.47 + url: https://api.linode.com/v4beta/networking/ips/45.79.125.41 method: GET response: - body: '{"address": "172.105.55.47", "gateway": "172.105.55.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-55-47.ip.linodeusercontent.com", - "linode_id": 61169660, "region": "ap-west", "vpc_nat_1_1": null}' + body: '{"address": "45.79.125.41", "gateway": "45.79.125.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-125-41.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: - "true" @@ -476,18 +627,20 @@ interactions: - '*' 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: - - "248" + - "259" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:45 GMT + - Wed, 02 Oct 2024 19:11:53 GMT Pragma: - no-cache Strict-Transport-Security: @@ -505,7 +658,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -521,7 +674,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61169660 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.125.41 method: DELETE response: body: '{}' @@ -536,6 +689,69 @@ interactions: - '*' 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: + - Wed, 02 Oct 2024 19:11:53 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/64761254 + 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: @@ -547,7 +763,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:45 GMT + - Wed, 02 Oct 2024 19:11:55 GMT Pragma: - no-cache Strict-Transport-Security: @@ -564,7 +780,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestIPAddress_Instance_Allocate.yaml b/test/integration/fixtures/TestIPAddress_Instance_Allocate.yaml new file mode 100644 index 000000000..7494c9ce9 --- /dev/null +++ b/test/integration/fixtures/TestIPAddress_Instance_Allocate.yaml @@ -0,0 +1,1560 @@ +--- +version: 1 +interactions: +- 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/regions?page=1 + method: GET + response: + body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.105.34.5, 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, + 172.105.39.5, 172.105.40.5, 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": + "2400:8904::f03c:91ff:fea5:659, 2400:8904::f03c:91ff:fea5:9282, 2400:8904::f03c:91ff:fea5:b9b3, + 2400:8904::f03c:91ff:fea5:925a, 2400:8904::f03c:91ff:fea5:22cb, 2400:8904::f03c:91ff:fea5:227a, + 2400:8904::f03c:91ff:fea5:924c, 2400:8904::f03c:91ff:fea5:f7e2, 2400:8904::f03c:91ff:fea5:2205, + 2400:8904::f03c:91ff:fea5:9207"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, + 172.105.5.5, 172.105.6.5, 172.105.7.5, 172.105.8.5, 172.105.9.5, 172.105.10.5, + 172.105.11.5", "ipv6": "2600:3c04::f03c:91ff:fea9:f63, 2600:3c04::f03c:91ff:fea9:f6d, + 2600:3c04::f03c:91ff:fea9:f80, 2600:3c04::f03c:91ff:fea9:f0f, 2600:3c04::f03c:91ff:fea9:f99, + 2600:3c04::f03c:91ff:fea9:fbd, 2600:3c04::f03c:91ff:fea9:fdd, 2600:3c04::f03c:91ff:fea9:fe2, + 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, + 172.105.168.5, 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, + 172.105.181.5, 172.105.161.5", "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, + 2400:8907::f03c:92ff:fe6e:1c58, 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, + 2400:8907::f03c:92ff:fe6e:c219, 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, + 2400:8907::f03c:92ff:fe6e:e6b, 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, + 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, + 139.144.192.68", "ipv6": "2600:3c05::f03c:93ff:feb6:43b6, 2600:3c05::f03c:93ff:feb6:4365, + 2600:3c05::f03c:93ff:feb6:43c2, 2600:3c05::f03c:93ff:feb6:e441, 2600:3c05::f03c:93ff:feb6:94ef, + 2600:3c05::f03c:93ff:feb6:94ba, 2600:3c05::f03c:93ff:feb6:94a8, 2600:3c05::f03c:93ff:feb6:9413, + 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, + 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", + "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, 2600:3c06::f03c:93ff:fed0:e572, + 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, 2600:3c06::f03c:93ff:fed0:e511, + 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, 2600:3c06::f03c:93ff:fed0:e529, + 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": + "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, + 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, + 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, + 2600:3c07::f03c:93ff:fef2:2ec7, 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, + 2600:3c07::f03c:93ff:fef2:0de0, 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, + 2600:3c07::f03c:93ff:fef2:0d82, 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, + 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, 172.232.160.11, + 172.232.160.14, 172.232.160.16", "ipv6": "2600:3c0a::f03c:93ff:fe54:c6da, 2600:3c0a::f03c:93ff:fe54:c691, + 2600:3c0a::f03c:93ff:fe54:c68d, 2600:3c0a::f03c:93ff:fe54:c61e, 2600:3c0a::f03c:93ff:fe54:c653, + 2600:3c0a::f03c:93ff:fe54:c64c, 2600:3c0a::f03c:93ff:fe54:c68a, 2600:3c0a::f03c:93ff:fe54:c697, + 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, 172.233.0.7, + 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, 172.233.0.8, + 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, 2600:3c0d::f03c:93ff:fe3d:51a7, + 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, 2600:3c0d::f03c:93ff:fe3d:51fe, + 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, 2600:3c0d::f03c:93ff:fe3d:5170, + 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, + 172.233.33.34, 172.233.33.33, 172.233.33.31, 172.233.33.30, 172.233.33.37, 172.233.33.32", + "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, + 2600:3c0e::f03c:93ff:fe9d:2d96, 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, + 2600:3c0e::f03c:93ff:fe9d:2d68, 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, + 2600:3c0e::f03c:93ff:fe9d:2d5c"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "se-sto", "label": + "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, + 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, + 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, 2600:3c09::f03c:93ff:fea9:4d63, + 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, 2600:3c09::f03c:93ff:fea9:4d99, + 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, 2600:3c09::f03c:93ff:fea9:4d69, + 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, + 172.233.111.25, 172.233.111.19, 172.233.111.12, 172.233.111.26, 172.233.111.16, + 172.233.111.18, 172.233.111.9", "ipv6": "2a01:7e02::f03c:93ff:feea:b585, 2a01:7e02::f03c:93ff:feea:b5ab, + 2a01:7e02::f03c:93ff:feea:b5c6, 2a01:7e02::f03c:93ff:feea:b592, 2a01:7e02::f03c:93ff:feea:b5aa, + 2a01:7e02::f03c:93ff:feea:b5d3, 2a01:7e02::f03c:93ff:feea:b5d7, 2a01:7e02::f03c:93ff:feea:b528, + 2a01:7e02::f03c:93ff:feea:b522, 2a01:7e02::f03c:93ff:feea:b51a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": "in", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, + 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", + "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, + 2600:3c08::f03c:93ff:fe7c:11a7, 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, + 2600:3c08::f03c:93ff:fe7c:11f9, 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, + 2600:3c08::f03c:93ff:fe7c:1164"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": + "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, + 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, + 172.233.64.42, 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, + 2400:8905::f03c:93ff:fe9d:b012, 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, + 2400:8905::f03c:93ff:fe9d:259f, 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, + 2400:8905::f03c:93ff:fe9d:b0ce, 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": + "it", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, + 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", + "ipv6": "2600:3c0b::f03c:93ff:feba:d513, 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, + 2600:3c0b::f03c:93ff:feba:d5fb, 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, + 2600:3c0b::f03c:93ff:feba:d5d5, 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, + 2600:3c0b::f03c:93ff:feba:d529"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": + "Miami, FL", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, + 172.233.160.29, 172.233.160.32, 172.233.160.28, 172.233.160.33, 172.233.160.26, + 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, 2a01:7e04::f03c:93ff:fead:d37f, + 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, 2a01:7e04::f03c:93ff:fead:d316, + 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, 2a01:7e04::f03c:93ff:fead:d395, + 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, + 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, + 172.232.224.31, 172.232.224.28", "ipv6": "2600:3c0c::f03c:93ff:feed:a90b, 2600:3c0c::f03c:93ff:feed:a9a5, + 2600:3c0c::f03c:93ff:feed:a935, 2600:3c0c::f03c:93ff:feed:a930, 2600:3c0c::f03c:93ff:feed:a95c, + 2600:3c0c::f03c:93ff:feed:a9ad, 2600:3c0c::f03c:93ff:feed:a9f2, 2600:3c0c::f03c:93ff:feed:a9ff, + 2600:3c0c::f03c:93ff:feed:a9c8, 2600:3c0c::f03c:93ff:feed:a96b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": + ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, + 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, 172.233.128.44", + "ipv6": "2a01:7e03::f03c:93ff:feb1:b789, 2a01:7e03::f03c:93ff:feb1:b717, 2a01:7e03::f03c:93ff:feb1:b707, + 2a01:7e03::f03c:93ff:feb1:b7ab, 2a01:7e03::f03c:93ff:feb1:b7e2, 2a01:7e03::f03c:93ff:feb1:b709, + 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, 2a01:7e03::f03c:93ff:feb1:b76e, + 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": + "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": + "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": + "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": + "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": + "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, + 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": + "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, 2600:3c00::8, + 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, + 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, + 74.207.241.5, 74.207.242.5", "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, + 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, + 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": + "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, + 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, + 50.116.41.5, 23.239.18.5", "ipv6": "2600:3c02::3, 2600:3c02::5, 2600:3c02::4, + 2600:3c02::6, 2600:3c02::c, 2600:3c02::7, 2600:3c02::2, 2600:3c02::9, 2600:3c02::8, + 2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": + "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, + 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, + 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, + 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": + "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": + "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, + 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, + 2a01:7e00::3, 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, + 2a01:7e00::4, 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, + 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, + 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "2400:8901::5, 2400:8901::4, + 2400:8901::b, 2400:8901::3, 2400:8901::9, 2400:8901::2, 2400:8901::8, 2400:8901::7, + 2400:8901::c, 2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 30}' + 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: + - Mon, 07 Oct 2024 14:56:09 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - '*' + 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":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-e5r0jt5hy380","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": 64970525, "label": "go-test-ins-wo-disk-e5r0jt5hy380", "group": + "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["194.195.117.161"], "ipv6": "2400:8904::f03c:95ff:fe8c:d6a6/128", + "image": null, "region": "ap-west", "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": "4ecff3e7ba293f448d05aad89062f4677f5065a3", "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: + - Mon, 07 Oct 2024 14:56:09 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: '{"label":"go-test-conf-8en09mw3l29s","devices":{},"interfaces":null}' + 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/64970525/configs + method: POST + response: + body: '{"id": 68259920, "label": "go-test-conf-8en09mw3l29s", "helpers": {"updatedb_disabled": + true, "distro": true, "modules_dep": true, "network": false, "devtmpfs_automount": + true}, "kernel": "linode/latest-64bit", "comments": "", "memory_limit": 0, "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "root_device": "/dev/sda", + "devices": {"sda": null, "sdb": null, "sdc": null, "sdd": null, "sde": null, + "sdf": null, "sdg": null, "sdh": null}, "initrd": null, "run_level": "default", + "virt_mode": "paravirt", "interfaces": []}' + 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: + - "540" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56: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: "" +- request: + body: '{"type":"ipv4","public":true,"reserved":true,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"address": "45.79.120.251", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-251.ip.linodeusercontent.com", + "linode_id": 64970525, "region": "ap-west", "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: + - Mon, 07 Oct 2024 14:56:10 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,"reserved":true,"region":"ap-west","linode_id":99999}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Linode is not active", "field": "linode_id"}]}' + 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: + - "70" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:10 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"reserved":true,"region":"ap-west"}' + 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/ips + method: POST + response: + body: '{"address": "45.79.120.253", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-253.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 14:56:12 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,"reserved":true,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Additional Reserved 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: + - "147" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:12 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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.120.251 + 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: + - Mon, 07 Oct 2024 14:56:12 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/45.79.120.253 + 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: + - Mon, 07 Oct 2024 14:56:12 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,"reserved":true,"linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"address": "45.79.120.253", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-253.ip.linodeusercontent.com", + "linode_id": 64970525, "region": "ap-west", "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: + - Mon, 07 Oct 2024 14:56:13 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: "" + 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.120.253 + 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: + - Mon, 07 Oct 2024 14:56: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: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"type":"ipv4","public":true,"reserved":true}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "A datacenter or a Linode must be provided when + reserving an 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: + - "96" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:14 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"reserved":true,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Cannot reserve a private address.", "field": "public"}]}' + 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: + - "80" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:14 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"address": "192.46.215.37", "gateway": "192.46.215.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-215-37.ip.linodeusercontent.com", + "linode_id": 64970525, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}' + 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: + - "267" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56: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: "" + 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/64970525/ips/192.46.215.37 + 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: + - Mon, 07 Oct 2024 14:56:14 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":true,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"address": "192.46.215.37", "gateway": "192.46.215.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-215-37.ip.linodeusercontent.com", + "linode_id": 64970525, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}' + 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: + - "267" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:15 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: "" + 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/64970525/ips/192.46.215.37 + 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: + - Mon, 07 Oct 2024 14:56:15 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":true,"region":"ap-west"}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Linode is a required argument when not reserving + an IP address.", "field": "linode_id"}]}' + 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: + - "113" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:15 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"region":"ap-west"}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Linode is a required argument when not reserving + an IP address.", "field": "linode_id"}]}' + 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: + - "113" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:15 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"reserved":true,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Only addresses of type ipv4 are currently supported."}]}' + 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: + - "80" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:15 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"region":"ap-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Only addresses of type ipv4 are currently supported."}]}' + 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: + - "80" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:16 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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,"reserved":true,"region":"us-west","linode_id":64970525}' + 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/ips + method: POST + response: + body: '{"errors": [{"reason": "Region passed in must match Linode''s region.", + "field": "region"}]}' + 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: + - "91" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 14:56:16 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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/linode/instances/64970525 + 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: + - Mon, 07 Oct 2024 14:56:18 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/TestIPAddress_Instance_ReserveIP_Assign.yaml b/test/integration/fixtures/TestIPAddress_Instance_ReserveIP_Assign.yaml new file mode 100644 index 000000000..fd5d19f79 --- /dev/null +++ b/test/integration/fixtures/TestIPAddress_Instance_ReserveIP_Assign.yaml @@ -0,0 +1,1372 @@ +--- +version: 1 +interactions: +- 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/regions?page=1 + method: GET + response: + body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.105.34.5, 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, + 172.105.39.5, 172.105.40.5, 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": + "2400:8904::f03c:91ff:fea5:659, 2400:8904::f03c:91ff:fea5:9282, 2400:8904::f03c:91ff:fea5:b9b3, + 2400:8904::f03c:91ff:fea5:925a, 2400:8904::f03c:91ff:fea5:22cb, 2400:8904::f03c:91ff:fea5:227a, + 2400:8904::f03c:91ff:fea5:924c, 2400:8904::f03c:91ff:fea5:f7e2, 2400:8904::f03c:91ff:fea5:2205, + 2400:8904::f03c:91ff:fea5:9207"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, + 172.105.5.5, 172.105.6.5, 172.105.7.5, 172.105.8.5, 172.105.9.5, 172.105.10.5, + 172.105.11.5", "ipv6": "2600:3c04::f03c:91ff:fea9:f63, 2600:3c04::f03c:91ff:fea9:f6d, + 2600:3c04::f03c:91ff:fea9:f80, 2600:3c04::f03c:91ff:fea9:f0f, 2600:3c04::f03c:91ff:fea9:f99, + 2600:3c04::f03c:91ff:fea9:fbd, 2600:3c04::f03c:91ff:fea9:fdd, 2600:3c04::f03c:91ff:fea9:fe2, + 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, + 172.105.168.5, 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, + 172.105.181.5, 172.105.161.5", "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, + 2400:8907::f03c:92ff:fe6e:1c58, 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, + 2400:8907::f03c:92ff:fe6e:c219, 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, + 2400:8907::f03c:92ff:fe6e:e6b, 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, + 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, + 139.144.192.68", "ipv6": "2600:3c05::f03c:93ff:feb6:43b6, 2600:3c05::f03c:93ff:feb6:4365, + 2600:3c05::f03c:93ff:feb6:43c2, 2600:3c05::f03c:93ff:feb6:e441, 2600:3c05::f03c:93ff:feb6:94ef, + 2600:3c05::f03c:93ff:feb6:94ba, 2600:3c05::f03c:93ff:feb6:94a8, 2600:3c05::f03c:93ff:feb6:9413, + 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, + 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", + "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, 2600:3c06::f03c:93ff:fed0:e572, + 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, 2600:3c06::f03c:93ff:fed0:e511, + 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, 2600:3c06::f03c:93ff:fed0:e529, + 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": + "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, + 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, + 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, + 2600:3c07::f03c:93ff:fef2:2ec7, 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, + 2600:3c07::f03c:93ff:fef2:0de0, 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, + 2600:3c07::f03c:93ff:fef2:0d82, 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, + 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, 172.232.160.11, + 172.232.160.14, 172.232.160.16", "ipv6": "2600:3c0a::f03c:93ff:fe54:c6da, 2600:3c0a::f03c:93ff:fe54:c691, + 2600:3c0a::f03c:93ff:fe54:c68d, 2600:3c0a::f03c:93ff:fe54:c61e, 2600:3c0a::f03c:93ff:fe54:c653, + 2600:3c0a::f03c:93ff:fe54:c64c, 2600:3c0a::f03c:93ff:fe54:c68a, 2600:3c0a::f03c:93ff:fe54:c697, + 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, 172.233.0.7, + 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, 172.233.0.8, + 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, 2600:3c0d::f03c:93ff:fe3d:51a7, + 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, 2600:3c0d::f03c:93ff:fe3d:51fe, + 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, 2600:3c0d::f03c:93ff:fe3d:5170, + 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, + 172.233.33.34, 172.233.33.33, 172.233.33.31, 172.233.33.30, 172.233.33.37, 172.233.33.32", + "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, + 2600:3c0e::f03c:93ff:fe9d:2d96, 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, + 2600:3c0e::f03c:93ff:fe9d:2d68, 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, + 2600:3c0e::f03c:93ff:fe9d:2d5c"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "se-sto", "label": + "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, + 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, + 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, 2600:3c09::f03c:93ff:fea9:4d63, + 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, 2600:3c09::f03c:93ff:fea9:4d99, + 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, 2600:3c09::f03c:93ff:fea9:4d69, + 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, + 172.233.111.25, 172.233.111.19, 172.233.111.12, 172.233.111.26, 172.233.111.16, + 172.233.111.18, 172.233.111.9", "ipv6": "2a01:7e02::f03c:93ff:feea:b585, 2a01:7e02::f03c:93ff:feea:b5ab, + 2a01:7e02::f03c:93ff:feea:b5c6, 2a01:7e02::f03c:93ff:feea:b592, 2a01:7e02::f03c:93ff:feea:b5aa, + 2a01:7e02::f03c:93ff:feea:b5d3, 2a01:7e02::f03c:93ff:feea:b5d7, 2a01:7e02::f03c:93ff:feea:b528, + 2a01:7e02::f03c:93ff:feea:b522, 2a01:7e02::f03c:93ff:feea:b51a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": "in", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, + 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", + "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, + 2600:3c08::f03c:93ff:fe7c:11a7, 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, + 2600:3c08::f03c:93ff:fe7c:11f9, 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, + 2600:3c08::f03c:93ff:fe7c:1164"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": + "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, + 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, + 172.233.64.42, 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, + 2400:8905::f03c:93ff:fe9d:b012, 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, + 2400:8905::f03c:93ff:fe9d:259f, 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, + 2400:8905::f03c:93ff:fe9d:b0ce, 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": + "it", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, + 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", + "ipv6": "2600:3c0b::f03c:93ff:feba:d513, 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, + 2600:3c0b::f03c:93ff:feba:d5fb, 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, + 2600:3c0b::f03c:93ff:feba:d5d5, 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, + 2600:3c0b::f03c:93ff:feba:d529"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": + "Miami, FL", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, + 172.233.160.29, 172.233.160.32, 172.233.160.28, 172.233.160.33, 172.233.160.26, + 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, 2a01:7e04::f03c:93ff:fead:d37f, + 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, 2a01:7e04::f03c:93ff:fead:d316, + 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, 2a01:7e04::f03c:93ff:fead:d395, + 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, + 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, + 172.232.224.31, 172.232.224.28", "ipv6": "2600:3c0c::f03c:93ff:feed:a90b, 2600:3c0c::f03c:93ff:feed:a9a5, + 2600:3c0c::f03c:93ff:feed:a935, 2600:3c0c::f03c:93ff:feed:a930, 2600:3c0c::f03c:93ff:feed:a95c, + 2600:3c0c::f03c:93ff:feed:a9ad, 2600:3c0c::f03c:93ff:feed:a9f2, 2600:3c0c::f03c:93ff:feed:a9ff, + 2600:3c0c::f03c:93ff:feed:a9c8, 2600:3c0c::f03c:93ff:feed:a96b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": + ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, + 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, 172.233.128.44", + "ipv6": "2a01:7e03::f03c:93ff:feb1:b789, 2a01:7e03::f03c:93ff:feb1:b717, 2a01:7e03::f03c:93ff:feb1:b707, + 2a01:7e03::f03c:93ff:feb1:b7ab, 2a01:7e03::f03c:93ff:feb1:b7e2, 2a01:7e03::f03c:93ff:feb1:b709, + 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, 2a01:7e03::f03c:93ff:feb1:b76e, + 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": + "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": + "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": + "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": + "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": + "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, + 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": + "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, 2600:3c00::8, + 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, + 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, + 74.207.241.5, 74.207.242.5", "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, + 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, + 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": + "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, + 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, + 50.116.41.5, 23.239.18.5", "ipv6": "2600:3c02::3, 2600:3c02::5, 2600:3c02::4, + 2600:3c02::6, 2600:3c02::c, 2600:3c02::7, 2600:3c02::2, 2600:3c02::9, 2600:3c02::8, + 2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": + "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, + 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, + 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, + 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": + "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": + "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, + 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, + 2a01:7e00::3, 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, + 2a01:7e00::4, 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, + 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, + 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "2400:8901::5, 2400:8901::4, + 2400:8901::b, 2400:8901::3, 2400:8901::9, 2400:8901::2, 2400:8901::8, 2400:8901::7, + 2400:8901::c, 2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 30}' + 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: + - Mon, 07 Oct 2024 15:04:08 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - '*' + 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":"ap-west","type":"g6-nanode-1","label":"go-test-ins-2ge1w3qzo876","root_pass":"Gefk==`[4354ke9Y+xHI6aJ(lPmir`/\\]mM:Xm+]k05~2#C@7wgA7MZ4U8407JXV","image":"linode/debian9","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": 64971153, "label": "go-test-ins-2ge1w3qzo876", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.79.123.50"], "ipv6": "2400:8904::f03c:95ff:fe8c:79f4/128", + "image": "linode/debian9", "region": "ap-west", "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": "4ecff3e7ba293f448d05aad89062f4677f5065a3", "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: + - Mon, 07 Oct 2024 15:04:14 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":"ap-west","type":"g6-nanode-1","label":"go-test-ins-h2v93y4i6ar8","root_pass":"\\Y[006!O26SlTJ18)IsF,3@u{Dv8TM1[\u003c!zv$8t.IA2ahhi|e+GIj*1L5ib,8f8A","image":"linode/debian9","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": 64971155, "label": "go-test-ins-h2v93y4i6ar8", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.79.123.74"], "ipv6": "2400:8904::f03c:95ff:fe8c:790f/128", + "image": "linode/debian9", "region": "ap-west", "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": "64f3e61b2e736f99ca5f41dd36bbc57071b08d42", "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: + - Mon, 07 Oct 2024 15:04: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: '{"region":"ap-west"}' + 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.52.41", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-41.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 15:04:15 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":"ap-west","assignments":[{"address":"172.105.52.41","linode_id":64971153}]}' + 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/ips/assign + method: POST + 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: + - Mon, 07 Oct 2024 15:04:16 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: "" + 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/ips/172.105.52.41 + method: GET + response: + body: '{"address": "172.105.52.41", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-41.ip.linodeusercontent.com", + "linode_id": 64971153, "region": "ap-west", "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: + - "266" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 15:04:16 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips: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: '{"region":"ap-west"}' + 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": "192.46.209.84", "gateway": "192.46.209.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-209-84.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 15:04:16 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":"ap-west","assignments":[{"address":"192.46.209.84","linode_id":64971153}]}' + 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/ips/assign + method: POST + 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: + - Mon, 07 Oct 2024 15:04:16 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":"ap-west","assignments":[{"address":"192.46.209.84","linode_id":64971155}]}' + 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/ips/assign + method: POST + 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: + - Mon, 07 Oct 2024 15:04: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: + - "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/ips/192.46.209.84 + method: GET + response: + body: '{"address": "192.46.209.84", "gateway": "192.46.209.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-209-84.ip.linodeusercontent.com", + "linode_id": 64971155, "region": "ap-west", "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: + - "266" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 15:04:17 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips: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/192.46.209.84 + 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: + - Mon, 07 Oct 2024 15:04: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: "" +- request: + body: '{"region":"ap-west","assignments":[{"address":"192.0.2.1","linode_id":64971153}]}' + 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/ips/assign + method: POST + response: + body: '{"errors": [{"reason": "IP Address 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: + - "49" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 15:04:17 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"ap-west"}' + 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": "192.46.209.91", "gateway": "192.46.209.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-209-91.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 15:04: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":"ap-west","assignments":[{"address":"192.46.209.91","linode_id":99999}]}' + 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/ips/assign + method: POST + response: + body: '{"errors": [{"reason": "Invalid Linode ID 99999"}]}' + 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: + - "51" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 15:04:18 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips: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/192.46.209.91 + 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: + - Mon, 07 Oct 2024 15:04: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: + - "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/172.105.52.41 + 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: + - Mon, 07 Oct 2024 15:04: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: + - "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/64971155 + 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: + - Mon, 07 Oct 2024 15:04:20 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/64971153 + 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: + - Mon, 07 Oct 2024 15:04:23 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/TestIPAddress_Update.yaml b/test/integration/fixtures/TestIPAddress_Update.yaml index 1843cad2e..483422079 100644 --- a/test/integration/fixtures/TestIPAddress_Update.yaml +++ b/test/integration/fixtures/TestIPAddress_Update.yaml @@ -15,262 +15,279 @@ interactions: method: GET response: body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata"], "status": "ok", "resolvers": {"ipv4": "172.105.34.5, 172.105.35.5, - 172.105.36.5, 172.105.37.5, 172.105.38.5, 172.105.39.5, 172.105.40.5, 172.105.41.5, - 172.105.42.5, 172.105.43.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "ca-central", "label": "Toronto, CA", "country": "ca", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.105.34.5, 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, + 172.105.39.5, 172.105.40.5, 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": + "2400:8904::f03c:91ff:fea5:659, 2400:8904::f03c:91ff:fea5:9282, 2400:8904::f03c:91ff:fea5:b9b3, + 2400:8904::f03c:91ff:fea5:925a, 2400:8904::f03c:91ff:fea5:22cb, 2400:8904::f03c:91ff:fea5:227a, + 2400:8904::f03c:91ff:fea5:924c, 2400:8904::f03c:91ff:fea5:f7e2, 2400:8904::f03c:91ff:fea5:2205, + 2400:8904::f03c:91ff:fea5:9207"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, 172.105.5.5, 172.105.6.5, 172.105.7.5, 172.105.8.5, 172.105.9.5, 172.105.10.5, - 172.105.11.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + 172.105.11.5", "ipv6": "2600:3c04::f03c:91ff:fea9:f63, 2600:3c04::f03c:91ff:fea9:f6d, + 2600:3c04::f03c:91ff:fea9:f80, 2600:3c04::f03c:91ff:fea9:f0f, 2600:3c04::f03c:91ff:fea9:f99, + 2600:3c04::f03c:91ff:fea9:fbd, 2600:3c04::f03c:91ff:fea9:fdd, 2600:3c04::f03c:91ff:fea9:fe2, + 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, 172.105.168.5, - 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, 172.105.181.5, - 172.105.161.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, + 172.105.168.5, 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, + 172.105.181.5, 172.105.161.5", "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, + 2400:8907::f03c:92ff:fe6e:1c58, 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, + 2400:8907::f03c:92ff:fe6e:c219, 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, + 2400:8907::f03c:92ff:fe6e:e6b, 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans"], "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, - 139.144.192.61, 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, - 139.144.192.66, 139.144.192.52, 139.144.192.68", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": - "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, + 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, + 139.144.192.68", "ipv6": "2600:3c05::f03c:93ff:feb6:43b6, 2600:3c05::f03c:93ff:feb6:4365, + 2600:3c05::f03c:93ff:feb6:43c2, 2600:3c05::f03c:93ff:feb6:e441, 2600:3c05::f03c:93ff:feb6:94ef, + 2600:3c05::f03c:93ff:feb6:94ba, 2600:3c05::f03c:93ff:feb6:94a8, 2600:3c05::f03c:93ff:feb6:9413, + 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": - "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "status": - "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, 172.232.32.17, 172.232.32.18, - 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, 172.232.32.11, 172.232.32.12", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-sea", "label": - "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, 2600:3c06::f03c:93ff:fed0:e572, + 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, 2600:3c06::f03c:93ff:fed0:e511, + 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, 2600:3c06::f03c:93ff:fed0:e529, + 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": + "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, + 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, + 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, + 2600:3c07::f03c:93ff:fef2:2ec7, 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, + 2600:3c07::f03c:93ff:fef2:0de0, 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, + 2600:3c07::f03c:93ff:fef2:0d82, 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, 172.232.160.15, 172.232.160.18, - 172.232.160.8, 172.232.160.12, 172.232.160.11, 172.232.160.14, 172.232.160.16", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "br-gru", "label": - "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.233.0.4, 172.233.0.9, 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, - 172.233.0.10, 172.233.0.6, 172.233.0.8, 172.233.0.11", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": - "nl", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, - 172.233.33.35, 172.233.33.39, 172.233.33.34, 172.233.33.33, 172.233.33.31, 172.233.33.30, - 172.233.33.37, 172.233.33.32", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": "se", "capabilities": + "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, + 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, 172.232.160.11, + 172.232.160.14, 172.232.160.16", "ipv6": "2600:3c0a::f03c:93ff:fe54:c6da, 2600:3c0a::f03c:93ff:fe54:c691, + 2600:3c0a::f03c:93ff:fe54:c68d, 2600:3c0a::f03c:93ff:fe54:c61e, 2600:3c0a::f03c:93ff:fe54:c653, + 2600:3c0a::f03c:93ff:fe54:c64c, 2600:3c0a::f03c:93ff:fe54:c68a, 2600:3c0a::f03c:93ff:fe54:c697, + 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, 172.232.128.22, - 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, 172.232.128.21, - 172.232.128.27", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, 172.233.0.7, + 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, 172.233.0.8, + 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, 2600:3c0d::f03c:93ff:fe3d:51a7, + 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, 2600:3c0d::f03c:93ff:fe3d:51fe, + 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, 2600:3c0d::f03c:93ff:fe3d:5170, + 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, + 172.233.33.34, 172.233.33.33, 172.233.33.31, 172.233.33.30, 172.233.33.37, 172.233.33.32", + "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, + 2600:3c0e::f03c:93ff:fe9d:2d96, 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, + 2600:3c0e::f03c:93ff:fe9d:2d68, 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, + 2600:3c0e::f03c:93ff:fe9d:2d5c"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "se-sto", "label": + "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, + 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, + 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, 2600:3c09::f03c:93ff:fea9:4d63, + 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, 2600:3c09::f03c:93ff:fea9:4d99, + 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, 2600:3c09::f03c:93ff:fea9:4d69, + 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, 172.233.111.25, - 172.233.111.19, 172.233.111.12, 172.233.111.26, 172.233.111.16, 172.233.111.18, - 172.233.111.9", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, + 172.233.111.25, 172.233.111.19, 172.233.111.12, 172.233.111.26, 172.233.111.16, + 172.233.111.18, 172.233.111.9", "ipv6": "2a01:7e02::f03c:93ff:feea:b585, 2a01:7e02::f03c:93ff:feea:b5ab, + 2a01:7e02::f03c:93ff:feea:b5c6, 2a01:7e02::f03c:93ff:feea:b592, 2a01:7e02::f03c:93ff:feea:b5aa, + 2a01:7e02::f03c:93ff:feea:b5d3, 2a01:7e02::f03c:93ff:feea:b5d7, 2a01:7e02::f03c:93ff:feea:b528, + 2a01:7e02::f03c:93ff:feea:b522, 2a01:7e02::f03c:93ff:feea:b51a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": "in", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": - "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.233.64.44, 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, - 172.233.64.41, 172.233.64.39, 172.233.64.42, 172.233.64.45, 172.233.64.38", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "it-mil", "label": - "Milan, IT", "country": "it", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, + 2600:3c08::f03c:93ff:fe7c:11a7, 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, + 2600:3c08::f03c:93ff:fe7c:11f9, 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, + 2600:3c08::f03c:93ff:fe7c:1164"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": + "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, + 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, + 172.233.64.42, 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, + 2400:8905::f03c:93ff:fe9d:b012, 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, + 2400:8905::f03c:93ff:fe9d:259f, 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, + 2400:8905::f03c:93ff:fe9d:b0ce, 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": + "it", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, + "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": + "ipv6": "2600:3c0b::f03c:93ff:feba:d513, 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, + 2600:3c0b::f03c:93ff:feba:d5fb, 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, + 2600:3c0b::f03c:93ff:feba:d5d5, 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, + 2600:3c0b::f03c:93ff:feba:d529"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, - 172.233.160.28, 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "id-cgk", "label": - "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.232.224.23, 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, - 172.232.224.24, 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-lax", "label": - "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, + 172.233.160.29, 172.233.160.32, 172.233.160.28, 172.233.160.33, 172.233.160.26, + 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, 2a01:7e04::f03c:93ff:fead:d37f, + 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, 2a01:7e04::f03c:93ff:fead:d316, + 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, 2a01:7e04::f03c:93ff:fead:d395, + 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, + 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, + 172.232.224.31, 172.232.224.28", "ipv6": "2600:3c0c::f03c:93ff:feed:a90b, 2600:3c0c::f03c:93ff:feed:a9a5, + 2600:3c0c::f03c:93ff:feed:a935, 2600:3c0c::f03c:93ff:feed:a930, 2600:3c0c::f03c:93ff:feed:a95c, + 2600:3c0c::f03c:93ff:feed:a9ad, 2600:3c0c::f03c:93ff:feed:a9f2, 2600:3c0c::f03c:93ff:feed:a9ff, + 2600:3c0c::f03c:93ff:feed:a9c8, 2600:3c0c::f03c:93ff:feed:a96b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": + ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, + "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, 172.233.128.44", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": + "ipv6": "2a01:7e03::f03c:93ff:feb1:b789, 2a01:7e03::f03c:93ff:feb1:b717, 2a01:7e03::f03c:93ff:feb1:b707, + 2a01:7e03::f03c:93ff:feb1:b7ab, 2a01:7e03::f03c:93ff:feb1:b7e2, 2a01:7e03::f03c:93ff:feb1:b709, + 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, 2a01:7e03::f03c:93ff:feb1:b76e, + 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.236.0.46, 172.236.0.50, - 172.236.0.47, 172.236.0.53, 172.236.0.52, 172.236.0.45, 172.236.0.49, 172.236.0.51, - 172.236.0.54, 172.236.0.48", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.236.32.23, 172.236.32.35, 172.236.32.30, 172.236.32.28, 172.236.32.32, - 172.236.32.33, 172.236.32.27, 172.236.32.37, 172.236.32.29, 172.236.32.34", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-central", - "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": + "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": + "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": + "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": + "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": + "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, 2600:3c00::8, + 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, 173.230.155.5, - 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, - 74.207.242.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": - "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": - {"ipv4": "74.207.231.5, 173.230.128.5, 173.230.129.5, 173.230.136.5, 173.230.140.5, - 66.228.59.5, 66.228.62.5, 50.116.35.5, 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, + 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, + 74.207.241.5, 74.207.242.5", "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, + 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, + 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": + "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, + 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, + 50.116.41.5, 23.239.18.5", "ipv6": "2600:3c02::3, 2600:3c02::5, 2600:3c02::4, + 2600:3c02::6, 2600:3c02::c, 2600:3c02::7, 2600:3c02::2, 2600:3c02::9, 2600:3c02::8, + 2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], "status": - "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, - 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, 207.192.69.5", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata"], - "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, - 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, 109.74.192.20, 109.74.193.20, - 109.74.194.20", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-south", "label": "Singapore, SG", "country": - "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": - {"ipv4": "139.162.11.5, 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, - 139.162.21.5, 139.162.27.5, 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU - Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5, - 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, 139.162.135.5, 139.162.136.5, - 139.162.137.5, 139.162.138.5, 139.162.139.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 100, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", - "label": "Tokyo, JP", "country": "jp", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata"], "status": "ok", "resolvers": - {"ipv4": "139.162.66.5, 139.162.67.5, 139.162.68.5, 139.162.69.5, 139.162.70.5, - 139.162.71.5, 139.162.72.5, 139.162.73.5, 139.162.74.5, 139.162.75.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg": 5}, "site_type": - "core"}], "page": 1, "pages": 1, "results": 27}' + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, + 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, + 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, + 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": + "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": + "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, + 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, + 2a01:7e00::3, 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, + 2a01:7e00::4, 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, + 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, + 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "2400:8901::5, 2400:8901::4, + 2400:8901::b, 2400:8901::3, 2400:8901::9, 2400:8901::2, 2400:8901::8, 2400:8901::7, + 2400:8901::c, 2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 30}' headers: Access-Control-Allow-Credentials: - "true" @@ -282,6 +299,8 @@ interactions: - '*' 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: @@ -291,7 +310,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:50 GMT + - Mon, 07 Oct 2024 16:10:13 GMT Pragma: - no-cache Strict-Transport-Security: @@ -310,14 +329,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-9ry433z3jee3","firewall_id":640265,"booted":false}' + body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-1xza1u1t95z0","booted":false}' form: {} headers: Accept: @@ -329,16 +348,17 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61169669, "label": "go-test-ins-wo-disk-9ry433z3jee3", "group": + body: '{"id": 64975249, "label": "go-test-ins-wo-disk-1xza1u1t95z0", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.105.55.85"], "ipv6": "1234::5678/128", - "image": null, "region": "ap-west", "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": - true, "available": false, "schedule": {"day": null, "window": null}, "last_successful": - null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": - "aeb2357ce09e1cb483d94ee0d025f3b254c93dfc", "has_user_data": false, "placement_group": - null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["45.79.123.50"], "ipv6": "2400:8904::f03c:95ff:fe8c:08e4/128", + "image": null, "region": "ap-west", "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": "915afd6c961c0333afa335a52a655d656beae128", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -350,18 +370,20 @@ interactions: - '*' 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: - - "785" + - "857" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:50 GMT + - Mon, 07 Oct 2024 16:10:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -385,7 +407,7 @@ interactions: code: 200 duration: "" - request: - body: '{"label":"go-test-conf-0q81y862eien","devices":{},"interfaces":null}' + body: '{"label":"go-test-conf-iz7ha58g3b23","devices":{},"interfaces":null}' form: {} headers: Accept: @@ -394,11 +416,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61169669/configs + url: https://api.linode.com/v4beta/linode/instances/64975249/configs method: POST response: - body: '{"id": 64385522, "label": "go-test-conf-0q81y862eien", "helpers": {"updatedb_disabled": - true, "distro": true, "modules_dep": true, "network": true, "devtmpfs_automount": + body: '{"id": 68264745, "label": "go-test-conf-iz7ha58g3b23", "helpers": {"updatedb_disabled": + true, "distro": true, "modules_dep": true, "network": false, "devtmpfs_automount": true}, "kernel": "linode/latest-64bit", "comments": "", "memory_limit": 0, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "root_device": "/dev/sda", "devices": {"sda": null, "sdb": null, "sdc": null, "sdd": null, "sde": null, @@ -415,18 +437,20 @@ interactions: - '*' 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: - - "539" + - "540" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:51 GMT + - Mon, 07 Oct 2024 16:10:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -443,7 +467,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -459,19 +483,19 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61169669/ips + url: https://api.linode.com/v4beta/linode/instances/64975249/ips method: GET response: - body: '{"ipv4": {"public": [{"address": "172.105.55.85", "gateway": "172.105.55.1", + body: '{"ipv4": {"public": [{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, - "rdns": "172-105-55-85.ip.linodeusercontent.com", "linode_id": 61169669, "region": - "ap-west", "vpc_nat_1_1": null}], "private": [], "shared": [], "reserved": [], - "vpc": []}, "ipv6": {"slaac": {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 61169669, "region": "ap-west", "public": - true}, "link_local": {"address": "1234::5678", "gateway": "1234::5678", - "subnet_mask": "1234::5678", "prefix": 64, "type": "ipv6", "rdns": - null, "linode_id": 61169669, "region": "ap-west", "public": false}, "global": + "rdns": "45-79-123-50.ip.linodeusercontent.com", "linode_id": 64975249, "region": + "ap-west", "vpc_nat_1_1": null, "reserved": false}], "private": [], "shared": + [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2400:8904::f03c:95ff:fe8c:08e4", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 64975249, "region": "ap-west", "public": + true}, "link_local": {"address": "fe80::f03c:95ff:fe8c:08e4", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 64975249, "region": "ap-west", "public": false}, "global": []}}' headers: Access-Control-Allow-Credentials: @@ -484,18 +508,20 @@ interactions: - '*' 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: - - "797" + - "813" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:51 GMT + - Mon, 07 Oct 2024 16:10:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -513,14 +539,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"rdns":"172-105-55-85.ip.linodeusercontent.com"}' + body: '{"reserved":false,"rdns":"45-79-123-50.ip.linodeusercontent.com"}' form: {} headers: Accept: @@ -529,12 +555,13 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.55.85 + url: https://api.linode.com/v4beta/networking/ips/45.79.123.50 method: PUT response: - body: '{"address": "172.105.55.85", "gateway": "172.105.55.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-55-85.ip.linodeusercontent.com", - "linode_id": 61169669, "region": "ap-west", "vpc_nat_1_1": null}' + body: '{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-123-50.ip.linodeusercontent.com", + "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}' headers: Access-Control-Allow-Credentials: - "true" @@ -546,18 +573,20 @@ interactions: - '*' 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: - - "248" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:51 GMT + - Mon, 07 Oct 2024 16:10:15 GMT Pragma: - no-cache Strict-Transport-Security: @@ -574,14 +603,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: "" + body: '{"reserved":true}' form: {} headers: Accept: @@ -590,10 +619,266 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61169669 - method: DELETE + url: https://api.linode.com/v4beta/networking/ips/45.79.123.50 + method: PUT response: - body: '{}' + body: '{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-123-50.ip.linodeusercontent.com", + "linode_id": 64975249, "region": "ap-west", "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: + - "263" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:15 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":"ap-west"}' + 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.120.251", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-251.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 16:10:15 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: '{"reserved":true}' + 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/ips/45.79.120.251 + method: PUT + response: + body: '{"address": "45.79.120.251", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-251.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 16:10:15 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: '{"reserved":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/networking/ips/45.79.123.50 + method: PUT + response: + body: '{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-123-50.ip.linodeusercontent.com", + "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}' + 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: + - Mon, 07 Oct 2024 16:10:16 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":"ap-west"}' + 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.120.253", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-253.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: - "true" @@ -605,6 +890,959 @@ interactions: - '*' 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: + - Mon, 07 Oct 2024 16:10:16 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":"ap-west","assignments":[{"address":"45.79.120.253","linode_id":64975249}]}' + 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/ips/assign + method: POST + 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: + - Mon, 07 Oct 2024 16:10:16 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: '{"reserved":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/networking/ips/45.79.120.253 + method: PUT + response: + body: '{"address": "45.79.120.253", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-253.ip.linodeusercontent.com", + "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}' + 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: + - "266" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10: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: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"ap-west"}' + 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.52.26", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-26.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 16:10: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: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"reserved":true,"rdns":"sample rdns"}' + 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/ips/172.105.52.26 + method: PUT + response: + body: '{"errors": [{"reason": "Domain is not valid.", "field": "rdns"}]}' + 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: + - "65" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:17 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"region":"ap-west"}' + 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: '{"errors": [{"reason": "Additional Reserved 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: + - "147" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:17 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"reserved":true}' + 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/ips/ + method: PUT + response: + body: '{"errors": [{"reason": "Method Not Allowed"}]}' + 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: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Content-Length: + - "46" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:17 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - '*' + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - unknown + status: 405 Method Not Allowed + code: 405 + 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.52.26 + 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: + - Mon, 07 Oct 2024 16:10: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: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"ap-west"}' + 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.52.110", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-110.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 16:10: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: '{"reserved":true}' + 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/ips/172.105.52.110 + method: PUT + response: + body: '{"address": "172.105.52.110", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-110.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 16:10: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: "" + 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.52.110 + 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: + - Mon, 07 Oct 2024 16:10: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: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"ap-west"}' + 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.52.41", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-41.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "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: + - Mon, 07 Oct 2024 16:10:19 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: '{"reserved":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/networking/ips/172.105.52.41 + method: PUT + response: + body: '{"address": "172.105.52.41", "gateway": "172.105.52.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-41.ip.linodeusercontent.com", + "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' + 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: + - "263" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:19 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: "" + 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/ips/172.105.52.41 + method: GET + 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 + Connection: + - keep-alive + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:19 GMT + Pragma: + - no-cache + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips:read_only + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 404 Not Found + code: 404 + duration: "" +- request: + body: '{"reserved":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/networking/ips/123.72.121.76 + method: PUT + 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: + - Mon, 07 Oct 2024 16:10:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + status: 404 Not Found + code: 404 + 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.120.253 + method: DELETE + 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 + Connection: + - keep-alive + Content-Length: + - "37" + Content-Type: + - application/json + Expires: + - Mon, 07 Oct 2024 16:10:19 GMT + Pragma: + - no-cache + X-Accepted-Oauth-Scopes: + - ips:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + status: 404 Not Found + code: 404 + 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.120.251 + 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: + - Mon, 07 Oct 2024 16:10:20 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/64975249 + 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: @@ -616,7 +1854,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 08 Jul 2024 13:31:51 GMT + - Mon, 07 Oct 2024 16:10:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -633,7 +1871,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestIPAddresses_List.yaml b/test/integration/fixtures/TestIPAddresses_List.yaml index b1d022faf..8fc1e9bc1 100644 --- a/test/integration/fixtures/TestIPAddresses_List.yaml +++ b/test/integration/fixtures/TestIPAddresses_List.yaml @@ -15,293 +15,278 @@ interactions: method: GET response: body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.34.5, - 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, 172.105.39.5, 172.105.40.5, - 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ca-central", "label": "Toronto, CA", "country": - "ca", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": - "172.105.0.5, 172.105.3.5, 172.105.4.5, 172.105.5.5, 172.105.6.5, 172.105.7.5, - 172.105.8.5, 172.105.9.5, 172.105.10.5, 172.105.11.5", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": - "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": - "172.105.166.5, 172.105.169.5, 172.105.168.5, 172.105.172.5, 172.105.162.5, - 172.105.170.5, 172.105.167.5, 172.105.171.5, 172.105.181.5, 172.105.161.5", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-iad", "label": - "Washington, DC", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, - 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, - 139.144.192.52, 139.144.192.68", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.105.34.5, 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, + 172.105.39.5, 172.105.40.5, 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": + "2400:8904::f03c:91ff:fea5:659, 2400:8904::f03c:91ff:fea5:9282, 2400:8904::f03c:91ff:fea5:b9b3, + 2400:8904::f03c:91ff:fea5:925a, 2400:8904::f03c:91ff:fea5:22cb, 2400:8904::f03c:91ff:fea5:227a, + 2400:8904::f03c:91ff:fea5:924c, 2400:8904::f03c:91ff:fea5:f7e2, 2400:8904::f03c:91ff:fea5:2205, + 2400:8904::f03c:91ff:fea5:9207"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, + 172.105.5.5, 172.105.6.5, 172.105.7.5, 172.105.8.5, 172.105.9.5, 172.105.10.5, + 172.105.11.5", "ipv6": "2600:3c04::f03c:91ff:fea9:f63, 2600:3c04::f03c:91ff:fea9:f6d, + 2600:3c04::f03c:91ff:fea9:f80, 2600:3c04::f03c:91ff:fea9:f0f, 2600:3c04::f03c:91ff:fea9:f99, + 2600:3c04::f03c:91ff:fea9:fbd, 2600:3c04::f03c:91ff:fea9:fdd, 2600:3c04::f03c:91ff:fea9:fe2, + 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud + Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, + 172.105.168.5, 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, + 172.105.181.5, 172.105.161.5", "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, + 2400:8907::f03c:92ff:fe6e:1c58, 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, + 2400:8907::f03c:92ff:fe6e:c219, 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, + 2400:8907::f03c:92ff:fe6e:e6b, 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", + "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, + 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, + 139.144.192.68", "ipv6": "2600:3c05::f03c:93ff:feb6:43b6, 2600:3c05::f03c:93ff:feb6:4365, + 2600:3c05::f03c:93ff:feb6:43c2, 2600:3c05::f03c:93ff:feb6:e441, 2600:3c05::f03c:93ff:feb6:94ef, + 2600:3c05::f03c:93ff:feb6:94ba, 2600:3c05::f03c:93ff:feb6:94a8, 2600:3c05::f03c:93ff:feb6:9413, + 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU - Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, - 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", "ipv6": - "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, + 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", + "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, 2600:3c06::f03c:93ff:fed0:e572, + 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, 2600:3c06::f03c:93ff:fed0:e511, + 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, 2600:3c06::f03c:93ff:fed0:e529, + 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": - "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, + 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, + 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, + 2600:3c07::f03c:93ff:fef2:2ec7, 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, + 2600:3c07::f03c:93ff:fef2:0de0, 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, + 2600:3c07::f03c:93ff:fef2:0d82, 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, - 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, - 172.232.32.11, 172.232.32.12", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": + "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, + 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, 172.232.160.11, + 172.232.160.14, 172.232.160.16", "ipv6": "2600:3c0a::f03c:93ff:fe54:c6da, 2600:3c0a::f03c:93ff:fe54:c691, + 2600:3c0a::f03c:93ff:fe54:c68d, 2600:3c0a::f03c:93ff:fe54:c61e, 2600:3c0a::f03c:93ff:fe54:c653, + 2600:3c0a::f03c:93ff:fe54:c64c, 2600:3c0a::f03c:93ff:fe54:c68a, 2600:3c0a::f03c:93ff:fe54:c697, + 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU - Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium - Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.160.19, - 172.232.160.21, 172.232.160.17, 172.232.160.15, 172.232.160.18, 172.232.160.8, - 172.232.160.12, 172.232.160.11, 172.232.160.14, 172.232.160.16", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": - "br", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.0.4, - 172.233.0.9, 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, - 172.233.0.6, 172.233.0.8, 172.233.0.11", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": - "nl", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, 172.233.0.7, + 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, 172.233.0.8, + 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, 2600:3c0d::f03c:93ff:fe3d:51a7, + 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, 2600:3c0d::f03c:93ff:fe3d:51fe, + 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, 2600:3c0d::f03c:93ff:fe3d:5170, + 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, 172.233.33.34, 172.233.33.33, 172.233.33.31, - 172.233.33.30, 172.233.33.37, 172.233.33.32", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, + 172.233.33.30, 172.233.33.37, 172.233.33.32", "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, + 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, 2600:3c0e::f03c:93ff:fe9d:2d96, + 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, 2600:3c0e::f03c:93ff:fe9d:2d68, + 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, 2600:3c0e::f03c:93ff:fe9d:2d5c"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, 172.232.128.22, 172.232.128.25, 172.232.128.19, - 172.232.128.23, 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, + 172.232.128.23, 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, + 2600:3c09::f03c:93ff:fea9:4d63, 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, + 2600:3c09::f03c:93ff:fea9:4d99, 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, + 2600:3c09::f03c:93ff:fea9:4d69, 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, 172.233.111.25, 172.233.111.19, 172.233.111.12, - 172.233.111.26, 172.233.111.16, 172.233.111.18, 172.233.111.9", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, + 172.233.111.26, 172.233.111.16, 172.233.111.18, 172.233.111.9", "ipv6": "2a01:7e02::f03c:93ff:feea:b585, + 2a01:7e02::f03c:93ff:feea:b5ab, 2a01:7e02::f03c:93ff:feea:b5c6, 2a01:7e02::f03c:93ff:feea:b592, + 2a01:7e02::f03c:93ff:feea:b5aa, 2a01:7e02::f03c:93ff:feea:b5d3, 2a01:7e02::f03c:93ff:feea:b5d7, + 2a01:7e02::f03c:93ff:feea:b528, 2a01:7e02::f03c:93ff:feea:b522, 2a01:7e02::f03c:93ff:feea:b51a"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": - "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.96.17, - 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, - 172.232.96.22, 172.232.96.23, 172.232.96.24", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "jp-osa", "label": "Osaka, JP", "country": - "jp", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.64.44, 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, - 172.233.64.41, 172.233.64.39, 172.233.64.42, 172.233.64.45, 172.233.64.38", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "it-mil", "label": - "Milan, IT", "country": "it", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "in", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, - 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": - "Miami, FL", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, - 172.233.160.28, 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "id-cgk", "label": - "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, - 172.232.224.24, 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-lax", "label": - "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, - 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, 172.233.128.44", - "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-den-edge-1", - "label": "Edge - Denver, CO", "country": "us", "capabilities": ["Linodes", "Cloud - Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "de-ham-edge-1", - "label": "Edge - Hamburg, DE", "country": "de", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "fr-mrs-edge-1", - "label": "Edge - Marseille, FR", "country": "fr", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "za-jnb-edge-1", - "label": "Edge - Johannesburg, ZA\t", "country": "za", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "my-kul-edge-1", - "label": "Edge - Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "co-bog-edge-1", - "label": "Edge - Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "mx-qro-edge-1", - "label": "Edge - Quer\u00e9taro, MX", "country": "mx", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "us-hou-edge-1", - "label": "Edge - Houston, TX", "country": "us", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "cl-scl-edge-1", - "label": "Edge - Santiago, CL", "country": "cl", "capabilities": ["Linodes", - "Cloud Firewall", "Distributed Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53, 173.223.101.53", "ipv6": "1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "distributed"}, {"id": "us-central", - "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, - 96.126.122.5, 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": + {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, + 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", + "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, + 2600:3c08::f03c:93ff:fe7c:11a7, 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, + 2600:3c08::f03c:93ff:fe7c:11f9, 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, + 2600:3c08::f03c:93ff:fe7c:1164"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": + "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, 172.233.64.43, + 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, 172.233.64.42, + 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, 2400:8905::f03c:93ff:fe9d:b012, + 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, 2400:8905::f03c:93ff:fe9d:259f, + 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, 2400:8905::f03c:93ff:fe9d:b0ce, + 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, + 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, + 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", "ipv6": "2600:3c0b::f03c:93ff:feba:d513, + 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, 2600:3c0b::f03c:93ff:feba:d5fb, + 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, 2600:3c0b::f03c:93ff:feba:d5d5, + 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, 2600:3c0b::f03c:93ff:feba:d529"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-mia", "label": "Miami, FL", "country": + "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.160.34, + 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, 172.233.160.28, + 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, + 2a01:7e04::f03c:93ff:fead:d37f, 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, + 2a01:7e04::f03c:93ff:fead:d316, 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, + 2a01:7e04::f03c:93ff:fead:d395, 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": + "id", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, + 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, + 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", "ipv6": "2600:3c0c::f03c:93ff:feed:a90b, + 2600:3c0c::f03c:93ff:feed:a9a5, 2600:3c0c::f03c:93ff:feed:a935, 2600:3c0c::f03c:93ff:feed:a930, + 2600:3c0c::f03c:93ff:feed:a95c, 2600:3c0c::f03c:93ff:feed:a9ad, 2600:3c0c::f03c:93ff:feed:a9f2, + 2600:3c0c::f03c:93ff:feed:a9ff, 2600:3c0c::f03c:93ff:feed:a9c8, 2600:3c0c::f03c:93ff:feed:a96b"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, + 172.233.128.37, 172.233.128.34, 172.233.128.36, 172.233.128.33, 172.233.128.39, + 172.233.128.43, 172.233.128.44", "ipv6": "2a01:7e03::f03c:93ff:feb1:b789, 2a01:7e03::f03c:93ff:feb1:b717, + 2a01:7e03::f03c:93ff:feb1:b707, 2a01:7e03::f03c:93ff:feb1:b7ab, 2a01:7e03::f03c:93ff:feb1:b7e2, + 2a01:7e03::f03c:93ff:feb1:b709, 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, + 2a01:7e03::f03c:93ff:feb1:b76e, 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": + ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud + Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": + "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": + "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": + "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": + "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": + "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, + 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": + "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, 2600:3c00::8, + 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, - 74.207.241.5, 74.207.242.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + 74.207.241.5, 74.207.242.5", "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, + 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, + 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, - 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + 50.116.41.5, 23.239.18.5", "ipv6": "2600:3c02::3, 2600:3c02::5, 2600:3c02::4, + 2600:3c02::6, 2600:3c02::c, 2600:3c02::7, 2600:3c02::2, 2600:3c02::9, 2600:3c02::8, + 2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, - 207.192.69.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, + 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, + 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, - 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": + 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, + 2a01:7e00::3, 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, + 2a01:7e00::4, 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, - 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": + 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "2400:8901::5, 2400:8901::4, + 2400:8901::b, 2400:8901::3, 2400:8901::9, 2400:8901::2, 2400:8901::8, 2400:8901::7, + 2400:8901::c, 2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5, - 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, 139.162.135.5, 139.162.136.5, - 139.162.137.5, 139.162.138.5, 139.162.139.5", "ipv6": "1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", - "label": "Tokyo, JP", "country": "jp", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "139.162.66.5, 139.162.67.5, 139.162.68.5, 139.162.69.5, - 139.162.70.5, 139.162.71.5, 139.162.72.5, 139.162.73.5, 139.162.74.5, 139.162.75.5", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}], "page": 1, "pages": 1, "results": 34}' + "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 30}' headers: Access-Control-Allow-Credentials: - "true" @@ -324,7 +309,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:32:53 GMT + - Tue, 01 Oct 2024 18:02:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -341,19 +326,16 @@ interactions: - DENY - DENY X-Oauth-Scopes: - - account:read_write databases:read_write domains:read_write events:read_write - firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write - longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write - volumes:read_write vpc:read_write + - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-9s5wo423f2cr","firewall_id":693050,"booted":false}' + body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-av9ed8oy5353","booted":false}' form: {} headers: Accept: @@ -365,16 +347,17 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61875749, "label": "go-test-ins-wo-disk-9s5wo423f2cr", "group": + body: '{"id": 64701046, "label": "go-test-ins-wo-disk-av9ed8oy5353", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["170.187.250.130"], "ipv6": "1234::5678/128", + "type": "g6-nanode-1", "ipv4": ["192.46.210.101"], "ipv6": "2400:8904::f03c:95ff:fead:e035/128", "image": null, "region": "ap-west", "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": true, "available": false, "schedule": {"day": null, "window": - null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": true, - "tags": [], "host_uuid": "0be889ff8efab8e9f1cbbb28b1799aa440e95149", "has_user_data": - false, "placement_group": null, "lke_cluster_id": null}' + "backups": {"enabled": false, "available": false, "schedule": {"day": null, + "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": + true, "tags": [], "host_uuid": "b87012b659b947e3d8e73fccf7a05a0eaa29cc4d", "has_user_data": + false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": + null, "capabilities": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -393,13 +376,13 @@ interactions: Connection: - keep-alive Content-Length: - - "808" + - "859" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:32:53 GMT + - Tue, 01 Oct 2024 18:02:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -414,10 +397,7 @@ interactions: - DENY - DENY X-Oauth-Scopes: - - account:read_write databases:read_write domains:read_write events:read_write - firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write - longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write - volumes:read_write vpc:read_write + - '*' X-Ratelimit-Limit: - "10" X-Xss-Protection: @@ -426,7 +406,7 @@ interactions: code: 200 duration: "" - request: - body: '{"label":"go-test-conf-6vqp59eug488","devices":{},"interfaces":null}' + body: '{"label":"go-test-conf-g57p51ye06xg","devices":{},"interfaces":null}' form: {} headers: Accept: @@ -435,10 +415,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875749/configs + url: https://api.linode.com/v4beta/linode/instances/64701046/configs method: POST response: - body: '{"id": 65096250, "label": "go-test-conf-6vqp59eug488", "helpers": {"updatedb_disabled": + body: '{"id": 67984990, "label": "go-test-conf-g57p51ye06xg", "helpers": {"updatedb_disabled": true, "distro": true, "modules_dep": true, "network": false, "devtmpfs_automount": true}, "kernel": "linode/latest-64bit", "comments": "", "memory_limit": 0, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "root_device": "/dev/sda", @@ -469,7 +449,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:32:54 GMT + - Tue, 01 Oct 2024 18:02:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -484,12 +464,9 @@ interactions: - DENY - DENY X-Oauth-Scopes: - - account:read_write databases:read_write domains:read_write events:read_write - firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write - longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write - volumes:read_write vpc:read_write + - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -506,75 +483,304 @@ interactions: User-Agent: - linodego/dev https://github.com/linode/linodego X-Filter: - - '{"linode_id":61875749}' + - '{"linode_id":64701046}' url: https://api.linode.com/v4beta/networking/ips?page=1 method: GET response: - body: '{"page": 1, "pages": 1, "results": 23, "data": [{"address": "172.234.197.207", - "gateway": "172.234.197.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": - "ipv4", "public": true, "rdns": "172-234-197-207.ip.linodeusercontent.com", - "linode_id": 54748754, "region": "us-ord", "vpc_nat_1_1": null}, {"address": - "50.116.24.42", "gateway": "50.116.24.1", "subnet_mask": "255.255.255.0", "prefix": - 24, "type": "ipv4", "public": true, "rdns": "50-116-24-42.ip.linodeusercontent.com", - "linode_id": 57328123, "region": "us-central", "vpc_nat_1_1": null}, {"address": - "172.233.221.75", "gateway": "172.233.221.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-221-75.ip.linodeusercontent.com", - "linode_id": 60472044, "region": "us-ord", "vpc_nat_1_1": null}, {"address": - "172.233.211.146", "gateway": "172.233.211.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-211-146.ip.linodeusercontent.com", - "linode_id": 60939824, "region": "us-ord", "vpc_nat_1_1": null}, {"address": - "66.175.208.38", "gateway": "66.175.208.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-208-38.ip.linodeusercontent.com", - "linode_id": 61839386, "region": "us-east", "vpc_nat_1_1": null}, {"address": - "23.239.30.160", "gateway": "23.239.30.1", "subnet_mask": "255.255.255.0", "prefix": - 24, "type": "ipv4", "public": true, "rdns": "23-239-30-160.ip.linodeusercontent.com", - "linode_id": 61871792, "region": "us-central", "vpc_nat_1_1": null}, {"address": - "192.168.227.101", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": - 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61871792, "region": - "us-central", "vpc_nat_1_1": null}, {"address": "23.239.30.211", "gateway": - "23.239.30.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", - "public": true, "rdns": "23-239-30-211.ip.linodeusercontent.com", "linode_id": - 61871793, "region": "us-central", "vpc_nat_1_1": null}, {"address": "192.168.227.212", + body: '{"page": 1, "pages": 2, "results": 99, "data": [{"address": "45.56.98.162", + "gateway": "45.56.98.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-56-98-162.ip.linodeusercontent.com", "linode_id": + 39246844, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.33.70.220", "gateway": "45.33.70.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-33-70-220.ip.linodeusercontent.com", + "linode_id": 41549688, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "143.42.129.149", "gateway": "143.42.129.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "143-42-129-149.ip.linodeusercontent.com", + "linode_id": 42990585, "region": "us-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "45.33.11.126", "gateway": "45.33.11.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-11-126.ip.linodeusercontent.com", + "linode_id": 52184548, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.194.15", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52184548, + "region": "us-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.138.2", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52184549, "region": + "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.164.60", + "gateway": "172.232.164.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-164-60.ip.linodeusercontent.com", "linode_id": + 52184549, "region": "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.154", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743665, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.49", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-49.ip.linodeusercontent.com", "linode_id": + 52743665, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.156", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743668, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.58", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-58.ip.linodeusercontent.com", "linode_id": + 52743668, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.169", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743669, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.69", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-69.ip.linodeusercontent.com", "linode_id": + 52743669, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.56.70.235", "gateway": "45.56.70.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-70-235.ip.linodeusercontent.com", + "linode_id": 53974636, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "139.162.82.92", "gateway": "139.162.82.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-162-82-92.ip.linodeusercontent.com", + "linode_id": 53974656, "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.151.187", "gateway": "172.234.151.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-151-187.ip.linodeusercontent.com", + "linode_id": 53983615, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.233.68", "gateway": "172.233.233.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-233-68.ip.linodeusercontent.com", + "linode_id": 53983631, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.178.99", "gateway": "172.233.178.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-178-99.ip.linodeusercontent.com", + "linode_id": 56582158, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.207.234", "gateway": "172.234.207.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-207-234.ip.linodeusercontent.com", + "linode_id": 56583021, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.32.96", "gateway": "172.234.32.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-32-96.ip.linodeusercontent.com", + "linode_id": 60857235, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "45.56.110.44", "gateway": "45.56.110.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-110-44.ip.linodeusercontent.com", + "linode_id": 61000537, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.228.28", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61656644, + "region": "us-southeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.105.158.45", "gateway": "172.105.158.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-158-45.ip.linodeusercontent.com", + "linode_id": 61656644, "region": "us-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.132.154", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61742447, + "region": "us-ord", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.202.132", + "gateway": "172.234.202.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-202-132.ip.linodeusercontent.com", + "linode_id": 61742447, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.151.76", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61742994, + "region": "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.250.224", + "gateway": "172.234.250.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-250-224.ip.linodeusercontent.com", + "linode_id": 61742994, "region": "us-sea", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.106.13", "gateway": "172.236.106.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-106-13.ip.linodeusercontent.com", + "linode_id": 61755287, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.184.86", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62091306, + "region": "us-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.56.72.210", "gateway": "45.56.72.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-72-210.ip.linodeusercontent.com", + "linode_id": 62091306, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "74.207.253.243", "gateway": "74.207.253.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "74-207-253-243.ip.linodeusercontent.com", + "linode_id": 62103624, "region": "us-west", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.178.76", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62103624, + "region": "us-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.136.17", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", - "public": false, "rdns": null, "linode_id": 61871793, "region": "us-central", - "vpc_nat_1_1": null}, {"address": "23.239.30.230", "gateway": "23.239.30.1", + "public": false, "rdns": null, "linode_id": 62103797, "region": "us-lax", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.235.61.148", "gateway": "172.235.61.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, - "rdns": "23-239-30-230.ip.linodeusercontent.com", "linode_id": 61871794, "region": - "us-central", "vpc_nat_1_1": null}, {"address": "192.168.227.219", "gateway": - null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", "public": - false, "rdns": null, "linode_id": 61871794, "region": "us-central", "vpc_nat_1_1": - null}, {"address": "139.144.1.10", "gateway": "139.144.1.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-144-1-10.ip.linodeusercontent.com", - "linode_id": 61874266, "region": "ap-west", "vpc_nat_1_1": null}, {"address": - "170.187.250.130", "gateway": "170.187.250.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "170-187-250-130.ip.linodeusercontent.com", - "linode_id": 61875749, "region": "ap-west", "vpc_nat_1_1": null}, {"address": - "1234::5678", "gateway": "1234::5678", "subnet_mask": "1234::5678", - "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 54748754, "region": - "us-ord", "public": true}, {"address": "1234::5678", "gateway": - "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, "type": "ipv6", - "rdns": null, "linode_id": 57328123, "region": "us-central", "public": true}, - {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": - "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 60472044, "region": "us-ord", "public": true}, {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 60939824, "region": "us-ord", "public": - true}, {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": - "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 61839386, "region": "us-east", "public": true}, {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 61871792, "region": "us-central", - "public": true}, {"address": "1234::5678", "gateway": "1234::5678", - "subnet_mask": "1234::5678", "prefix": 64, "type": "ipv6", "rdns": - null, "linode_id": 61871793, "region": "us-central", "public": true}, {"address": - "1234::5678", "gateway": "1234::5678", "subnet_mask": "1234::5678", - "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 61871794, "region": - "us-central", "public": true}, {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 61874266, "region": "ap-west", "public": - true}, {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": - "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 61875749, "region": "ap-west", "public": true}]}' + "rdns": "172-235-61-148.ip.linodeusercontent.com", "linode_id": 62103797, "region": + "us-lax", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.138.122", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62103841, "region": "us-mia", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.233.187.175", "gateway": "172.233.187.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-233-187-175.ip.linodeusercontent.com", "linode_id": 62103841, "region": + "us-mia", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.43.188", + "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-43-188.ip.linodeusercontent.com", "linode_id": + 62177702, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.132.216", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62177702, "region": + "ap-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.9.207", + "gateway": "172.105.9.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-9-207.ip.linodeusercontent.com", "linode_id": + 62177703, "region": "ca-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.138.217", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62177703, "region": + "ca-central", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.173.244", + "gateway": "172.105.173.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-173-244.ip.linodeusercontent.com", + "linode_id": 62182442, "region": "ap-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.134.110", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182442, + "region": "ap-southeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.142.78", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182443, "region": + "us-iad", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.37.78", + "gateway": "172.234.37.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-37-78.ip.linodeusercontent.com", "linode_id": + 62182443, "region": "us-iad", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.128.28", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182444, "region": + "fr-par", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.60.230", + "gateway": "172.232.60.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-60-230.ip.linodeusercontent.com", "linode_id": + 62182444, "region": "fr-par", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.128.34", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182447, "region": + "br-gru", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.233.11.90", + "gateway": "172.233.11.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-233-11-90.ip.linodeusercontent.com", "linode_id": + 62182447, "region": "br-gru", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.233.58.100", "gateway": "172.233.58.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-58-100.ip.linodeusercontent.com", + "linode_id": 62182448, "region": "nl-ams", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.132.32", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182448, + "region": "nl-ams", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.134.10", + "gateway": "172.232.134.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-134-10.ip.linodeusercontent.com", "linode_id": + 62182452, "region": "se-sto", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.159.54", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182452, "region": + "se-sto", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.233.120.210", + "gateway": "172.233.120.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-233-120-210.ip.linodeusercontent.com", + "linode_id": 62182453, "region": "es-mad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.159.191", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182453, + "region": "es-mad", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.114.137", + "gateway": "172.232.114.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-114-137.ip.linodeusercontent.com", + "linode_id": 62182454, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.159.226", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182454, + "region": "in-maa", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.159.122", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182455, "region": "jp-osa", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.233.81.46", "gateway": "172.233.81.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-233-81-46.ip.linodeusercontent.com", "linode_id": 62182455, "region": + "jp-osa", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.159.220", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182460, "region": "it-mil", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.232.216.130", "gateway": "172.232.216.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-232-216-130.ip.linodeusercontent.com", "linode_id": 62182460, "region": + "it-mil", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.248.5", + "gateway": "172.232.248.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-248-5.ip.linodeusercontent.com", "linode_id": + 62182462, "region": "id-cgk", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.148.128", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182462, "region": + "id-cgk", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.128.131", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182463, "region": "gb-lon", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.236.1.108", "gateway": "172.236.1.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-236-1-108.ip.linodeusercontent.com", "linode_id": 62182463, "region": + "gb-lon", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.128.254", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182465, "region": "au-mel", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.236.61.193", "gateway": "172.236.61.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-236-61-193.ip.linodeusercontent.com", "linode_id": 62182465, "region": + "au-mel", "vpc_nat_1_1": null, "reserved": false}, {"address": "66.175.213.75", + "gateway": "66.175.213.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "66-175-213-75.ip.linodeusercontent.com", "linode_id": + 62182466, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.223.6", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182466, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.172.145", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182471, "region": "eu-west", "vpc_nat_1_1": + null, "reserved": false}, {"address": "212.71.244.79", "gateway": "212.71.244.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "212-71-244-79.ip.linodeusercontent.com", "linode_id": 62182471, "region": + "eu-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.133.143", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182473, "region": "ap-south", + "vpc_nat_1_1": null, "reserved": false}, {"address": "139.177.186.84", "gateway": + "139.177.186.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", + "public": true, "rdns": "139-177-186-84.ip.linodeusercontent.com", "linode_id": + 62182473, "region": "ap-south", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.104.146.131", "gateway": "172.104.146.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-146-131.ip.linodeusercontent.com", + "linode_id": 62182475, "region": "eu-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "139.162.81.50", "gateway": "139.162.81.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-162-81-50.ip.linodeusercontent.com", + "linode_id": 62182477, "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.186.3", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182477, + "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "139.144.218.154", "gateway": "139.144.218.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-144-218-154.ip.linodeusercontent.com", + "linode_id": 62361598, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.175.36", "gateway": "172.233.175.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-175-36.ip.linodeusercontent.com", + "linode_id": 63198551, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.125.198", "gateway": "172.236.125.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-125-198.ip.linodeusercontent.com", + "linode_id": 63219315, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.125.199", "gateway": "172.236.125.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-125-199.ip.linodeusercontent.com", + "linode_id": 63219421, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.29.18", "gateway": "172.235.29.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-29-18.ip.linodeusercontent.com", + "linode_id": 63219480, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.29.23", "gateway": "172.235.29.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-29-23.ip.linodeusercontent.com", + "linode_id": 63219566, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.56.7", "gateway": "172.234.56.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-56-7.ip.linodeusercontent.com", + "linode_id": 63219603, "region": "fr-par", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.232.34.104", "gateway": "172.232.34.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-232-34-104.ip.linodeusercontent.com", + "linode_id": 63219704, "region": "fr-par", "vpc_nat_1_1": null, "reserved": + false}, {"address": "66.228.42.218", "gateway": "66.228.42.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-42-218.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "50.116.63.168", "gateway": "50.116.63.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "50-116-63-168.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.143.164", "gateway": "172.235.143.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-143-164.ip.linodeusercontent.com", + "linode_id": 63523131, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.134.163", "gateway": "172.235.134.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-134-163.ip.linodeusercontent.com", + "linode_id": 63523611, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.46.210.101", "gateway": "192.46.210.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-210-101.ip.linodeusercontent.com", + "linode_id": 64701046, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}, {"address": "66.175.210.251", "gateway": "66.175.210.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-210-251.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, + {"address": "2600:3c03::f03c:93ff:fedc:2b27", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 39246844, "region": "us-east", "public": true}, {"address": "2600:3c03::f03c:93ff:fe27:a9d9", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 41549688, "region": "us-east", "public": + true}, {"address": "2600:3c02::f03c:93ff:fefe:60f5", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 42990585, "region": "us-southeast", "public": true}, {"address": "2600:3c00::f03c:93ff:fe91:4a99", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 52184548, "region": "us-central", + "public": true}, {"address": "2600:3c0a::f03c:93ff:fe91:4ac9", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 52184549, "region": "us-sea", "public": true}, {"address": + "2600:3c03::f03c:94ff:fea1:516d", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 52743665, "region": + "us-east", "public": true}, {"address": "2600:3c03::f03c:94ff:fea1:5152", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 52743668, "region": "us-east", "public": true}, {"address": + "2600:3c03::f03c:94ff:fea1:51ad", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 52743669, "region": + "us-east", "public": true}, {"address": "2600:3c00::f03c:94ff:fecf:d569", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 53974636, "region": "us-central", "public": true}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -597,7 +803,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:32:54 GMT + - Tue, 01 Oct 2024 18:02:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -614,12 +820,191 @@ interactions: - DENY - DENY X-Oauth-Scopes: - - account:read_write databases:read_write domains:read_write events:read_write - firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write - longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write - volumes:read_write vpc:read_write + - '*' X-Ratelimit-Limit: - - "400" + - "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 + X-Filter: + - '{"linode_id":64701046}' + url: https://api.linode.com/v4beta/networking/ips?page=2 + method: GET + response: + body: '{"page": 2, "pages": 2, "results": 47, "data": [{"address": "2400:8902::f03c:94ff:fecf:d5fd", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 53974656, "region": "ap-northeast", + "public": true}, {"address": "2600:3c05::f03c:94ff:fecf:c7a3", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 53983615, "region": "us-iad", "public": true}, {"address": + "2600:3c05::f03c:94ff:fecf:c77e", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 53983631, "region": + "us-iad", "public": true}, {"address": "2a01:7e04::f03c:94ff:fed9:fd29", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 56582158, "region": "us-mia", "public": true}, {"address": + "2600:3c06::f03c:94ff:fed9:46b2", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 56583021, "region": + "us-ord", "public": true}, {"address": "2600:3c05::f03c:94ff:fe85:e08a", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 60857235, "region": "us-iad", "public": true}, {"address": + "2600:3c03::f03c:94ff:fe45:3e27", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 61000537, "region": + "us-east", "public": true}, {"address": "2600:3c02::f03c:94ff:fed0:3afb", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 61656644, "region": "us-southeast", "public": true}, + {"address": "2600:3c06::f03c:94ff:fef6:56d7", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 61742447, "region": "us-ord", "public": true}, {"address": "2600:3c0a::f03c:94ff:fef6:e547", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 61742994, "region": "us-sea", "public": + true}, {"address": "2600:3c06::f03c:94ff:fef6:46ee", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 61755287, "region": "us-ord", "public": true}, {"address": "2600:3c00::f03c:94ff:fe75:5f28", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62091306, "region": "us-central", + "public": true}, {"address": "2600:3c01::f03c:94ff:fe75:e693", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 62103624, "region": "us-west", "public": true}, {"address": + "2a01:7e03::f03c:94ff:fe75:e657", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 62103797, "region": + "us-lax", "public": true}, {"address": "2a01:7e04::f03c:94ff:fe75:e2fe", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 62103841, "region": "us-mia", "public": true}, {"address": + "2400:8904::f03c:94ff:fe68:cd68", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 62177702, "region": + "ap-west", "public": true}, {"address": "2600:3c04::f03c:94ff:fe68:cd4a", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 62177703, "region": "ca-central", "public": true}, + {"address": "2400:8907::f03c:94ff:fe68:ba8b", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182442, "region": "ap-southeast", "public": true}, {"address": "2600:3c05::f03c:94ff:fe68:ba71", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182443, "region": "us-iad", "public": + true}, {"address": "2600:3c07::f03c:94ff:fe68:bac2", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182444, "region": "fr-par", "public": true}, {"address": "2600:3c0d::f03c:94ff:fe68:babb", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182447, "region": "br-gru", "public": + true}, {"address": "2600:3c0e::f03c:94ff:fe68:ba0e", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182448, "region": "nl-ams", "public": true}, {"address": "2600:3c09::f03c:94ff:fe68:ba50", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182452, "region": "se-sto", "public": + true}, {"address": "2a01:7e02::f03c:94ff:fe68:baba", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182453, "region": "es-mad", "public": true}, {"address": "2600:3c08::f03c:94ff:fe68:bafc", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182454, "region": "in-maa", "public": + true}, {"address": "2400:8905::f03c:94ff:fe68:baa1", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182455, "region": "jp-osa", "public": true}, {"address": "2600:3c0b::f03c:94ff:fe68:ba61", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182460, "region": "it-mil", "public": + true}, {"address": "2600:3c0c::f03c:94ff:fe68:ba6d", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182462, "region": "id-cgk", "public": true}, {"address": "2600:3c13::f03c:94ff:fe68:ba57", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182463, "region": "gb-lon", "public": + true}, {"address": "2600:3c14::f03c:94ff:fe68:ba5b", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182465, "region": "au-mel", "public": true}, {"address": "2600:3c03::f03c:94ff:fe68:ba85", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182466, "region": "us-east", "public": + true}, {"address": "2a01:7e00::f03c:94ff:fe68:ba72", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182471, "region": "eu-west", "public": true}, {"address": "2400:8901::f03c:94ff:fe68:ba30", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182473, "region": "ap-south", "public": + true}, {"address": "2a01:7e01::f03c:94ff:fe68:ba11", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182475, "region": "eu-central", "public": true}, {"address": "2400:8902::f03c:94ff:fe68:babf", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182477, "region": "ap-northeast", + "public": true}, {"address": "2600:3c05::f03c:94ff:fe6d:8efe", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 62361598, "region": "us-iad", "public": true}, {"address": + "2a01:7e04::f03c:95ff:fe14:636a", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63198551, "region": + "us-mia", "public": true}, {"address": "2600:3c06::f03c:95ff:fe14:0767", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63219315, "region": "us-ord", "public": true}, {"address": + "2600:3c06::f03c:95ff:fe14:076e", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63219421, "region": + "us-ord", "public": true}, {"address": "2600:3c08::f03c:95ff:fe14:259c", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63219480, "region": "in-maa", "public": true}, {"address": + "2600:3c08::f03c:95ff:fe14:25db", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63219566, "region": + "in-maa", "public": true}, {"address": "2600:3c07::f03c:95ff:fe14:25d2", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63219603, "region": "fr-par", "public": true}, {"address": + "2600:3c07::f03c:95ff:fe14:25c6", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63219704, "region": + "fr-par", "public": true}, {"address": "2600:3c03::f03c:95ff:feed:c413", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63262077, "region": "us-east", "public": true}, {"address": + "2a01:7e04::f03c:95ff:fe3d:4733", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63523131, "region": + "us-mia", "public": true}, {"address": "2a01:7e04::f03c:95ff:fe3d:66d9", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63523611, "region": "us-mia", "public": true}, {"address": + "2400:8904::f03c:95ff:fead:e035", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 64701046, "region": + "ap-west", "public": 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-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 01 Oct 2024 18:02:12 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - ips: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 @@ -638,71 +1023,300 @@ interactions: url: https://api.linode.com/v4beta/networking/ips?page=1&skip_ipv6_rdns=true method: GET response: - body: '{"page": 1, "pages": 1, "results": 23, "data": [{"address": "172.234.197.207", - "gateway": "172.234.197.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": - "ipv4", "public": true, "rdns": "172-234-197-207.ip.linodeusercontent.com", - "linode_id": 54748754, "region": "us-ord", "vpc_nat_1_1": null}, {"address": - "50.116.24.42", "gateway": "50.116.24.1", "subnet_mask": "255.255.255.0", "prefix": - 24, "type": "ipv4", "public": true, "rdns": "50-116-24-42.ip.linodeusercontent.com", - "linode_id": 57328123, "region": "us-central", "vpc_nat_1_1": null}, {"address": - "172.233.221.75", "gateway": "172.233.221.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-221-75.ip.linodeusercontent.com", - "linode_id": 60472044, "region": "us-ord", "vpc_nat_1_1": null}, {"address": - "172.233.211.146", "gateway": "172.233.211.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-211-146.ip.linodeusercontent.com", - "linode_id": 60939824, "region": "us-ord", "vpc_nat_1_1": null}, {"address": - "66.175.208.38", "gateway": "66.175.208.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-208-38.ip.linodeusercontent.com", - "linode_id": 61839386, "region": "us-east", "vpc_nat_1_1": null}, {"address": - "23.239.30.160", "gateway": "23.239.30.1", "subnet_mask": "255.255.255.0", "prefix": - 24, "type": "ipv4", "public": true, "rdns": "23-239-30-160.ip.linodeusercontent.com", - "linode_id": 61871792, "region": "us-central", "vpc_nat_1_1": null}, {"address": - "192.168.227.101", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": - 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61871792, "region": - "us-central", "vpc_nat_1_1": null}, {"address": "23.239.30.211", "gateway": - "23.239.30.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", - "public": true, "rdns": "23-239-30-211.ip.linodeusercontent.com", "linode_id": - 61871793, "region": "us-central", "vpc_nat_1_1": null}, {"address": "192.168.227.212", + body: '{"page": 1, "pages": 2, "results": 99, "data": [{"address": "45.56.98.162", + "gateway": "45.56.98.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-56-98-162.ip.linodeusercontent.com", "linode_id": + 39246844, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.33.70.220", "gateway": "45.33.70.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-33-70-220.ip.linodeusercontent.com", + "linode_id": 41549688, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "143.42.129.149", "gateway": "143.42.129.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "143-42-129-149.ip.linodeusercontent.com", + "linode_id": 42990585, "region": "us-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "45.33.11.126", "gateway": "45.33.11.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-11-126.ip.linodeusercontent.com", + "linode_id": 52184548, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.194.15", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52184548, + "region": "us-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.138.2", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52184549, "region": + "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.164.60", + "gateway": "172.232.164.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-164-60.ip.linodeusercontent.com", "linode_id": + 52184549, "region": "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.154", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743665, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.49", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-49.ip.linodeusercontent.com", "linode_id": + 52743665, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.156", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743668, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.58", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-58.ip.linodeusercontent.com", "linode_id": + 52743668, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.169", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743669, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.69", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-69.ip.linodeusercontent.com", "linode_id": + 52743669, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.56.70.235", "gateway": "45.56.70.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-70-235.ip.linodeusercontent.com", + "linode_id": 53974636, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "139.162.82.92", "gateway": "139.162.82.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-162-82-92.ip.linodeusercontent.com", + "linode_id": 53974656, "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.151.187", "gateway": "172.234.151.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-151-187.ip.linodeusercontent.com", + "linode_id": 53983615, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.233.68", "gateway": "172.233.233.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-233-68.ip.linodeusercontent.com", + "linode_id": 53983631, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.178.99", "gateway": "172.233.178.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-178-99.ip.linodeusercontent.com", + "linode_id": 56582158, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.207.234", "gateway": "172.234.207.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-207-234.ip.linodeusercontent.com", + "linode_id": 56583021, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.32.96", "gateway": "172.234.32.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-32-96.ip.linodeusercontent.com", + "linode_id": 60857235, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "45.56.110.44", "gateway": "45.56.110.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-110-44.ip.linodeusercontent.com", + "linode_id": 61000537, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.228.28", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61656644, + "region": "us-southeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.105.158.45", "gateway": "172.105.158.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-158-45.ip.linodeusercontent.com", + "linode_id": 61656644, "region": "us-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.132.154", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61742447, + "region": "us-ord", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.202.132", + "gateway": "172.234.202.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-202-132.ip.linodeusercontent.com", + "linode_id": 61742447, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.151.76", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61742994, + "region": "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.250.224", + "gateway": "172.234.250.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-250-224.ip.linodeusercontent.com", + "linode_id": 61742994, "region": "us-sea", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.106.13", "gateway": "172.236.106.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-106-13.ip.linodeusercontent.com", + "linode_id": 61755287, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.184.86", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62091306, + "region": "us-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.56.72.210", "gateway": "45.56.72.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-72-210.ip.linodeusercontent.com", + "linode_id": 62091306, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "74.207.253.243", "gateway": "74.207.253.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "74-207-253-243.ip.linodeusercontent.com", + "linode_id": 62103624, "region": "us-west", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.178.76", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62103624, + "region": "us-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.136.17", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", - "public": false, "rdns": null, "linode_id": 61871793, "region": "us-central", - "vpc_nat_1_1": null}, {"address": "23.239.30.230", "gateway": "23.239.30.1", + "public": false, "rdns": null, "linode_id": 62103797, "region": "us-lax", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.235.61.148", "gateway": "172.235.61.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, - "rdns": "23-239-30-230.ip.linodeusercontent.com", "linode_id": 61871794, "region": - "us-central", "vpc_nat_1_1": null}, {"address": "192.168.227.219", "gateway": - null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", "public": - false, "rdns": null, "linode_id": 61871794, "region": "us-central", "vpc_nat_1_1": - null}, {"address": "139.144.1.10", "gateway": "139.144.1.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-144-1-10.ip.linodeusercontent.com", - "linode_id": 61874266, "region": "ap-west", "vpc_nat_1_1": null}, {"address": - "170.187.250.130", "gateway": "170.187.250.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "170-187-250-130.ip.linodeusercontent.com", - "linode_id": 61875749, "region": "ap-west", "vpc_nat_1_1": null}, {"address": - "1234::5678", "gateway": "1234::5678", "subnet_mask": "1234::5678", - "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 54748754, "region": - "us-ord", "public": true}, {"address": "1234::5678", "gateway": - "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, "type": "ipv6", - "rdns": null, "linode_id": 57328123, "region": "us-central", "public": true}, - {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": - "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 60472044, "region": "us-ord", "public": true}, {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 60939824, "region": "us-ord", "public": - true}, {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": - "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 61839386, "region": "us-east", "public": true}, {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 61871792, "region": "us-central", - "public": true}, {"address": "1234::5678", "gateway": "1234::5678", - "subnet_mask": "1234::5678", "prefix": 64, "type": "ipv6", "rdns": - null, "linode_id": 61871793, "region": "us-central", "public": true}, {"address": - "1234::5678", "gateway": "1234::5678", "subnet_mask": "1234::5678", - "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 61871794, "region": - "us-central", "public": true}, {"address": "1234::5678", - "gateway": "1234::5678", "subnet_mask": "1234::5678", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 61874266, "region": "ap-west", "public": - true}, {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": - "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": - 61875749, "region": "ap-west", "public": true}]}' + "rdns": "172-235-61-148.ip.linodeusercontent.com", "linode_id": 62103797, "region": + "us-lax", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.138.122", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62103841, "region": "us-mia", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.233.187.175", "gateway": "172.233.187.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-233-187-175.ip.linodeusercontent.com", "linode_id": 62103841, "region": + "us-mia", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.43.188", + "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-43-188.ip.linodeusercontent.com", "linode_id": + 62177702, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.132.216", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62177702, "region": + "ap-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.9.207", + "gateway": "172.105.9.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-9-207.ip.linodeusercontent.com", "linode_id": + 62177703, "region": "ca-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.138.217", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62177703, "region": + "ca-central", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.173.244", + "gateway": "172.105.173.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-173-244.ip.linodeusercontent.com", + "linode_id": 62182442, "region": "ap-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.134.110", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182442, + "region": "ap-southeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.142.78", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182443, "region": + "us-iad", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.37.78", + "gateway": "172.234.37.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-37-78.ip.linodeusercontent.com", "linode_id": + 62182443, "region": "us-iad", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.128.28", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182444, "region": + "fr-par", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.60.230", + "gateway": "172.232.60.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-60-230.ip.linodeusercontent.com", "linode_id": + 62182444, "region": "fr-par", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.128.34", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182447, "region": + "br-gru", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.233.11.90", + "gateway": "172.233.11.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-233-11-90.ip.linodeusercontent.com", "linode_id": + 62182447, "region": "br-gru", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.233.58.100", "gateway": "172.233.58.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-58-100.ip.linodeusercontent.com", + "linode_id": 62182448, "region": "nl-ams", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.132.32", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182448, + "region": "nl-ams", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.134.10", + "gateway": "172.232.134.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-134-10.ip.linodeusercontent.com", "linode_id": + 62182452, "region": "se-sto", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.159.54", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182452, "region": + "se-sto", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.233.120.210", + "gateway": "172.233.120.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-233-120-210.ip.linodeusercontent.com", + "linode_id": 62182453, "region": "es-mad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.159.191", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182453, + "region": "es-mad", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.114.137", + "gateway": "172.232.114.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-114-137.ip.linodeusercontent.com", + "linode_id": 62182454, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.159.226", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182454, + "region": "in-maa", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.159.122", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182455, "region": "jp-osa", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.233.81.46", "gateway": "172.233.81.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-233-81-46.ip.linodeusercontent.com", "linode_id": 62182455, "region": + "jp-osa", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.159.220", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182460, "region": "it-mil", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.232.216.130", "gateway": "172.232.216.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-232-216-130.ip.linodeusercontent.com", "linode_id": 62182460, "region": + "it-mil", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.248.5", + "gateway": "172.232.248.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-248-5.ip.linodeusercontent.com", "linode_id": + 62182462, "region": "id-cgk", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.148.128", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182462, "region": + "id-cgk", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.128.131", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182463, "region": "gb-lon", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.236.1.108", "gateway": "172.236.1.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-236-1-108.ip.linodeusercontent.com", "linode_id": 62182463, "region": + "gb-lon", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.128.254", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182465, "region": "au-mel", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.236.61.193", "gateway": "172.236.61.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-236-61-193.ip.linodeusercontent.com", "linode_id": 62182465, "region": + "au-mel", "vpc_nat_1_1": null, "reserved": false}, {"address": "66.175.213.75", + "gateway": "66.175.213.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "66-175-213-75.ip.linodeusercontent.com", "linode_id": + 62182466, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.223.6", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182466, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.172.145", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182471, "region": "eu-west", "vpc_nat_1_1": + null, "reserved": false}, {"address": "212.71.244.79", "gateway": "212.71.244.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "212-71-244-79.ip.linodeusercontent.com", "linode_id": 62182471, "region": + "eu-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.133.143", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182473, "region": "ap-south", + "vpc_nat_1_1": null, "reserved": false}, {"address": "139.177.186.84", "gateway": + "139.177.186.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", + "public": true, "rdns": "139-177-186-84.ip.linodeusercontent.com", "linode_id": + 62182473, "region": "ap-south", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.104.146.131", "gateway": "172.104.146.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-146-131.ip.linodeusercontent.com", + "linode_id": 62182475, "region": "eu-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "139.162.81.50", "gateway": "139.162.81.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-162-81-50.ip.linodeusercontent.com", + "linode_id": 62182477, "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.186.3", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182477, + "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "139.144.218.154", "gateway": "139.144.218.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-144-218-154.ip.linodeusercontent.com", + "linode_id": 62361598, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.175.36", "gateway": "172.233.175.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-175-36.ip.linodeusercontent.com", + "linode_id": 63198551, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.125.198", "gateway": "172.236.125.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-125-198.ip.linodeusercontent.com", + "linode_id": 63219315, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.125.199", "gateway": "172.236.125.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-125-199.ip.linodeusercontent.com", + "linode_id": 63219421, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.29.18", "gateway": "172.235.29.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-29-18.ip.linodeusercontent.com", + "linode_id": 63219480, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.29.23", "gateway": "172.235.29.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-29-23.ip.linodeusercontent.com", + "linode_id": 63219566, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.56.7", "gateway": "172.234.56.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-56-7.ip.linodeusercontent.com", + "linode_id": 63219603, "region": "fr-par", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.232.34.104", "gateway": "172.232.34.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-232-34-104.ip.linodeusercontent.com", + "linode_id": 63219704, "region": "fr-par", "vpc_nat_1_1": null, "reserved": + false}, {"address": "66.228.42.218", "gateway": "66.228.42.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-42-218.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "50.116.63.168", "gateway": "50.116.63.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "50-116-63-168.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.143.164", "gateway": "172.235.143.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-143-164.ip.linodeusercontent.com", + "linode_id": 63523131, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.134.163", "gateway": "172.235.134.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-134-163.ip.linodeusercontent.com", + "linode_id": 63523611, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.46.210.101", "gateway": "192.46.210.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-210-101.ip.linodeusercontent.com", + "linode_id": 64701046, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}, {"address": "66.175.210.251", "gateway": "66.175.210.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-175-210-251.ip.linodeusercontent.com", + "linode_id": null, "region": "us-east", "vpc_nat_1_1": null, "reserved": true}, + {"address": "2600:3c03::f03c:93ff:fedc:2b27", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 39246844, "region": "us-east", "public": true}, {"address": "2600:3c03::f03c:93ff:fe27:a9d9", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 41549688, "region": "us-east", "public": + true}, {"address": "2600:3c02::f03c:93ff:fefe:60f5", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 42990585, "region": "us-southeast", "public": true}, {"address": "2600:3c00::f03c:93ff:fe91:4a99", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 52184548, "region": "us-central", + "public": true}, {"address": "2600:3c0a::f03c:93ff:fe91:4ac9", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 52184549, "region": "us-sea", "public": true}, {"address": + "2600:3c03::f03c:94ff:fea1:516d", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 52743665, "region": + "us-east", "public": true}, {"address": "2600:3c03::f03c:94ff:fea1:5152", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 52743668, "region": "us-east", "public": true}, {"address": + "2600:3c03::f03c:94ff:fea1:51ad", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 52743669, "region": + "us-east", "public": true}, {"address": "2600:3c00::f03c:94ff:fecf:d569", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 53974636, "region": "us-central", "public": true}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -725,7 +1339,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:32:54 GMT + - Tue, 01 Oct 2024 18:02:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -742,12 +1356,9 @@ interactions: - DENY - DENY X-Oauth-Scopes: - - account:read_write databases:read_write domains:read_write events:read_write - firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write - longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write - volumes:read_write vpc:read_write + - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -763,7 +1374,585 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875749 + url: https://api.linode.com/v4beta/networking/ips?page=2&skip_ipv6_rdns=true + method: GET + response: + body: '{"page": 2, "pages": 2, "results": 47, "data": [{"address": "2400:8902::f03c:94ff:fecf:d5fd", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 53974656, "region": "ap-northeast", + "public": true}, {"address": "2600:3c05::f03c:94ff:fecf:c7a3", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 53983615, "region": "us-iad", "public": true}, {"address": + "2600:3c05::f03c:94ff:fecf:c77e", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 53983631, "region": + "us-iad", "public": true}, {"address": "2a01:7e04::f03c:94ff:fed9:fd29", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 56582158, "region": "us-mia", "public": true}, {"address": + "2600:3c06::f03c:94ff:fed9:46b2", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 56583021, "region": + "us-ord", "public": true}, {"address": "2600:3c05::f03c:94ff:fe85:e08a", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 60857235, "region": "us-iad", "public": true}, {"address": + "2600:3c03::f03c:94ff:fe45:3e27", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 61000537, "region": + "us-east", "public": true}, {"address": "2600:3c02::f03c:94ff:fed0:3afb", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 61656644, "region": "us-southeast", "public": true}, + {"address": "2600:3c06::f03c:94ff:fef6:56d7", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 61742447, "region": "us-ord", "public": true}, {"address": "2600:3c0a::f03c:94ff:fef6:e547", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 61742994, "region": "us-sea", "public": + true}, {"address": "2600:3c06::f03c:94ff:fef6:46ee", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 61755287, "region": "us-ord", "public": true}, {"address": "2600:3c00::f03c:94ff:fe75:5f28", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62091306, "region": "us-central", + "public": true}, {"address": "2600:3c01::f03c:94ff:fe75:e693", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 62103624, "region": "us-west", "public": true}, {"address": + "2a01:7e03::f03c:94ff:fe75:e657", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 62103797, "region": + "us-lax", "public": true}, {"address": "2a01:7e04::f03c:94ff:fe75:e2fe", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 62103841, "region": "us-mia", "public": true}, {"address": + "2400:8904::f03c:94ff:fe68:cd68", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 62177702, "region": + "ap-west", "public": true}, {"address": "2600:3c04::f03c:94ff:fe68:cd4a", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 62177703, "region": "ca-central", "public": true}, + {"address": "2400:8907::f03c:94ff:fe68:ba8b", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182442, "region": "ap-southeast", "public": true}, {"address": "2600:3c05::f03c:94ff:fe68:ba71", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182443, "region": "us-iad", "public": + true}, {"address": "2600:3c07::f03c:94ff:fe68:bac2", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182444, "region": "fr-par", "public": true}, {"address": "2600:3c0d::f03c:94ff:fe68:babb", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182447, "region": "br-gru", "public": + true}, {"address": "2600:3c0e::f03c:94ff:fe68:ba0e", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182448, "region": "nl-ams", "public": true}, {"address": "2600:3c09::f03c:94ff:fe68:ba50", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182452, "region": "se-sto", "public": + true}, {"address": "2a01:7e02::f03c:94ff:fe68:baba", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182453, "region": "es-mad", "public": true}, {"address": "2600:3c08::f03c:94ff:fe68:bafc", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182454, "region": "in-maa", "public": + true}, {"address": "2400:8905::f03c:94ff:fe68:baa1", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182455, "region": "jp-osa", "public": true}, {"address": "2600:3c0b::f03c:94ff:fe68:ba61", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182460, "region": "it-mil", "public": + true}, {"address": "2600:3c0c::f03c:94ff:fe68:ba6d", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182462, "region": "id-cgk", "public": true}, {"address": "2600:3c13::f03c:94ff:fe68:ba57", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182463, "region": "gb-lon", "public": + true}, {"address": "2600:3c14::f03c:94ff:fe68:ba5b", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182465, "region": "au-mel", "public": true}, {"address": "2600:3c03::f03c:94ff:fe68:ba85", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182466, "region": "us-east", "public": + true}, {"address": "2a01:7e00::f03c:94ff:fe68:ba72", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182471, "region": "eu-west", "public": true}, {"address": "2400:8901::f03c:94ff:fe68:ba30", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182473, "region": "ap-south", "public": + true}, {"address": "2a01:7e01::f03c:94ff:fe68:ba11", "gateway": "fe80::1", "subnet_mask": + "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 62182475, "region": "eu-central", "public": true}, {"address": "2400:8902::f03c:94ff:fe68:babf", + "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, + "type": "ipv6", "rdns": null, "linode_id": 62182477, "region": "ap-northeast", + "public": true}, {"address": "2600:3c05::f03c:94ff:fe6d:8efe", "gateway": "fe80::1", + "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 62361598, "region": "us-iad", "public": true}, {"address": + "2a01:7e04::f03c:95ff:fe14:636a", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63198551, "region": + "us-mia", "public": true}, {"address": "2600:3c06::f03c:95ff:fe14:0767", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63219315, "region": "us-ord", "public": true}, {"address": + "2600:3c06::f03c:95ff:fe14:076e", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63219421, "region": + "us-ord", "public": true}, {"address": "2600:3c08::f03c:95ff:fe14:259c", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63219480, "region": "in-maa", "public": true}, {"address": + "2600:3c08::f03c:95ff:fe14:25db", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63219566, "region": + "in-maa", "public": true}, {"address": "2600:3c07::f03c:95ff:fe14:25d2", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63219603, "region": "fr-par", "public": true}, {"address": + "2600:3c07::f03c:95ff:fe14:25c6", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63219704, "region": + "fr-par", "public": true}, {"address": "2600:3c03::f03c:95ff:feed:c413", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63262077, "region": "us-east", "public": true}, {"address": + "2a01:7e04::f03c:95ff:fe3d:4733", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 63523131, "region": + "us-mia", "public": true}, {"address": "2a01:7e04::f03c:95ff:fe3d:66d9", "gateway": + "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", + "rdns": null, "linode_id": 63523611, "region": "us-mia", "public": true}, {"address": + "2400:8904::f03c:95ff:fead:e035", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", + "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": 64701046, "region": + "ap-west", "public": 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-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 01 Oct 2024 18:02:12 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - ips: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 + X-Filter: + - '{"reserved":true}' + url: https://api.linode.com/v4beta/networking/ips?page=1 + method: GET + response: + body: '{"page": 1, "pages": 1, "results": 1, "data": [{"address": "66.175.210.251", + "gateway": "66.175.210.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "66-175-210-251.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: + - "313" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 01 Oct 2024 18:02:12 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - ips: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 + X-Filter: + - '{"reserved":false}' + url: https://api.linode.com/v4beta/networking/ips?page=1 + method: GET + response: + body: '{"page": 1, "pages": 1, "results": 89, "data": [{"address": "45.56.98.162", + "gateway": "45.56.98.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-56-98-162.ip.linodeusercontent.com", "linode_id": + 39246844, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.33.70.220", "gateway": "45.33.70.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-33-70-220.ip.linodeusercontent.com", + "linode_id": 41549688, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "143.42.129.149", "gateway": "143.42.129.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "143-42-129-149.ip.linodeusercontent.com", + "linode_id": 42990585, "region": "us-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "45.33.11.126", "gateway": "45.33.11.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-33-11-126.ip.linodeusercontent.com", + "linode_id": 52184548, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.194.15", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52184548, + "region": "us-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.138.2", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52184549, "region": + "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.164.60", + "gateway": "172.232.164.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-164-60.ip.linodeusercontent.com", "linode_id": + 52184549, "region": "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.154", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743665, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.49", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-49.ip.linodeusercontent.com", "linode_id": + 52743665, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.156", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743668, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.58", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-58.ip.linodeusercontent.com", "linode_id": + 52743668, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.219.169", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 52743669, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "45.79.189.69", + "gateway": "45.79.189.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "45-79-189-69.ip.linodeusercontent.com", "linode_id": + 52743669, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.56.70.235", "gateway": "45.56.70.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-70-235.ip.linodeusercontent.com", + "linode_id": 53974636, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "139.162.82.92", "gateway": "139.162.82.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-162-82-92.ip.linodeusercontent.com", + "linode_id": 53974656, "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.151.187", "gateway": "172.234.151.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-151-187.ip.linodeusercontent.com", + "linode_id": 53983615, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.233.68", "gateway": "172.233.233.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-233-68.ip.linodeusercontent.com", + "linode_id": 53983631, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.178.99", "gateway": "172.233.178.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-178-99.ip.linodeusercontent.com", + "linode_id": 56582158, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.207.234", "gateway": "172.234.207.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-207-234.ip.linodeusercontent.com", + "linode_id": 56583021, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.32.96", "gateway": "172.234.32.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-32-96.ip.linodeusercontent.com", + "linode_id": 60857235, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "45.56.110.44", "gateway": "45.56.110.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-56-110-44.ip.linodeusercontent.com", + "linode_id": 61000537, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.228.28", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61656644, + "region": "us-southeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.105.158.45", "gateway": "172.105.158.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-158-45.ip.linodeusercontent.com", + "linode_id": 61656644, "region": "us-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.132.154", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61742447, + "region": "us-ord", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.202.132", + "gateway": "172.234.202.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-202-132.ip.linodeusercontent.com", + "linode_id": 61742447, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.151.76", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 61742994, + "region": "us-sea", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.250.224", + "gateway": "172.234.250.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-250-224.ip.linodeusercontent.com", + "linode_id": 61742994, "region": "us-sea", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.106.13", "gateway": "172.236.106.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-106-13.ip.linodeusercontent.com", + "linode_id": 61755287, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.184.86", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62091306, + "region": "us-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "45.56.72.210", "gateway": "45.56.72.1", "subnet_mask": "255.255.255.0", "prefix": + 24, "type": "ipv4", "public": true, "rdns": "45-56-72-210.ip.linodeusercontent.com", + "linode_id": 62091306, "region": "us-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "74.207.253.243", "gateway": "74.207.253.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "74-207-253-243.ip.linodeusercontent.com", + "linode_id": 62103624, "region": "us-west", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.178.76", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62103624, + "region": "us-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.136.17", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62103797, "region": "us-lax", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.235.61.148", "gateway": "172.235.61.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-235-61-148.ip.linodeusercontent.com", "linode_id": 62103797, "region": + "us-lax", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.138.122", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62103841, "region": "us-mia", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.233.187.175", "gateway": "172.233.187.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-233-187-175.ip.linodeusercontent.com", "linode_id": 62103841, "region": + "us-mia", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.43.188", + "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-43-188.ip.linodeusercontent.com", "linode_id": + 62177702, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.132.216", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62177702, "region": + "ap-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.9.207", + "gateway": "172.105.9.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-9-207.ip.linodeusercontent.com", "linode_id": + 62177703, "region": "ca-central", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.138.217", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62177703, "region": + "ca-central", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.105.173.244", + "gateway": "172.105.173.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-105-173-244.ip.linodeusercontent.com", + "linode_id": 62182442, "region": "ap-southeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.134.110", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182442, + "region": "ap-southeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.142.78", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182443, "region": + "us-iad", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.234.37.78", + "gateway": "172.234.37.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-234-37-78.ip.linodeusercontent.com", "linode_id": + 62182443, "region": "us-iad", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.128.28", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182444, "region": + "fr-par", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.60.230", + "gateway": "172.232.60.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-60-230.ip.linodeusercontent.com", "linode_id": + 62182444, "region": "fr-par", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.128.34", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182447, "region": + "br-gru", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.233.11.90", + "gateway": "172.233.11.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-233-11-90.ip.linodeusercontent.com", "linode_id": + 62182447, "region": "br-gru", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.233.58.100", "gateway": "172.233.58.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-58-100.ip.linodeusercontent.com", + "linode_id": 62182448, "region": "nl-ams", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.132.32", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182448, + "region": "nl-ams", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.134.10", + "gateway": "172.232.134.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-134-10.ip.linodeusercontent.com", "linode_id": + 62182452, "region": "se-sto", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.159.54", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182452, "region": + "se-sto", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.233.120.210", + "gateway": "172.233.120.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-233-120-210.ip.linodeusercontent.com", + "linode_id": 62182453, "region": "es-mad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.159.191", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182453, + "region": "es-mad", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.114.137", + "gateway": "172.232.114.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-114-137.ip.linodeusercontent.com", + "linode_id": 62182454, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.159.226", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182454, + "region": "in-maa", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.159.122", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182455, "region": "jp-osa", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.233.81.46", "gateway": "172.233.81.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-233-81-46.ip.linodeusercontent.com", "linode_id": 62182455, "region": + "jp-osa", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.159.220", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182460, "region": "it-mil", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.232.216.130", "gateway": "172.232.216.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-232-216-130.ip.linodeusercontent.com", "linode_id": 62182460, "region": + "it-mil", "vpc_nat_1_1": null, "reserved": false}, {"address": "172.232.248.5", + "gateway": "172.232.248.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "172-232-248-5.ip.linodeusercontent.com", "linode_id": + 62182462, "region": "id-cgk", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.148.128", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182462, "region": + "id-cgk", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.128.131", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182463, "region": "gb-lon", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.236.1.108", "gateway": "172.236.1.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-236-1-108.ip.linodeusercontent.com", "linode_id": 62182463, "region": + "gb-lon", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.128.254", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182465, "region": "au-mel", "vpc_nat_1_1": + null, "reserved": false}, {"address": "172.236.61.193", "gateway": "172.236.61.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "172-236-61-193.ip.linodeusercontent.com", "linode_id": 62182465, "region": + "au-mel", "vpc_nat_1_1": null, "reserved": false}, {"address": "66.175.213.75", + "gateway": "66.175.213.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": + "ipv4", "public": true, "rdns": "66-175-213-75.ip.linodeusercontent.com", "linode_id": + 62182466, "region": "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": + "192.168.223.6", "gateway": null, "subnet_mask": "255.255.128.0", "prefix": + 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182466, "region": + "us-east", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.172.145", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182471, "region": "eu-west", "vpc_nat_1_1": + null, "reserved": false}, {"address": "212.71.244.79", "gateway": "212.71.244.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "212-71-244-79.ip.linodeusercontent.com", "linode_id": 62182471, "region": + "eu-west", "vpc_nat_1_1": null, "reserved": false}, {"address": "192.168.133.143", + "gateway": null, "subnet_mask": "255.255.128.0", "prefix": 17, "type": "ipv4", + "public": false, "rdns": null, "linode_id": 62182473, "region": "ap-south", + "vpc_nat_1_1": null, "reserved": false}, {"address": "139.177.186.84", "gateway": + "139.177.186.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", + "public": true, "rdns": "139-177-186-84.ip.linodeusercontent.com", "linode_id": + 62182473, "region": "ap-south", "vpc_nat_1_1": null, "reserved": false}, {"address": + "172.104.146.131", "gateway": "172.104.146.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-104-146-131.ip.linodeusercontent.com", + "linode_id": 62182475, "region": "eu-central", "vpc_nat_1_1": null, "reserved": + false}, {"address": "139.162.81.50", "gateway": "139.162.81.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-162-81-50.ip.linodeusercontent.com", + "linode_id": 62182477, "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.168.186.3", "gateway": null, "subnet_mask": "255.255.128.0", + "prefix": 17, "type": "ipv4", "public": false, "rdns": null, "linode_id": 62182477, + "region": "ap-northeast", "vpc_nat_1_1": null, "reserved": false}, {"address": + "139.144.218.154", "gateway": "139.144.218.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "139-144-218-154.ip.linodeusercontent.com", + "linode_id": 62361598, "region": "us-iad", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.233.175.36", "gateway": "172.233.175.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-233-175-36.ip.linodeusercontent.com", + "linode_id": 63198551, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.125.198", "gateway": "172.236.125.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-125-198.ip.linodeusercontent.com", + "linode_id": 63219315, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.236.125.199", "gateway": "172.236.125.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-236-125-199.ip.linodeusercontent.com", + "linode_id": 63219421, "region": "us-ord", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.29.18", "gateway": "172.235.29.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-29-18.ip.linodeusercontent.com", + "linode_id": 63219480, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.29.23", "gateway": "172.235.29.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-29-23.ip.linodeusercontent.com", + "linode_id": 63219566, "region": "in-maa", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.234.56.7", "gateway": "172.234.56.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-234-56-7.ip.linodeusercontent.com", + "linode_id": 63219603, "region": "fr-par", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.232.34.104", "gateway": "172.232.34.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-232-34-104.ip.linodeusercontent.com", + "linode_id": 63219704, "region": "fr-par", "vpc_nat_1_1": null, "reserved": + false}, {"address": "66.228.42.218", "gateway": "66.228.42.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "66-228-42-218.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "50.116.63.168", "gateway": "50.116.63.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "50-116-63-168.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "23.92.20.39", "gateway": "23.92.20.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "23-92-20-39.ip.linodeusercontent.com", + "linode_id": 63262077, "region": "us-east", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.143.164", "gateway": "172.235.143.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-143-164.ip.linodeusercontent.com", + "linode_id": 63523131, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "172.235.134.163", "gateway": "172.235.134.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-235-134-163.ip.linodeusercontent.com", + "linode_id": 63523611, "region": "us-mia", "vpc_nat_1_1": null, "reserved": + false}, {"address": "192.46.210.101", "gateway": "192.46.210.1", "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": true, "rdns": "192-46-210-101.ip.linodeusercontent.com", + "linode_id": 64701046, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + false}]}' + 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: + - Tue, 01 Oct 2024 18:02:12 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - ips: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/linode/instances/64701046 method: DELETE response: body: '{}' @@ -791,7 +1980,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:32:54 GMT + - Tue, 01 Oct 2024 18:02:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -806,12 +1995,9 @@ interactions: - DENY - DENY X-Oauth-Scopes: - - account:read_write databases:read_write domains:read_write events:read_write - firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write - longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write - volumes:read_write vpc:read_write + - '*' X-Ratelimit-Limit: - - "400" + - "800" X-Xss-Protection: - 1; mode=block status: 200 OK From 25bcf8179e56aa67a389be5f2f24c1a6c8cdc8bd Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 7 Oct 2024 16:00:09 -0400 Subject: [PATCH 39/43] changed the name of the test function to keeop it more succinct --- test/integration/network_reserved_ips_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/network_reserved_ips_test.go b/test/integration/network_reserved_ips_test.go index 0e90cb350..725be3f2e 100644 --- a/test/integration/network_reserved_ips_test.go +++ b/test/integration/network_reserved_ips_test.go @@ -392,7 +392,7 @@ func TestReservedIPAddresses_DeleteIPAddressVariants(t *testing.T) { } } -func TestReservedIPAddresses_GetInstanceIPReservationStatus(t *testing.T) { +func TestReservedIPAddresses_GetIPReservationStatus(t *testing.T) { client, teardown := createTestClient(t, "TestReservedIPAddresses_GetInstanceIPReservationStatus") defer teardown() From 62d25507c3730ea54b1528696c077695f965de87 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Tue, 29 Oct 2024 15:24:11 -0400 Subject: [PATCH 40/43] setting reserved as an optional field --- network_ips.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_ips.go b/network_ips.go index 450e87523..d61f9380c 100644 --- a/network_ips.go +++ b/network_ips.go @@ -7,7 +7,7 @@ import ( // IPAddressUpdateOptions fields are those accepted by UpdateToken type IPAddressUpdateOptions struct { // The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to a default value provided by Linode if set to nil. - Reserved bool `json:"reserved"` + Reserved bool `json:"reserved,omitempty"` RDNS *string `json:"rdns,omitempty"` } From 478928797c848e454b3516669e6ddb27949128ab Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Fri, 8 Nov 2024 11:51:42 -0500 Subject: [PATCH 41/43] Made change to make reserved a part of the update IP address functionality --- network_ips.go | 2 +- .../fixtures/TestIPAddress_Update.yaml | 543 +++++++++--------- 2 files changed, 276 insertions(+), 269 deletions(-) diff --git a/network_ips.go b/network_ips.go index d61f9380c..450e87523 100644 --- a/network_ips.go +++ b/network_ips.go @@ -7,7 +7,7 @@ import ( // IPAddressUpdateOptions fields are those accepted by UpdateToken type IPAddressUpdateOptions struct { // The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to a default value provided by Linode if set to nil. - Reserved bool `json:"reserved,omitempty"` + Reserved bool `json:"reserved"` RDNS *string `json:"rdns,omitempty"` } diff --git a/test/integration/fixtures/TestIPAddress_Update.yaml b/test/integration/fixtures/TestIPAddress_Update.yaml index 483422079..bdd11d62c 100644 --- a/test/integration/fixtures/TestIPAddress_Update.yaml +++ b/test/integration/fixtures/TestIPAddress_Update.yaml @@ -36,17 +36,18 @@ interactions: 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", - "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5, 172.105.169.5, - 172.105.168.5, 172.105.172.5, 172.105.162.5, 172.105.170.5, 172.105.167.5, 172.105.171.5, - 172.105.181.5, 172.105.161.5", "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, - 2400:8907::f03c:92ff:fe6e:1c58, 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, - 2400:8907::f03c:92ff:fe6e:c219, 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, - 2400:8907::f03c:92ff:fe6e:e6b, 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": + "172.105.166.5, 172.105.169.5, 172.105.168.5, 172.105.172.5, 172.105.162.5, + 172.105.170.5, 172.105.167.5, 172.105.171.5, 172.105.181.5, 172.105.161.5", + "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, 2400:8907::f03c:92ff:fe6e:1c58, + 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, 2400:8907::f03c:92ff:fe6e:c219, + 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, 2400:8907::f03c:92ff:fe6e:e6b, + 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-iad", "label": + "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, @@ -57,28 +58,29 @@ interactions: 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": - ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", - "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, - 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", - "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, 2600:3c06::f03c:93ff:fed0:e572, - 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, 2600:3c06::f03c:93ff:fed0:e511, - 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, 2600:3c06::f03c:93ff:fed0:e529, - 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": - "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, - 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, - 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, - 2600:3c07::f03c:93ff:fef2:2ec7, 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, - 2600:3c07::f03c:93ff:fef2:0de0, 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, - 2600:3c07::f03c:93ff:fef2:0d82, 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, - "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": - "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, + 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, + 172.232.0.15, 172.232.0.18", "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, + 2600:3c06::f03c:93ff:fed0:e572, 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, + 2600:3c06::f03c:93ff:fed0:e511, 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, + 2600:3c06::f03c:93ff:fed0:e529, 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": + ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, + 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, + 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, 2600:3c07::f03c:93ff:fef2:2ec7, + 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, 2600:3c07::f03c:93ff:fef2:0de0, + 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, 2600:3c07::f03c:93ff:fef2:0d82, + 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": + ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, @@ -89,90 +91,90 @@ interactions: 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, 172.233.0.7, - 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, 172.233.0.8, - 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, 2600:3c0d::f03c:93ff:fe3d:51a7, - 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, 2600:3c0d::f03c:93ff:fe3d:51fe, - 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, 2600:3c0d::f03c:93ff:fe3d:5170, - 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", - "resolvers": {"ipv4": "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, - 172.233.33.34, 172.233.33.33, 172.233.33.31, 172.233.33.30, 172.233.33.37, 172.233.33.32", - "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, - 2600:3c0e::f03c:93ff:fe9d:2d96, 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, - 2600:3c0e::f03c:93ff:fe9d:2d68, 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, - 2600:3c0e::f03c:93ff:fe9d:2d5c"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "se-sto", "label": - "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, - 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, - 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, 2600:3c09::f03c:93ff:fea9:4d63, - 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, 2600:3c09::f03c:93ff:fea9:4d99, - 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, 2600:3c09::f03c:93ff:fea9:4d69, - 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, - 172.233.111.25, 172.233.111.19, 172.233.111.12, 172.233.111.26, 172.233.111.16, - 172.233.111.18, 172.233.111.9", "ipv6": "2a01:7e02::f03c:93ff:feea:b585, 2a01:7e02::f03c:93ff:feea:b5ab, - 2a01:7e02::f03c:93ff:feea:b5c6, 2a01:7e02::f03c:93ff:feea:b592, 2a01:7e02::f03c:93ff:feea:b5aa, - 2a01:7e02::f03c:93ff:feea:b5d3, 2a01:7e02::f03c:93ff:feea:b5d7, 2a01:7e02::f03c:93ff:feea:b528, - 2a01:7e02::f03c:93ff:feea:b522, 2a01:7e02::f03c:93ff:feea:b51a"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": "in", "capabilities": - ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", - "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, - 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", - "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, - 2600:3c08::f03c:93ff:fe7c:11a7, 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, - 2600:3c08::f03c:93ff:fe7c:11f9, 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, - 2600:3c08::f03c:93ff:fe7c:1164"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": - "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, - 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, - 172.233.64.42, 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, - 2400:8905::f03c:93ff:fe9d:b012, 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, - 2400:8905::f03c:93ff:fe9d:259f, 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, - 2400:8905::f03c:93ff:fe9d:b0ce, 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.0.4, + 172.233.0.9, 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, + 172.233.0.6, 172.233.0.8, 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, + 2600:3c0d::f03c:93ff:fe3d:51a7, 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, + 2600:3c0d::f03c:93ff:fe3d:51fe, 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, + 2600:3c0d::f03c:93ff:fe3d:5170, 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": + "nl", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.33.36, + 172.233.33.38, 172.233.33.35, 172.233.33.39, 172.233.33.34, 172.233.33.33, 172.233.33.31, + 172.233.33.30, 172.233.33.37, 172.233.33.32", "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, + 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, 2600:3c0e::f03c:93ff:fe9d:2d96, + 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, 2600:3c0e::f03c:93ff:fe9d:2d68, + 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, 2600:3c0e::f03c:93ff:fe9d:2d5c"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": - "it", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + 5}, "site_type": "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": + "se", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.128.24, + 172.232.128.26, 172.232.128.20, 172.232.128.22, 172.232.128.25, 172.232.128.19, + 172.232.128.23, 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, + 2600:3c09::f03c:93ff:fea9:4d63, 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, + 2600:3c09::f03c:93ff:fea9:4d99, 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, + 2600:3c09::f03c:93ff:fea9:4d69, 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": + "es", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, - 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", - "ipv6": "2600:3c0b::f03c:93ff:feba:d513, 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, - 2600:3c0b::f03c:93ff:feba:d5fb, 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, - 2600:3c0b::f03c:93ff:feba:d5d5, 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, - 2600:3c0b::f03c:93ff:feba:d529"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": - "Miami, FL", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, - 172.233.160.29, 172.233.160.32, 172.233.160.28, 172.233.160.33, 172.233.160.26, - 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, 2a01:7e04::f03c:93ff:fead:d37f, - 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, 2a01:7e04::f03c:93ff:fead:d316, - 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, 2a01:7e04::f03c:93ff:fead:d395, - 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, "placement_group_limits": + {"ipv4": "172.233.111.6,172.233.111.17,172.233.111.21,172.233.111.25,172.233.111.19,172.233.111.12,172.233.111.26,172.233.111.16,172.233.111.18,172.233.111.9", + "ipv6": "2a01:7e02::f03c:93ff:feea:b585,2a01:7e02::f03c:93ff:feea:b5ab,2a01:7e02::f03c:93ff:feea:b5c6,2a01:7e02::f03c:93ff:feea:b592,2a01:7e02::f03c:93ff:feea:b5aa,2a01:7e02::f03c:93ff:feea:b5d3,2a01:7e02::f03c:93ff:feea:b5d7,2a01:7e02::f03c:93ff:feea:b528,2a01:7e02::f03c:93ff:feea:b522,2a01:7e02::f03c:93ff:feea:b51a"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": + "in", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.96.17, + 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, + 172.232.96.22, 172.232.96.23, 172.232.96.24", "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, + 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, 2600:3c08::f03c:93ff:fe7c:11a7, + 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, 2600:3c08::f03c:93ff:fe7c:11f9, + 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, 2600:3c08::f03c:93ff:fe7c:1164"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "jp-osa", "label": "Osaka, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement + Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, 172.233.64.43, + 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, 172.233.64.42, + 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, 2400:8905::f03c:93ff:fe9d:b012, + 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, 2400:8905::f03c:93ff:fe9d:259f, + 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, 2400:8905::f03c:93ff:fe9d:b0ce, + 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "core"}, {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, + 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, + 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", "ipv6": "2600:3c0b::f03c:93ff:feba:d513, + 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, 2600:3c0b::f03c:93ff:feba:d5fb, + 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, 2600:3c0b::f03c:93ff:feba:d5d5, + 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, 2600:3c0b::f03c:93ff:feba:d529"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-mia", "label": "Miami, FL", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.160.34, + 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, 172.233.160.28, + 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, + 2a01:7e04::f03c:93ff:fead:d37f, 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, + 2a01:7e04::f03c:93ff:fead:d316, 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, + 2a01:7e04::f03c:93ff:fead:d395, 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": + "id", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, @@ -192,35 +194,44 @@ interactions: 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, 2a01:7e03::f03c:93ff:feb1:b76e, 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": - "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": - "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "au", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": - "in", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "in", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": - "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "de", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", + "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": + {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": - "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "sg", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud + Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], + "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "jp-tyo-3", "label": "Tokyo 3, JP", "country": + "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.237.4.15,172.237.4.19,172.237.4.17,172.237.4.21,172.237.4.16,172.237.4.18,172.237.4.23,172.237.4.24,172.237.4.20,172.237.4.14", + "ipv6": "2600:3c18::f03c:95ff:fe99:c783,2600:3c18::f03c:95ff:fe99:c70f,2600:3c18::f03c:95ff:fe99:c7c8,2600:3c18::f03c:95ff:fe99:c7c2,2600:3c18::f03c:95ff:fe99:c7fc,2600:3c18::f03c:95ff:fe99:c784,2600:3c18::f03c:95ff:fe99:c70e,2600:3c18::f03c:95ff:fe99:c7e7,2600:3c18::f03c:95ff:fe99:c78b,2600:3c18::f03c:95ff:fe99:c715"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", @@ -231,53 +242,50 @@ interactions: 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": + "173.230.145.5, 173.230.147.5, 173.230.155.5, 173.255.212.5, 173.255.219.5, + 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, 74.207.242.5", "ipv6": + "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, + 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, 2600:3c01::6"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": + ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "74.207.231.5,173.230.128.5,173.230.129.5,173.230.136.5,173.230.140.5,66.228.59.5,66.228.62.5,50.116.35.5,50.116.41.5,23.239.18.5", + "ipv6": "2600:3c02::3,2600:3c02::5,2600:3c02::4,2600:3c02::6,2600:3c02::c,2600:3c02::7,2600:3c02::2,2600:3c02::9,2600:3c02::8,2600:3c02::b"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": + "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, + 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, 207.192.69.5", + "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, 2600:3c03::3, + 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": + "core"}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", - "Placement Group"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, - 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, - 74.207.241.5, 74.207.242.5", "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, - 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, - 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": - "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Placement Group"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, + 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, 109.74.192.20, + 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, 2a01:7e00::3, 2a01:7e00::c, + 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, 2a01:7e00::4, 2a01:7e00::7, + 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": null, + "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", "label": + "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, - 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, - 50.116.41.5, 23.239.18.5", "ipv6": "2600:3c02::3, 2600:3c02::5, 2600:3c02::4, - 2600:3c02::6, 2600:3c02::c, 2600:3c02::7, 2600:3c02::2, 2600:3c02::9, 2600:3c02::8, - 2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": - "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, - 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, - 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, - 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, + Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5,139.162.13.5,139.162.14.5,139.162.15.5,139.162.16.5,139.162.21.5,139.162.27.5,103.3.60.18,103.3.60.19,103.3.60.20", + "ipv6": "2400:8901::5,2400:8901::4,2400:8901::b,2400:8901::3,2400:8901::9,2400:8901::2,2400:8901::8,2400:8901::7,2400:8901::c,2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": - "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": - "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, - 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, - 2a01:7e00::3, 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, - 2a01:7e00::4, 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", - "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, - 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, - 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": "2400:8901::5, 2400:8901::4, - 2400:8901::b, 2400:8901::3, 2400:8901::9, 2400:8901::2, 2400:8901::8, 2400:8901::7, - 2400:8901::c, 2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", - "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + 5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": + "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": + "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": @@ -287,7 +295,7 @@ interactions: {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 30}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 31}' headers: Access-Control-Allow-Credentials: - "true" @@ -310,7 +318,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:13 GMT + - Wed, 30 Oct 2024 15:43:11 GMT Pragma: - no-cache Strict-Transport-Security: @@ -336,7 +344,7 @@ interactions: code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-1xza1u1t95z0","booted":false}' + body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-kdg6zpd73431","booted":false}' form: {} headers: Accept: @@ -348,17 +356,17 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 64975249, "label": "go-test-ins-wo-disk-1xza1u1t95z0", "group": + body: '{"id": 66290506, "label": "go-test-ins-wo-disk-kdg6zpd73431", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["45.79.123.50"], "ipv6": "2400:8904::f03c:95ff:fe8c:08e4/128", + "type": "g6-nanode-1", "ipv4": ["172.105.54.4"], "ipv6": "2400:8904::f03c:95ff:fed2:9187/128", "image": null, "region": "ap-west", "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": "915afd6c961c0333afa335a52a655d656beae128", "has_user_data": + true, "tags": [], "host_uuid": "2e7e621b06c3a54cd9ae471f05a1316ee6ce8f0d", "has_user_data": false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": - null, "capabilities": []}' + null, "capabilities": ["SMTP Enabled"]}' headers: Access-Control-Allow-Credentials: - "true" @@ -376,20 +384,19 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "857" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:14 GMT + - Wed, 30 Oct 2024 15:43:12 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: @@ -400,14 +407,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "10" + - "5" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"go-test-conf-iz7ha58g3b23","devices":{},"interfaces":null}' + body: '{"label":"go-test-conf-673jfv981wzd","devices":{},"interfaces":null}' form: {} headers: Accept: @@ -416,10 +423,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/64975249/configs + url: https://api.linode.com/v4beta/linode/instances/66290506/configs method: POST response: - body: '{"id": 68264745, "label": "go-test-conf-iz7ha58g3b23", "helpers": {"updatedb_disabled": + body: '{"id": 69601357, "label": "go-test-conf-673jfv981wzd", "helpers": {"updatedb_disabled": true, "distro": true, "modules_dep": true, "network": false, "devtmpfs_automount": true}, "kernel": "linode/latest-64bit", "comments": "", "memory_limit": 0, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "root_device": "/dev/sda", @@ -450,7 +457,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:14 GMT + - Wed, 30 Oct 2024 15:43:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -483,19 +490,19 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/64975249/ips + url: https://api.linode.com/v4beta/linode/instances/66290506/ips method: GET response: - body: '{"ipv4": {"public": [{"address": "45.79.123.50", "gateway": "45.79.123.1", + body: '{"ipv4": {"public": [{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, - "rdns": "45-79-123-50.ip.linodeusercontent.com", "linode_id": 64975249, "region": + "rdns": "172-105-54-4.ip.linodeusercontent.com", "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}], "private": [], "shared": - [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2400:8904::f03c:95ff:fe8c:08e4", + [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2400:8904::f03c:95ff:fed2:9187", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 64975249, "region": "ap-west", "public": - true}, "link_local": {"address": "fe80::f03c:95ff:fe8c:08e4", "gateway": "fe80::1", + "type": "ipv6", "rdns": null, "linode_id": 66290506, "region": "ap-west", "public": + true}, "link_local": {"address": "fe80::f03c:95ff:fed2:9187", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": - null, "linode_id": 64975249, "region": "ap-west", "public": false}, "global": + null, "linode_id": 66290506, "region": "ap-west", "public": false}, "global": []}}' headers: Access-Control-Allow-Credentials: @@ -515,13 +522,13 @@ interactions: Connection: - keep-alive Content-Length: - - "813" + - "814" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:14 GMT + - Wed, 30 Oct 2024 15:43:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -546,7 +553,7 @@ interactions: code: 200 duration: "" - request: - body: '{"reserved":false,"rdns":"45-79-123-50.ip.linodeusercontent.com"}' + body: '{"reserved":false,"rdns":"172-105-54-4.ip.linodeusercontent.com"}' form: {} headers: Accept: @@ -555,12 +562,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/45.79.123.50 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.4 method: PUT response: - body: '{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-123-50.ip.linodeusercontent.com", - "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-4.ip.linodeusercontent.com", + "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -580,13 +587,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "265" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:15 GMT + - Wed, 30 Oct 2024 15:43:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -619,12 +626,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/45.79.123.50 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.4 method: PUT response: - body: '{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-123-50.ip.linodeusercontent.com", - "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-4.ip.linodeusercontent.com", + "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -644,13 +651,13 @@ interactions: Connection: - keep-alive Content-Length: - - "263" + - "264" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:15 GMT + - Wed, 30 Oct 2024 15:43:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -686,8 +693,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.79.120.251", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-251.ip.linodeusercontent.com", + body: '{"address": "172.105.43.77", "gateway": "172.105.43.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-77.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -707,13 +714,13 @@ interactions: Connection: - keep-alive Content-Length: - - "261" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:15 GMT + - Wed, 30 Oct 2024 15:43:13 GMT Pragma: - no-cache Strict-Transport-Security: @@ -746,11 +753,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/45.79.120.251 + url: https://api.linode.com/v4beta/networking/ips/172.105.43.77 method: PUT response: - body: '{"address": "45.79.120.251", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-251.ip.linodeusercontent.com", + body: '{"address": "172.105.43.77", "gateway": "172.105.43.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-77.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -770,13 +777,13 @@ interactions: Connection: - keep-alive Content-Length: - - "261" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:15 GMT + - Wed, 30 Oct 2024 15:43:13 GMT Pragma: - no-cache Strict-Transport-Security: @@ -809,12 +816,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/45.79.123.50 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.4 method: PUT response: - body: '{"address": "45.79.123.50", "gateway": "45.79.123.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-123-50.ip.linodeusercontent.com", - "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-4.ip.linodeusercontent.com", + "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -834,13 +841,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "265" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:16 GMT + - Wed, 30 Oct 2024 15:43:13 GMT Pragma: - no-cache Strict-Transport-Security: @@ -876,8 +883,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "45.79.120.253", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-253.ip.linodeusercontent.com", + body: '{"address": "172.105.43.7", "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-7.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -897,13 +904,13 @@ interactions: Connection: - keep-alive Content-Length: - - "261" + - "260" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:16 GMT + - Wed, 30 Oct 2024 15:43:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -927,7 +934,7 @@ interactions: code: 200 duration: "" - request: - body: '{"region":"ap-west","assignments":[{"address":"45.79.120.253","linode_id":64975249}]}' + body: '{"region":"ap-west","assignments":[{"address":"172.105.43.7","linode_id":66290506}]}' form: {} headers: Accept: @@ -964,7 +971,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:16 GMT + - Wed, 30 Oct 2024 15:43:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -997,12 +1004,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/45.79.120.253 + url: https://api.linode.com/v4beta/networking/ips/172.105.43.7 method: PUT response: - body: '{"address": "45.79.120.253", "gateway": "45.79.120.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-120-253.ip.linodeusercontent.com", - "linode_id": 64975249, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.43.7", "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-7.ip.linodeusercontent.com", + "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -1022,13 +1029,13 @@ interactions: Connection: - keep-alive Content-Length: - - "266" + - "265" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:17 GMT + - Wed, 30 Oct 2024 15:43:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1064,8 +1071,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.52.26", "gateway": "172.105.52.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-26.ip.linodeusercontent.com", + body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1091,7 +1098,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:17 GMT + - Wed, 30 Oct 2024 15:43:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1124,7 +1131,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.52.26 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 method: PUT response: body: '{"errors": [{"reason": "Domain is not valid.", "field": "rdns"}]}' @@ -1144,7 +1151,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:17 GMT + - Wed, 30 Oct 2024 15:43:14 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1189,7 +1196,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:17 GMT + - Wed, 30 Oct 2024 15:43:15 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1231,7 +1238,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:17 GMT + - Wed, 30 Oct 2024 15:43:15 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1253,7 +1260,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.52.26 + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.54.62 method: DELETE response: body: '{}' @@ -1281,7 +1288,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:18 GMT + - Wed, 30 Oct 2024 15:43:15 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1317,8 +1324,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.52.110", "gateway": "172.105.52.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-110.ip.linodeusercontent.com", + body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1338,13 +1345,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:18 GMT + - Wed, 30 Oct 2024 15:43:15 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1377,11 +1384,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.52.110 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 method: PUT response: - body: '{"address": "172.105.52.110", "gateway": "172.105.52.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-110.ip.linodeusercontent.com", + body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1401,13 +1408,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:18 GMT + - Wed, 30 Oct 2024 15:43:16 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1440,7 +1447,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.52.110 + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.54.62 method: DELETE response: body: '{}' @@ -1468,7 +1475,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:18 GMT + - Wed, 30 Oct 2024 15:43:16 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1504,8 +1511,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.52.41", "gateway": "172.105.52.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-41.ip.linodeusercontent.com", + body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1531,7 +1538,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:19 GMT + - Wed, 30 Oct 2024 15:43:16 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1564,11 +1571,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.52.41 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 method: PUT response: - body: '{"address": "172.105.52.41", "gateway": "172.105.52.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-52-41.ip.linodeusercontent.com", + body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -1594,7 +1601,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:19 GMT + - Wed, 30 Oct 2024 15:43:16 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1627,7 +1634,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.52.41 + url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -1649,7 +1656,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:19 GMT + - Wed, 30 Oct 2024 15:43:16 GMT Pragma: - no-cache Vary: @@ -1695,7 +1702,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:19 GMT + - Wed, 30 Oct 2024 15:43:16 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1719,7 +1726,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.120.253 + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.43.7 method: DELETE response: body: '{"errors": [{"reason": "Not found"}]}' @@ -1741,7 +1748,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:19 GMT + - Wed, 30 Oct 2024 15:43:17 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1765,7 +1772,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.120.251 + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.43.77 method: DELETE response: body: '{}' @@ -1793,7 +1800,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:20 GMT + - Wed, 30 Oct 2024 15:43:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1826,7 +1833,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/64975249 + url: https://api.linode.com/v4beta/linode/instances/66290506 method: DELETE response: body: '{}' @@ -1854,7 +1861,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 07 Oct 2024 16:10:23 GMT + - Wed, 30 Oct 2024 15:43:19 GMT Pragma: - no-cache Strict-Transport-Security: From b716ca281e3cdced62ff40f373e6539dd2ff75bd Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Thu, 14 Nov 2024 17:00:39 -0500 Subject: [PATCH 42/43] Removed test for exceeding IP MAX and changed the type of the reserved field in the IPAddressUpdateOptions struct --- network_ips.go | 2 +- .../fixtures/TestIPAddress_Update.yaml | 670 +++++++----------- test/integration/network_ips_test.go | 34 +- 3 files changed, 279 insertions(+), 427 deletions(-) diff --git a/network_ips.go b/network_ips.go index 450e87523..d64a01ae9 100644 --- a/network_ips.go +++ b/network_ips.go @@ -7,7 +7,7 @@ import ( // IPAddressUpdateOptions fields are those accepted by UpdateToken type IPAddressUpdateOptions struct { // The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to a default value provided by Linode if set to nil. - Reserved bool `json:"reserved"` + Reserved *bool `json:"reserved,omitempty"` RDNS *string `json:"rdns,omitempty"` } diff --git a/test/integration/fixtures/TestIPAddress_Update.yaml b/test/integration/fixtures/TestIPAddress_Update.yaml index bdd11d62c..d28dea404 100644 --- a/test/integration/fixtures/TestIPAddress_Update.yaml +++ b/test/integration/fixtures/TestIPAddress_Update.yaml @@ -17,282 +17,231 @@ interactions: body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.105.34.5, 172.105.35.5, 172.105.36.5, 172.105.37.5, 172.105.38.5, - 172.105.39.5, 172.105.40.5, 172.105.41.5, 172.105.42.5, 172.105.43.5", "ipv6": - "2400:8904::f03c:91ff:fea5:659, 2400:8904::f03c:91ff:fea5:9282, 2400:8904::f03c:91ff:fea5:b9b3, - 2400:8904::f03c:91ff:fea5:925a, 2400:8904::f03c:91ff:fea5:22cb, 2400:8904::f03c:91ff:fea5:227a, - 2400:8904::f03c:91ff:fea5:924c, 2400:8904::f03c:91ff:fea5:f7e2, 2400:8904::f03c:91ff:fea5:2205, - 2400:8904::f03c:91ff:fea5:9207"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ca-central", - "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5, 172.105.3.5, 172.105.4.5, - 172.105.5.5, 172.105.6.5, 172.105.7.5, 172.105.8.5, 172.105.9.5, 172.105.10.5, - 172.105.11.5", "ipv6": "2600:3c04::f03c:91ff:fea9:f63, 2600:3c04::f03c:91ff:fea9:f6d, - 2600:3c04::f03c:91ff:fea9:f80, 2600:3c04::f03c:91ff:fea9:f0f, 2600:3c04::f03c:91ff:fea9:f99, - 2600:3c04::f03c:91ff:fea9:fbd, 2600:3c04::f03c:91ff:fea9:fdd, 2600:3c04::f03c:91ff:fea9:fe2, - 2600:3c04::f03c:91ff:fea9:f68, 2600:3c04::f03c:91ff:fea9:f4a"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": "au", "capabilities": - ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": - "172.105.166.5, 172.105.169.5, 172.105.168.5, 172.105.172.5, 172.105.162.5, - 172.105.170.5, 172.105.167.5, 172.105.171.5, 172.105.181.5, 172.105.161.5", - "ipv6": "2400:8907::f03c:92ff:fe6e:ec8, 2400:8907::f03c:92ff:fe6e:98e4, 2400:8907::f03c:92ff:fe6e:1c58, - 2400:8907::f03c:92ff:fe6e:c299, 2400:8907::f03c:92ff:fe6e:c210, 2400:8907::f03c:92ff:fe6e:c219, - 2400:8907::f03c:92ff:fe6e:1c5c, 2400:8907::f03c:92ff:fe6e:c24e, 2400:8907::f03c:92ff:fe6e:e6b, - 2400:8907::f03c:92ff:fe6e:e3d"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-iad", "label": - "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", - "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, - 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, - 139.144.192.68", "ipv6": "2600:3c05::f03c:93ff:feb6:43b6, 2600:3c05::f03c:93ff:feb6:4365, - 2600:3c05::f03c:93ff:feb6:43c2, 2600:3c05::f03c:93ff:feb6:e441, 2600:3c05::f03c:93ff:feb6:94ef, - 2600:3c05::f03c:93ff:feb6:94ba, 2600:3c05::f03c:93ff:feb6:94a8, 2600:3c05::f03c:93ff:feb6:9413, - 2600:3c05::f03c:93ff:feb6:9443, 2600:3c05::f03c:93ff:feb6:94e0"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": - ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, - 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, - 172.232.0.15, 172.232.0.18", "ipv6": "2600:3c06::f03c:93ff:fed0:e5fc, 2600:3c06::f03c:93ff:fed0:e54b, - 2600:3c06::f03c:93ff:fed0:e572, 2600:3c06::f03c:93ff:fed0:e530, 2600:3c06::f03c:93ff:fed0:e597, - 2600:3c06::f03c:93ff:fed0:e511, 2600:3c06::f03c:93ff:fed0:e5f2, 2600:3c06::f03c:93ff:fed0:e5bf, - 2600:3c06::f03c:93ff:fed0:e529, 2600:3c06::f03c:93ff:fed0:e5a3"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": - ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, - 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, - 172.232.32.11, 172.232.32.12", "ipv6": "2600:3c07::f03c:93ff:fef2:2e63, 2600:3c07::f03c:93ff:fef2:2ec7, - 2600:3c07::f03c:93ff:fef2:0dee, 2600:3c07::f03c:93ff:fef2:0d25, 2600:3c07::f03c:93ff:fef2:0de0, - 2600:3c07::f03c:93ff:fef2:2e29, 2600:3c07::f03c:93ff:fef2:0dda, 2600:3c07::f03c:93ff:fef2:0d82, - 2600:3c07::f03c:93ff:fef2:b3ac, 2600:3c07::f03c:93ff:fef2:b3a8"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": - ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, - 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, 172.232.160.11, - 172.232.160.14, 172.232.160.16", "ipv6": "2600:3c0a::f03c:93ff:fe54:c6da, 2600:3c0a::f03c:93ff:fe54:c691, - 2600:3c0a::f03c:93ff:fe54:c68d, 2600:3c0a::f03c:93ff:fe54:c61e, 2600:3c0a::f03c:93ff:fe54:c653, - 2600:3c0a::f03c:93ff:fe54:c64c, 2600:3c0a::f03c:93ff:fe54:c68a, 2600:3c0a::f03c:93ff:fe54:c697, - 2600:3c0a::f03c:93ff:fe54:c60f, 2600:3c0a::f03c:93ff:fe54:c6a0"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": - ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.0.4, - 172.233.0.9, 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, - 172.233.0.6, 172.233.0.8, 172.233.0.11", "ipv6": "2600:3c0d::f03c:93ff:fe3d:51cb, - 2600:3c0d::f03c:93ff:fe3d:51a7, 2600:3c0d::f03c:93ff:fe3d:51a9, 2600:3c0d::f03c:93ff:fe3d:5119, - 2600:3c0d::f03c:93ff:fe3d:51fe, 2600:3c0d::f03c:93ff:fe3d:517c, 2600:3c0d::f03c:93ff:fe3d:5144, - 2600:3c0d::f03c:93ff:fe3d:5170, 2600:3c0d::f03c:93ff:fe3d:51cc, 2600:3c0d::f03c:93ff:fe3d:516c"}, + "Managed Databases", "Metadata", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "172.105.34.5,172.105.35.5,172.105.36.5,172.105.37.5,172.105.38.5,172.105.39.5,172.105.40.5,172.105.41.5,172.105.42.5,172.105.43.5", + "ipv6": "2400:8904:e001:264::1,2400:8904:e001:264::2,2400:8904:e001:264::3,2400:8904:e001:264::4,2400:8904:e001:264::5,2400:8904:e001:264::6,2400:8904:e001:264::7,2400:8904:e001:264::8,2400:8904:e001:264::9,2400:8904:e001:264::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ca-central", "label": "Toronto, CA", "country": + "ca", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "172.105.0.5,172.105.3.5,172.105.4.5,172.105.5.5,172.105.6.5,172.105.7.5,172.105.8.5,172.105.9.5,172.105.10.5,172.105.11.5", + "ipv6": "2600:3c04:e001:305::1,2600:3c04:e001:305::2,2600:3c04:e001:305::3,2600:3c04:e001:305::4,2600:3c04:e001:305::5,2600:3c04:e001:305::6,2600:3c04:e001:305::7,2600:3c04:e001:305::8,2600:3c04:e001:305::9,2600:3c04:e001:305::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "ap-southeast", "label": "Sydney, AU", "country": + "au", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "172.105.166.5,172.105.169.5,172.105.168.5,172.105.172.5,172.105.162.5,172.105.170.5,172.105.167.5,172.105.171.5,172.105.181.5,172.105.161.5", + "ipv6": "2400:8907:e001:294::1,2400:8907:e001:294::2,2400:8907:e001:294::3,2400:8907:e001:294::4,2400:8907:e001:294::5,2400:8907:e001:294::6,2400:8907:e001:294::7,2400:8907:e001:294::8,2400:8907:e001:294::9,2400:8907:e001:294::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-iad", "label": "Washington, DC", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": + "139.144.192.62,139.144.192.60,139.144.192.61,139.144.192.53,139.144.192.54,139.144.192.67,139.144.192.69,139.144.192.66,139.144.192.52,139.144.192.68", + "ipv6": "2600:3c05:e001:bc::1,2600:3c05:e001:bc::2,2600:3c05:e001:bc::3,2600:3c05:e001:bc::4,2600:3c05:e001:bc::5,2600:3c05:e001:bc::6,2600:3c05:e001:bc::7,2600:3c05:e001:bc::8,2600:3c05:e001:bc::9,2600:3c05:e001:bc::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": + {"ipv4": "172.232.0.17,172.232.0.16,172.232.0.21,172.232.0.13,172.232.0.22,172.232.0.9,172.232.0.19,172.232.0.20,172.232.0.15,172.232.0.18", + "ipv6": "2600:3c06:e001:67::1,2600:3c06:e001:67::2,2600:3c06:e001:67::3,2600:3c06:e001:67::4,2600:3c06:e001:67::5,2600:3c06:e001:67::6,2600:3c06:e001:67::7,2600:3c06:e001:67::8,2600:3c06:e001:67::9,2600:3c06:e001:67::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "fr-par", "label": "Paris, FR", "country": + "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": + {"ipv4": "172.232.32.21,172.232.32.23,172.232.32.17,172.232.32.18,172.232.32.16,172.232.32.22,172.232.32.20,172.232.32.14,172.232.32.11,172.232.32.12", + "ipv6": "2600:3c07:e001:9a::1,2600:3c07:e001:9a::2,2600:3c07:e001:9a::3,2600:3c07:e001:9a::4,2600:3c07:e001:9a::5,2600:3c07:e001:9a::6,2600:3c07:e001:9a::7,2600:3c07:e001:9a::8,2600:3c07:e001:9a::9,2600:3c07:e001:9a::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", + "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": "172.232.160.19,172.232.160.21,172.232.160.17,172.232.160.15,172.232.160.18,172.232.160.8,172.232.160.12,172.232.160.11,172.232.160.14,172.232.160.16", + "ipv6": "2600:3c0a:e001:7bb::1,2600:3c0a:e001:7bb::2,2600:3c0a:e001:7bb::3,2600:3c0a:e001:7bb::4,2600:3c0a:e001:7bb::5,2600:3c0a:e001:7bb::6,2600:3c0a:e001:7bb::7,2600:3c0a:e001:7bb::8,2600:3c0a:e001:7bb::9,2600:3c0a:e001:7bb::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": + "br", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "172.233.0.4,172.233.0.9,172.233.0.7,172.233.0.12,172.233.0.5,172.233.0.13,172.233.0.10,172.233.0.6,172.233.0.8,172.233.0.11", + "ipv6": "2600:3c0d:e001:44::1,2600:3c0d:e001:44::2,2600:3c0d:e001:44::3,2600:3c0d:e001:44::4,2600:3c0d:e001:44::5,2600:3c0d:e001:44::6,2600:3c0d:e001:44::7,2600:3c0d:e001:44::8,2600:3c0d:e001:44::9,2600:3c0d:e001:44::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "nl-ams", "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.33.36, - 172.233.33.38, 172.233.33.35, 172.233.33.39, 172.233.33.34, 172.233.33.33, 172.233.33.31, - 172.233.33.30, 172.233.33.37, 172.233.33.32", "ipv6": "2600:3c0e::f03c:93ff:fe9d:2d10, - 2600:3c0e::f03c:93ff:fe9d:2d89, 2600:3c0e::f03c:93ff:fe9d:2d79, 2600:3c0e::f03c:93ff:fe9d:2d96, - 2600:3c0e::f03c:93ff:fe9d:2da5, 2600:3c0e::f03c:93ff:fe9d:2d34, 2600:3c0e::f03c:93ff:fe9d:2d68, - 2600:3c0e::f03c:93ff:fe9d:2d17, 2600:3c0e::f03c:93ff:fe9d:2d45, 2600:3c0e::f03c:93ff:fe9d:2d5c"}, + Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": + "172.233.33.36,172.233.33.38,172.233.33.35,172.233.33.39,172.233.33.34,172.233.33.33,172.233.33.31,172.233.33.30,172.233.33.37,172.233.33.32", + "ipv6": "2600:3c0e:e001:a0::1,2600:3c0e:e001:a0::2,2600:3c0e:e001:a0::3,2600:3c0e:e001:a0::4,2600:3c0e:e001:a0::5,2600:3c0e:e001:a0::6,2600:3c0e:e001:a0::7,2600:3c0e:e001:a0::8,2600:3c0e:e001:a0::9,2600:3c0e:e001:a0::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.128.24, - 172.232.128.26, 172.232.128.20, 172.232.128.22, 172.232.128.25, 172.232.128.19, - 172.232.128.23, 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "2600:3c09::f03c:93ff:fea9:4dbe, - 2600:3c09::f03c:93ff:fea9:4d63, 2600:3c09::f03c:93ff:fea9:4dce, 2600:3c09::f03c:93ff:fea9:4dbb, - 2600:3c09::f03c:93ff:fea9:4d99, 2600:3c09::f03c:93ff:fea9:4d26, 2600:3c09::f03c:93ff:fea9:4de0, - 2600:3c09::f03c:93ff:fea9:4d69, 2600:3c09::f03c:93ff:fea9:4dbf, 2600:3c09::f03c:93ff:fea9:4da6"}, + Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": + "172.232.128.24,172.232.128.26,172.232.128.20,172.232.128.22,172.232.128.25,172.232.128.19,172.232.128.23,172.232.128.18,172.232.128.21,172.232.128.27", + "ipv6": "2600:3c09:e001:93::1,2600:3c09:e001:93::2,2600:3c09:e001:93::3,2600:3c09:e001:93::4,2600:3c09:e001:93::5,2600:3c09:e001:93::6,2600:3c09:e001:93::7,2600:3c09:e001:93::8,2600:3c09:e001:93::9,2600:3c09:e001:93::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.111.6,172.233.111.17,172.233.111.21,172.233.111.25,172.233.111.19,172.233.111.12,172.233.111.26,172.233.111.16,172.233.111.18,172.233.111.9", - "ipv6": "2a01:7e02::f03c:93ff:feea:b585,2a01:7e02::f03c:93ff:feea:b5ab,2a01:7e02::f03c:93ff:feea:b5c6,2a01:7e02::f03c:93ff:feea:b592,2a01:7e02::f03c:93ff:feea:b5aa,2a01:7e02::f03c:93ff:feea:b5d3,2a01:7e02::f03c:93ff:feea:b5d7,2a01:7e02::f03c:93ff:feea:b528,2a01:7e02::f03c:93ff:feea:b522,2a01:7e02::f03c:93ff:feea:b51a"}, + "VPCs", "Metadata", "Premium Plans", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "172.233.111.6,172.233.111.17,172.233.111.21,172.233.111.25,172.233.111.19,172.233.111.12,172.233.111.26,172.233.111.16,172.233.111.18,172.233.111.9", + "ipv6": "2a01:7e02:e001:3e::1,2a01:7e02:e001:3e::2,2a01:7e02:e001:3e::3,2a01:7e02:e001:3e::4,2a01:7e02:e001:3e::5,2a01:7e02:e001:3e::6,2a01:7e02:e001:3e::7,2a01:7e02:e001:3e::8,2a01:7e02:e001:3e::9,2a01:7e02:e001:3e::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.96.17, - 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, - 172.232.96.22, 172.232.96.23, 172.232.96.24", "ipv6": "2600:3c08::f03c:93ff:fe7c:1135, - 2600:3c08::f03c:93ff:fe7c:11f8, 2600:3c08::f03c:93ff:fe7c:11d2, 2600:3c08::f03c:93ff:fe7c:11a7, - 2600:3c08::f03c:93ff:fe7c:11ad, 2600:3c08::f03c:93ff:fe7c:110a, 2600:3c08::f03c:93ff:fe7c:11f9, - 2600:3c08::f03c:93ff:fe7c:1137, 2600:3c08::f03c:93ff:fe7c:11db, 2600:3c08::f03c:93ff:fe7c:1164"}, + Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": + "172.232.96.17,172.232.96.26,172.232.96.19,172.232.96.20,172.232.96.25,172.232.96.21,172.232.96.18,172.232.96.22,172.232.96.23,172.232.96.24", + "ipv6": "2600:3c08:e001:82::1,2600:3c08:e001:82::2,2600:3c08:e001:82::3,2600:3c08:e001:82::4,2600:3c08:e001:82::5,2600:3c08:e001:82::6,2600:3c08:e001:82::7,2600:3c08:e001:82::8,2600:3c08:e001:82::9,2600:3c08:e001:82::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44, 172.233.64.43, - 172.233.64.37, 172.233.64.40, 172.233.64.46, 172.233.64.41, 172.233.64.39, 172.233.64.42, - 172.233.64.45, 172.233.64.38", "ipv6": "2400:8905::f03c:93ff:fe9d:b085, 2400:8905::f03c:93ff:fe9d:b012, - 2400:8905::f03c:93ff:fe9d:b09b, 2400:8905::f03c:93ff:fe9d:b0d8, 2400:8905::f03c:93ff:fe9d:259f, - 2400:8905::f03c:93ff:fe9d:b006, 2400:8905::f03c:93ff:fe9d:b084, 2400:8905::f03c:93ff:fe9d:b0ce, - 2400:8905::f03c:93ff:fe9d:25ea, 2400:8905::f03c:93ff:fe9d:b086"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": - ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, - 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, - 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", "ipv6": "2600:3c0b::f03c:93ff:feba:d513, - 2600:3c0b::f03c:93ff:feba:d5c3, 2600:3c0b::f03c:93ff:feba:d597, 2600:3c0b::f03c:93ff:feba:d5fb, - 2600:3c0b::f03c:93ff:feba:d51f, 2600:3c0b::f03c:93ff:feba:d58e, 2600:3c0b::f03c:93ff:feba:d5d5, - 2600:3c0b::f03c:93ff:feba:d534, 2600:3c0b::f03c:93ff:feba:d57c, 2600:3c0b::f03c:93ff:feba:d529"}, + Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": "172.233.64.44,172.233.64.43,172.233.64.37,172.233.64.40,172.233.64.46,172.233.64.41,172.233.64.39,172.233.64.42,172.233.64.45,172.233.64.38", + "ipv6": "2400:8905:e001:d4::1,2400:8905:e001:d4::2,2400:8905:e001:d4::3,2400:8905:e001:d4::4,2400:8905:e001:d4::5,2400:8905:e001:d4::6,2400:8905:e001:d4::7,2400:8905:e001:d4::8,2400:8905:e001:d4::9,2400:8905:e001:d4::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": + "it", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "172.232.192.19,172.232.192.18,172.232.192.16,172.232.192.20,172.232.192.24,172.232.192.21,172.232.192.22,172.232.192.17,172.232.192.15,172.232.192.23", + "ipv6": "2600:3c0b:e001:56::1,2600:3c0b:e001:56::2,2600:3c0b:e001:56::3,2600:3c0b:e001:56::4,2600:3c0b:e001:56::5,2600:3c0b:e001:56::6,2600:3c0b:e001:56::7,2600:3c0b:e001:56::8,2600:3c0b:e001:56::9,2600:3c0b:e001:56::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.233.160.34, - 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, 172.233.160.28, - 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", "ipv6": "2a01:7e04::f03c:93ff:fead:d31f, - 2a01:7e04::f03c:93ff:fead:d37f, 2a01:7e04::f03c:93ff:fead:d30c, 2a01:7e04::f03c:93ff:fead:d318, - 2a01:7e04::f03c:93ff:fead:d316, 2a01:7e04::f03c:93ff:fead:d339, 2a01:7e04::f03c:93ff:fead:d367, - 2a01:7e04::f03c:93ff:fead:d395, 2a01:7e04::f03c:93ff:fead:d3d0, 2a01:7e04::f03c:93ff:fead:d38e"}, + Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": + "172.233.160.34,172.233.160.27,172.233.160.30,172.233.160.29,172.233.160.32,172.233.160.28,172.233.160.33,172.233.160.26,172.233.160.25,172.233.160.31", + "ipv6": "2a01:7e04:e001:b3::1,2a01:7e04:e001:b3::2,2a01:7e04:e001:b3::3,2a01:7e04:e001:b3::4,2a01:7e04:e001:b3::5,2a01:7e04:e001:b3::6,2a01:7e04:e001:b3::7,2a01:7e04:e001:b3::8,2a01:7e04:e001:b3::9,2a01:7e04:e001:b3::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, - 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, - 172.232.224.31, 172.232.224.28", "ipv6": "2600:3c0c::f03c:93ff:feed:a90b, 2600:3c0c::f03c:93ff:feed:a9a5, - 2600:3c0c::f03c:93ff:feed:a935, 2600:3c0c::f03c:93ff:feed:a930, 2600:3c0c::f03c:93ff:feed:a95c, - 2600:3c0c::f03c:93ff:feed:a9ad, 2600:3c0c::f03c:93ff:feed:a9f2, 2600:3c0c::f03c:93ff:feed:a9ff, - 2600:3c0c::f03c:93ff:feed:a9c8, 2600:3c0c::f03c:93ff:feed:a96b"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": - ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, 172.233.128.34, - 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, 172.233.128.44", - "ipv6": "2a01:7e03::f03c:93ff:feb1:b789, 2a01:7e03::f03c:93ff:feb1:b717, 2a01:7e03::f03c:93ff:feb1:b707, - 2a01:7e03::f03c:93ff:feb1:b7ab, 2a01:7e03::f03c:93ff:feb1:b7e2, 2a01:7e03::f03c:93ff:feb1:b709, - 2a01:7e03::f03c:93ff:feb1:b7a6, 2a01:7e03::f03c:93ff:feb1:b750, 2a01:7e03::f03c:93ff:feb1:b76e, - 2a01:7e03::f03c:93ff:feb1:b7a2"}, "placement_group_limits": {"maximum_pgs_per_customer": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "gb-lon", "label": - "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", - "ipv6": "2600:3c13::f03c:94ff:fe52:37c2,2600:3c13::f03c:94ff:fe52:37da,2600:3c13::f03c:94ff:fe52:370c,2600:3c13::f03c:94ff:fe52:37b1,2600:3c13::f03c:94ff:fe52:3743,2600:3c13::f03c:94ff:fe52:37e8,2600:3c13::f03c:94ff:fe52:37c7,2600:3c13::f03c:94ff:fe52:372d,2600:3c13::f03c:94ff:fe52:37d2,2600:3c13::f03c:94ff:fe52:3797"}, + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", + "StackScripts"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23,172.232.224.32,172.232.224.26,172.232.224.27,172.232.224.21,172.232.224.24,172.232.224.22,172.232.224.20,172.232.224.31,172.232.224.28", + "ipv6": "2600:3c0c:e001:7f3::1,2600:3c0c:e001:7f3::2,2600:3c0c:e001:7f3::3,2600:3c0c:e001:7f3::4,2600:3c0c:e001:7f3::5,2600:3c0c:e001:7f3::6,2600:3c0c:e001:7f3::7,2600:3c0c:e001:7f3::8,2600:3c0c:e001:7f3::9,2600:3c0c:e001:7f3::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": + "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", + "StackScripts"], "status": "ok", "resolvers": {"ipv4": "172.233.128.45,172.233.128.38,172.233.128.53,172.233.128.37,172.233.128.34,172.233.128.36,172.233.128.33,172.233.128.39,172.233.128.43,172.233.128.44", + "ipv6": "2a01:7e03:e001:e8::1,2a01:7e03:e001:e8::2,2a01:7e03:e001:e8::3,2a01:7e03:e001:e8::4,2a01:7e03:e001:e8::5,2a01:7e03:e001:e8::6,2a01:7e03:e001:e8::7,2a01:7e03:e001:e8::8,2a01:7e03:e001:e8::9,2a01:7e03:e001:e8::10"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "gb-lon", "label": "London 2, UK", "country": + "gb", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts"], "status": "ok", + "resolvers": {"ipv4": "172.236.0.46,172.236.0.50,172.236.0.47,172.236.0.53,172.236.0.52,172.236.0.45,172.236.0.49,172.236.0.51,172.236.0.54,172.236.0.48", + "ipv6": "2600:3c13:e001:29::1,2600:3c13:e001:29::2,2600:3c13:e001:29::3,2600:3c13:e001:29::4,2600:3c13:e001:29::5,2600:3c13:e001:29::6,2600:3c13:e001:29::7,2600:3c13:e001:29::8,2600:3c13:e001:29::9,2600:3c13:e001:29::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", - "ipv6": "2600:3c14::f03c:94ff:fe62:70bb,2600:3c14::f03c:94ff:fe62:70a0,2600:3c14::f03c:94ff:fe62:70d9,2600:3c14::f03c:94ff:fe62:7099,2600:3c14::f03c:94ff:fe62:70f1,2600:3c14::f03c:94ff:fe62:7018,2600:3c14::f03c:94ff:fe62:70b7,2600:3c14::f03c:94ff:fe62:701c,2600:3c14::f03c:94ff:fe62:703c,2600:3c14::f03c:94ff:fe62:700d"}, + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts"], "status": "ok", + "resolvers": {"ipv4": "172.236.32.23,172.236.32.35,172.236.32.30,172.236.32.28,172.236.32.32,172.236.32.33,172.236.32.27,172.236.32.37,172.236.32.29,172.236.32.34", + "ipv6": "2600:3c14:e001:15::1,2600:3c14:e001:15::2,2600:3c14:e001:15::3,2600:3c14:e001:15::4,2600:3c14:e001:15::5,2600:3c14:e001:15::6,2600:3c14:e001:15::7,2600:3c14:e001:15::8,2600:3c14:e001:15::9,2600:3c14:e001:15::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", - "ipv6": "2600:3c16::f03c:94ff:fe31:b2b4,2600:3c16::f03c:94ff:fe31:b239,2600:3c16::f03c:94ff:fe31:463b,2600:3c16::f03c:94ff:fe31:b2a8,2600:3c16::f03c:94ff:fe31:4692,2600:3c16::f03c:94ff:fe31:b26a,2600:3c16::f03c:94ff:fe31:4611,2600:3c16::f03c:94ff:fe31:b230,2600:3c16::f03c:94ff:fe31:46df,2600:3c16::f03c:94ff:fe31:46c3"}, + "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": "172.236.171.41,172.236.171.42,172.236.171.25,172.236.171.44,172.236.171.26,172.236.171.45,172.236.171.24,172.236.171.43,172.236.171.27,172.236.171.28", + "ipv6": "2600:3c16:e001:b::1,2600:3c16:e001:b::2,2600:3c16:e001:b::3,2600:3c16:e001:b::4,2600:3c16:e001:b::5,2600:3c16:e001:b::6,2600:3c16:e001:b::7,2600:3c16:e001:b::8,2600:3c16:e001:b::9,2600:3c16:e001:b::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Premium Plans", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", - "ipv6": "2600:3c17::f03c:95ff:feed:7740,2600:3c17::f03c:95ff:feed:7785,2600:3c17::f03c:95ff:feed:77f7,2600:3c17::f03c:95ff:feed:77d8,2600:3c17::f03c:95ff:feed:77f9,2600:3c17::f03c:95ff:feed:7733,2600:3c17::f03c:95ff:feed:776f,2600:3c17::f03c:95ff:feed:77eb,2600:3c17::f03c:95ff:feed:775c,2600:3c17::f03c:95ff:feed:77a8"}, + "Metadata", "Premium Plans", "Placement Group", "StackScripts"], "status": "ok", + "resolvers": {"ipv4": "172.236.203.9,172.236.203.16,172.236.203.19,172.236.203.15,172.236.203.17,172.236.203.11,172.236.203.18,172.236.203.14,172.236.203.13,172.236.203.12", + "ipv6": "2600:3c17:e001:4::1,2600:3c17:e001:4::2,2600:3c17:e001:4::3,2600:3c17:e001:4::4,2600:3c17:e001:4::5,2600:3c17:e001:4::6,2600:3c17:e001:4::7,2600:3c17:e001:4::8,2600:3c17:e001:4::9,2600:3c17:e001:4::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group"], - "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", - "ipv6": "2600:3c15::f03c:94ff:fe13:eb03,2600:3c15::f03c:94ff:fe13:74b2,2600:3c15::f03c:94ff:fe13:7462,2600:3c15::f03c:94ff:fe13:dbdb,2600:3c15::f03c:94ff:fe13:74a6,2600:3c15::f03c:94ff:fe13:dbe2,2600:3c15::f03c:94ff:fe13:74d8,2600:3c15::f03c:94ff:fe13:db12,2600:3c15::f03c:94ff:fe13:dbc3,2600:3c15::f03c:94ff:fe13:74a3"}, + Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": "172.236.129.8,172.236.129.42,172.236.129.41,172.236.129.19,172.236.129.46,172.236.129.23,172.236.129.48,172.236.129.20,172.236.129.21,172.236.129.47", + "ipv6": "2600:3c15:e001:17::1,2600:3c15:e001:17::2,2600:3c15:e001:17::3,2600:3c15:e001:17::4,2600:3c15:e001:17::5,2600:3c15:e001:17::6,2600:3c15:e001:17::7,2600:3c15:e001:17::8,2600:3c15:e001:17::9,2600:3c15:e001:17::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Premium Plans", "Placement Group"], "status": "ok", "resolvers": {"ipv4": "172.237.4.15,172.237.4.19,172.237.4.17,172.237.4.21,172.237.4.16,172.237.4.18,172.237.4.23,172.237.4.24,172.237.4.20,172.237.4.14", - "ipv6": "2600:3c18::f03c:95ff:fe99:c783,2600:3c18::f03c:95ff:fe99:c70f,2600:3c18::f03c:95ff:fe99:c7c8,2600:3c18::f03c:95ff:fe99:c7c2,2600:3c18::f03c:95ff:fe99:c7fc,2600:3c18::f03c:95ff:fe99:c784,2600:3c18::f03c:95ff:fe99:c70e,2600:3c18::f03c:95ff:fe99:c7e7,2600:3c18::f03c:95ff:fe99:c78b,2600:3c18::f03c:95ff:fe99:c715"}, + "Premium Plans", "Placement Group", "StackScripts"], "status": "ok", "resolvers": + {"ipv4": "172.237.4.15,172.237.4.19,172.237.4.17,172.237.4.21,172.237.4.16,172.237.4.18,172.237.4.23,172.237.4.24,172.237.4.20,172.237.4.14", + "ipv6": "2600:3c18:e001:4::1,2600:3c18:e001:4::2,2600:3c18:e001:4::3,2600:3c18:e001:4::4,2600:3c18:e001:4::5,2600:3c18:e001:4::6,2600:3c18:e001:4::7,2600:3c18:e001:4::8,2600:3c18:e001:4::9,2600:3c18:e001:4::10"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, - 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": - "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, 2600:3c00::8, - 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": + "Managed Databases", "Metadata", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, + 96.126.122.5, 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", + "ipv6": "2600:3c00::2, 2600:3c00::9, 2600:3c00::7, 2600:3c00::5, 2600:3c00::3, + 2600:3c00::8, 2600:3c00::6, 2600:3c00::4, 2600:3c00::c, 2600:3c00::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": {"ipv4": - "173.230.145.5, 173.230.147.5, 173.230.155.5, 173.255.212.5, 173.255.219.5, - 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, 74.207.242.5", "ipv6": - "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, 2600:3c01::7, 2600:3c01::3, 2600:3c01::8, - 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, 2600:3c01::6"}, "placement_group_limits": + Databases", "Metadata", "Placement Group", "StackScripts"], "status": "ok", + "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, 173.230.155.5, 173.255.212.5, + 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, 74.207.242.5", + "ipv6": "2600:3c01::2, 2600:3c01::9, 2600:3c01::5, 2600:3c01::7, 2600:3c01::3, + 2600:3c01::8, 2600:3c01::4, 2600:3c01::b, 2600:3c01::c, 2600:3c01::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "74.207.231.5,173.230.128.5,173.230.129.5,173.230.136.5,173.230.140.5,66.228.59.5,66.228.62.5,50.116.35.5,50.116.41.5,23.239.18.5", + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts"], + "status": "ok", "resolvers": {"ipv4": "74.207.231.5,173.230.128.5,173.230.129.5,173.230.136.5,173.230.140.5,66.228.59.5,66.228.62.5,50.116.35.5,50.116.41.5,23.239.18.5", "ipv6": "2600:3c02::3,2600:3c02::5,2600:3c02::4,2600:3c02::6,2600:3c02::c,2600:3c02::7,2600:3c02::2,2600:3c02::9,2600:3c02::8,2600:3c02::b"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, - 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, 207.192.69.5", - "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, 2600:3c03::3, - 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, "placement_group_limits": - {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", - "Placement Group"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, - 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, 109.74.192.20, - 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, 2a01:7e00::3, 2a01:7e00::c, - 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, 2a01:7e00::4, 2a01:7e00::7, - 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": null, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", "label": - "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5,139.162.13.5,139.162.14.5,139.162.15.5,139.162.16.5,139.162.21.5,139.162.27.5,103.3.60.18,103.3.60.19,103.3.60.20", + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts"], + "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, + 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, + 207.192.69.5", "ipv6": "2600:3c03::7, 2600:3c03::4, 2600:3c03::9, 2600:3c03::6, + 2600:3c03::3, 2600:3c03::c, 2600:3c03::5, 2600:3c03::b, 2600:3c03::2, 2600:3c03::8"}, + "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": + "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", + "Placement Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5, + 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, + 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": "2a01:7e00::9, 2a01:7e00::3, + 2a01:7e00::c, 2a01:7e00::5, 2a01:7e00::6, 2a01:7e00::8, 2a01:7e00::b, 2a01:7e00::4, + 2a01:7e00::7, 2a01:7e00::2"}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement + Group", "StackScripts"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5,139.162.13.5,139.162.14.5,139.162.15.5,139.162.16.5,139.162.21.5,139.162.27.5,103.3.60.18,103.3.60.19,103.3.60.20", "ipv6": "2400:8901::5,2400:8901::4,2400:8901::b,2400:8901::3,2400:8901::9,2400:8901::2,2400:8901::8,2400:8901::7,2400:8901::c,2400:8901::6"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group"], "status": - "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts"], + "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", "ipv6": "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group"], "status": "ok", "resolvers": - {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "Managed Databases", "Metadata", "Placement Group", "StackScripts"], "status": + "ok", "resolvers": {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", "ipv6": "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9"}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 31}' @@ -318,7 +267,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:11 GMT + - Thu, 14 Nov 2024 21:56:38 GMT Pragma: - no-cache Strict-Transport-Security: @@ -337,14 +286,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-kdg6zpd73431","booted":false}' + body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-wo-disk-4n35klr91l9g","booted":false}' form: {} headers: Accept: @@ -356,17 +305,17 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 66290506, "label": "go-test-ins-wo-disk-kdg6zpd73431", "group": + body: '{"id": 67107631, "label": "go-test-ins-wo-disk-4n35klr91l9g", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.105.54.4"], "ipv6": "2400:8904::f03c:95ff:fed2:9187/128", + "type": "g6-nanode-1", "ipv4": ["172.105.40.131"], "ipv6": "2400:8904::f03c:95ff:fe00:10df/128", "image": null, "region": "ap-west", "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": "2e7e621b06c3a54cd9ae471f05a1316ee6ce8f0d", "has_user_data": - false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": - null, "capabilities": ["SMTP Enabled"]}' + "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000, "accelerated_devices": + 0}, "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": "2d866f872e9163f3cdf48d9d8fc7e6649d1d54e7", + "has_user_data": false, "placement_group": null, "disk_encryption": "disabled", + "lke_cluster_id": null, "capabilities": ["SMTP Enabled"]}' headers: Access-Control-Allow-Credentials: - "true" @@ -389,7 +338,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:12 GMT + - Thu, 14 Nov 2024 21:56:39 GMT Pragma: - no-cache Strict-Transport-Security: @@ -407,14 +356,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "5" + - "8" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"go-test-conf-673jfv981wzd","devices":{},"interfaces":null}' + body: '{"label":"go-test-conf-j9a1uaa081w5","devices":{},"interfaces":null}' form: {} headers: Accept: @@ -423,10 +372,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/66290506/configs + url: https://api.linode.com/v4beta/linode/instances/67107631/configs method: POST response: - body: '{"id": 69601357, "label": "go-test-conf-673jfv981wzd", "helpers": {"updatedb_disabled": + body: '{"id": 70431776, "label": "go-test-conf-j9a1uaa081w5", "helpers": {"updatedb_disabled": true, "distro": true, "modules_dep": true, "network": false, "devtmpfs_automount": true}, "kernel": "linode/latest-64bit", "comments": "", "memory_limit": 0, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "root_device": "/dev/sda", @@ -457,7 +406,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:12 GMT + - Thu, 14 Nov 2024 21:56:39 GMT Pragma: - no-cache Strict-Transport-Security: @@ -474,7 +423,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -490,19 +439,19 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/66290506/ips + url: https://api.linode.com/v4beta/linode/instances/67107631/ips method: GET response: - body: '{"ipv4": {"public": [{"address": "172.105.54.4", "gateway": "172.105.54.1", + body: '{"ipv4": {"public": [{"address": "172.105.40.131", "gateway": "172.105.40.1", "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, - "rdns": "172-105-54-4.ip.linodeusercontent.com", "linode_id": 66290506, "region": + "rdns": "172-105-40-131.ip.linodeusercontent.com", "linode_id": 67107631, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}], "private": [], "shared": - [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2400:8904::f03c:95ff:fed2:9187", + [], "reserved": [], "vpc": []}, "ipv6": {"slaac": {"address": "2400:8904::f03c:95ff:fe00:10df", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, - "type": "ipv6", "rdns": null, "linode_id": 66290506, "region": "ap-west", "public": - true}, "link_local": {"address": "fe80::f03c:95ff:fed2:9187", "gateway": "fe80::1", + "type": "ipv6", "rdns": null, "linode_id": 67107631, "region": "ap-west", "public": + true}, "link_local": {"address": "fe80::f03c:95ff:fe00:10df", "gateway": "fe80::1", "subnet_mask": "ffff:ffff:ffff:ffff::", "prefix": 64, "type": "ipv6", "rdns": - null, "linode_id": 66290506, "region": "ap-west", "public": false}, "global": + null, "linode_id": 67107631, "region": "ap-west", "public": false}, "global": []}}' headers: Access-Control-Allow-Credentials: @@ -522,13 +471,13 @@ interactions: Connection: - keep-alive Content-Length: - - "814" + - "818" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:12 GMT + - Thu, 14 Nov 2024 21:56:39 GMT Pragma: - no-cache Strict-Transport-Security: @@ -546,14 +495,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"reserved":false,"rdns":"172-105-54-4.ip.linodeusercontent.com"}' + body: '{"rdns":"172-105-40-131.ip.linodeusercontent.com"}' form: {} headers: Accept: @@ -562,12 +511,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.4 + url: https://api.linode.com/v4beta/networking/ips/172.105.40.131 method: PUT response: - body: '{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-4.ip.linodeusercontent.com", - "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.40.131", "gateway": "172.105.40.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-40-131.ip.linodeusercontent.com", + "linode_id": 67107631, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -587,13 +536,13 @@ interactions: Connection: - keep-alive Content-Length: - - "265" + - "269" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:12 GMT + - Thu, 14 Nov 2024 21:56:40 GMT Pragma: - no-cache Strict-Transport-Security: @@ -610,7 +559,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -626,12 +575,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.4 + url: https://api.linode.com/v4beta/networking/ips/172.105.40.131 method: PUT response: - body: '{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-4.ip.linodeusercontent.com", - "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.40.131", "gateway": "172.105.40.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-40-131.ip.linodeusercontent.com", + "linode_id": 67107631, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -651,13 +600,13 @@ interactions: Connection: - keep-alive Content-Length: - - "264" + - "268" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:12 GMT + - Thu, 14 Nov 2024 21:56:40 GMT Pragma: - no-cache Strict-Transport-Security: @@ -674,7 +623,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -693,8 +642,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.43.77", "gateway": "172.105.43.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-77.ip.linodeusercontent.com", + body: '{"address": "172.105.56.60", "gateway": "172.105.56.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-56-60.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -720,7 +669,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:13 GMT + - Thu, 14 Nov 2024 21:56:40 GMT Pragma: - no-cache Strict-Transport-Security: @@ -737,7 +686,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -753,11 +702,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.43.77 + url: https://api.linode.com/v4beta/networking/ips/172.105.56.60 method: PUT response: - body: '{"address": "172.105.43.77", "gateway": "172.105.43.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-77.ip.linodeusercontent.com", + body: '{"address": "172.105.56.60", "gateway": "172.105.56.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-56-60.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -783,7 +732,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:13 GMT + - Thu, 14 Nov 2024 21:56:40 GMT Pragma: - no-cache Strict-Transport-Security: @@ -800,7 +749,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -816,12 +765,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.4 + url: https://api.linode.com/v4beta/networking/ips/172.105.40.131 method: PUT response: - body: '{"address": "172.105.54.4", "gateway": "172.105.54.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-4.ip.linodeusercontent.com", - "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "172.105.40.131", "gateway": "172.105.40.1", "subnet_mask": + "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-40-131.ip.linodeusercontent.com", + "linode_id": 67107631, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -841,13 +790,13 @@ interactions: Connection: - keep-alive Content-Length: - - "265" + - "269" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:13 GMT + - Thu, 14 Nov 2024 21:56:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -864,7 +813,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -883,8 +832,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.43.7", "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-7.ip.linodeusercontent.com", + body: '{"address": "45.79.122.120", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-120.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -904,13 +853,13 @@ interactions: Connection: - keep-alive Content-Length: - - "260" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:14 GMT + - Thu, 14 Nov 2024 21:56:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -927,14 +876,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","assignments":[{"address":"172.105.43.7","linode_id":66290506}]}' + body: '{"region":"ap-west","assignments":[{"address":"45.79.122.120","linode_id":67107631}]}' form: {} headers: Accept: @@ -971,7 +920,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:14 GMT + - Thu, 14 Nov 2024 21:56:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -988,7 +937,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1004,12 +953,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.43.7 + url: https://api.linode.com/v4beta/networking/ips/45.79.122.120 method: PUT response: - body: '{"address": "172.105.43.7", "gateway": "172.105.43.1", "subnet_mask": "255.255.255.0", - "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-43-7.ip.linodeusercontent.com", - "linode_id": 66290506, "region": "ap-west", "vpc_nat_1_1": null, "reserved": + body: '{"address": "45.79.122.120", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-120.ip.linodeusercontent.com", + "linode_id": 67107631, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -1029,13 +978,13 @@ interactions: Connection: - keep-alive Content-Length: - - "265" + - "266" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:14 GMT + - Thu, 14 Nov 2024 21:56:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1052,7 +1001,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1071,8 +1020,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", + body: '{"address": "45.79.122.105", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-105.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1092,13 +1041,13 @@ interactions: Connection: - keep-alive Content-Length: - - "262" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:14 GMT + - Thu, 14 Nov 2024 21:56:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1115,7 +1064,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1131,7 +1080,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 + url: https://api.linode.com/v4beta/networking/ips/45.79.122.105 method: PUT response: body: '{"errors": [{"reason": "Domain is not valid.", "field": "rdns"}]}' @@ -1151,7 +1100,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:14 GMT + - Thu, 14 Nov 2024 21:56:42 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1161,95 +1110,10 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" status: 400 Bad Request code: 400 duration: "" -- request: - body: '{"region":"ap-west"}' - 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: '{"errors": [{"reason": "Additional Reserved 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: - - "147" - Content-Type: - - application/json - Expires: - - Wed, 30 Oct 2024 15:43:15 GMT - Pragma: - - no-cache - X-Accepted-Oauth-Scopes: - - ips:read_write - X-Frame-Options: - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "800" - status: 400 Bad Request - code: 400 - duration: "" -- request: - body: '{"reserved":true}' - 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/ips/ - method: PUT - response: - body: '{"errors": [{"reason": "Method Not Allowed"}]}' - 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: - - '*' - Cache-Control: - - max-age=0, no-cache, no-store - Content-Length: - - "46" - Content-Type: - - application/json - Expires: - - Wed, 30 Oct 2024 15:43:15 GMT - Pragma: - - no-cache - X-Accepted-Oauth-Scopes: - - '*' - X-Frame-Options: - - DENY - X-Oauth-Scopes: - - unknown - status: 405 Method Not Allowed - code: 405 - duration: "" - request: body: "" form: {} @@ -1260,7 +1124,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.54.62 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.122.105 method: DELETE response: body: '{}' @@ -1288,7 +1152,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:15 GMT + - Thu, 14 Nov 2024 21:56:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1324,8 +1188,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", + body: '{"address": "45.79.122.105", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-105.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1345,13 +1209,13 @@ interactions: Connection: - keep-alive Content-Length: - - "262" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:15 GMT + - Thu, 14 Nov 2024 21:56:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1368,7 +1232,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1384,11 +1248,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 + url: https://api.linode.com/v4beta/networking/ips/45.79.122.105 method: PUT response: - body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", + body: '{"address": "45.79.122.105", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-105.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1408,13 +1272,13 @@ interactions: Connection: - keep-alive Content-Length: - - "262" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:16 GMT + - Thu, 14 Nov 2024 21:56:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1431,7 +1295,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1447,7 +1311,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.54.62 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.122.105 method: DELETE response: body: '{}' @@ -1475,7 +1339,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:16 GMT + - Thu, 14 Nov 2024 21:56:43 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1511,8 +1375,8 @@ interactions: url: https://api.linode.com/v4beta/networking/reserved/ips method: POST response: - body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", + body: '{"address": "45.79.122.105", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-105.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": true}' headers: Access-Control-Allow-Credentials: @@ -1532,13 +1396,13 @@ interactions: Connection: - keep-alive Content-Length: - - "262" + - "261" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:16 GMT + - Thu, 14 Nov 2024 21:56:43 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1555,7 +1419,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1571,11 +1435,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 + url: https://api.linode.com/v4beta/networking/ips/45.79.122.105 method: PUT response: - body: '{"address": "172.105.54.62", "gateway": "172.105.54.1", "subnet_mask": - "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, "rdns": "172-105-54-62.ip.linodeusercontent.com", + body: '{"address": "45.79.122.105", "gateway": "45.79.122.1", "subnet_mask": "255.255.255.0", + "prefix": 24, "type": "ipv4", "public": true, "rdns": "45-79-122-105.ip.linodeusercontent.com", "linode_id": null, "region": "ap-west", "vpc_nat_1_1": null, "reserved": false}' headers: Access-Control-Allow-Credentials: @@ -1595,13 +1459,13 @@ interactions: Connection: - keep-alive Content-Length: - - "263" + - "262" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:16 GMT + - Thu, 14 Nov 2024 21:56:43 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1618,7 +1482,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1634,7 +1498,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/ips/172.105.54.62 + url: https://api.linode.com/v4beta/networking/ips/45.79.122.105 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -1656,7 +1520,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:16 GMT + - Thu, 14 Nov 2024 21:56:43 GMT Pragma: - no-cache Vary: @@ -1668,7 +1532,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" status: 404 Not Found code: 404 duration: "" @@ -1702,7 +1566,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:16 GMT + - Thu, 14 Nov 2024 21:56:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1712,7 +1576,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" status: 404 Not Found code: 404 duration: "" @@ -1726,7 +1590,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.43.7 + url: https://api.linode.com/v4beta/networking/reserved/ips/45.79.122.120 method: DELETE response: body: '{"errors": [{"reason": "Not found"}]}' @@ -1748,7 +1612,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:17 GMT + - Thu, 14 Nov 2024 21:56:43 GMT Pragma: - no-cache X-Accepted-Oauth-Scopes: @@ -1772,7 +1636,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.43.77 + url: https://api.linode.com/v4beta/networking/reserved/ips/172.105.56.60 method: DELETE response: body: '{}' @@ -1800,7 +1664,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:17 GMT + - Thu, 14 Nov 2024 21:56:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1833,7 +1697,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/66290506 + url: https://api.linode.com/v4beta/linode/instances/67107631 method: DELETE response: body: '{}' @@ -1861,7 +1725,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 30 Oct 2024 15:43:19 GMT + - Thu, 14 Nov 2024 21:56:46 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1878,7 +1742,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "1600" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/network_ips_test.go b/test/integration/network_ips_test.go index 123155586..00b0d9ef0 100644 --- a/test/integration/network_ips_test.go +++ b/test/integration/network_ips_test.go @@ -177,6 +177,9 @@ func TestIPAddress_Update(t *testing.T) { t.Error(err) } + reservedTrue := true + reservedFalse := false + address := instance.IPv4[0].String() i, err := client.GetInstanceIPAddresses(context.Background(), instance.ID) if err != nil { @@ -207,7 +210,7 @@ func TestIPAddress_Update(t *testing.T) { ephemeralIP := instance.IPv4[0].String() updateOpts = IPAddressUpdateOptions{ - Reserved: true, + Reserved: &reservedTrue, } updatedIP, err := client.UpdateIPAddress(context.Background(), ephemeralIP, updateOpts) if err != nil { @@ -226,7 +229,7 @@ func TestIPAddress_Update(t *testing.T) { defer client.DeleteReservedIPAddress(context.Background(), reservedIP) updateOpts = IPAddressUpdateOptions{ - Reserved: true, + Reserved: &reservedTrue, } updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { @@ -240,7 +243,7 @@ func TestIPAddress_Update(t *testing.T) { ephemeralIP = instance.IPv4[0].String() updateOpts = IPAddressUpdateOptions{ - Reserved: false, + Reserved: &reservedFalse, } updatedIP, err = client.UpdateIPAddress(context.Background(), ephemeralIP, updateOpts) if err != nil { @@ -273,7 +276,7 @@ func TestIPAddress_Update(t *testing.T) { } updateOpts = IPAddressUpdateOptions{ - Reserved: false, + Reserved: &reservedFalse, } updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { @@ -291,7 +294,7 @@ func TestIPAddress_Update(t *testing.T) { } updateOpts = IPAddressUpdateOptions{ - Reserved: true, + Reserved: &reservedTrue, RDNS: String("sample rdns"), } _, err = client.UpdateIPAddress(context.Background(), unassignedResIP, updateOpts) @@ -299,21 +302,6 @@ func TestIPAddress_Update(t *testing.T) { t.Fatalf("Expected error when setting RDNS for unassigned reserved IP, but got none") } - // Sceanrio 6: Try to reserve an IP at MAX reserve IP limit - - reservedIP, err = createReservedIP() - if err == nil { - t.Fatalf("Expected error indicating MAX IP Reservation limit has been reached, got nil") - } else { - updateOpts = IPAddressUpdateOptions{ - Reserved: true, - } - _, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) - if err == nil { - t.Fatalf("Expected error when setting RDNS for unassigned reserved IP, but got none") - } - } - client.DeleteReservedIPAddress(context.Background(), unassignedResIP) // Scenario 6: Convert unassigned reserved IP to reserved (no-op) @@ -324,7 +312,7 @@ func TestIPAddress_Update(t *testing.T) { } updateOpts = IPAddressUpdateOptions{ - Reserved: true, + Reserved: &reservedTrue, } updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { @@ -344,7 +332,7 @@ func TestIPAddress_Update(t *testing.T) { } updateOpts = IPAddressUpdateOptions{ - Reserved: false, + Reserved: &reservedFalse, } _, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { @@ -362,7 +350,7 @@ func TestIPAddress_Update(t *testing.T) { invalidResIp := "123.72.121.76" updateOpts = IPAddressUpdateOptions{ - Reserved: false, + Reserved: &reservedFalse, } updatedIP, err = client.UpdateIPAddress(context.Background(), invalidResIp, updateOpts) From 4af2cc73e085263f1668b23e5a6e3fac17703ef1 Mon Sep 17 00:00:00 2001 From: Anirudh Jagadish Date: Mon, 18 Nov 2024 15:18:44 -0500 Subject: [PATCH 43/43] Changed struct name from LinodeReserveIPOptions to AllocateReserveIPOptions --- network_ips.go | 4 ++-- test/integration/network_ips_test.go | 30 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/network_ips.go b/network_ips.go index d64a01ae9..ad622cdf8 100644 --- a/network_ips.go +++ b/network_ips.go @@ -17,7 +17,7 @@ type LinodeIPAssignment struct { LinodeID int `json:"linode_id"` } -type LinodeReserveIPOptions struct { +type AllocateReserveIPOptions struct { Type string `json:"type"` Public bool `json:"public"` Reserved bool `json:"reserved,omitempty"` @@ -100,7 +100,7 @@ func (c *Client) ShareIPAddresses(ctx context.Context, opts IPAddressesShareOpti // AllocateReserveIP allocates a new IPv4 address to the Account, with the option to reserve it // and optionally assign it to a Linode. -func (c *Client) AllocateReserveIP(ctx context.Context, opts LinodeReserveIPOptions) (*InstanceIP, error) { +func (c *Client) AllocateReserveIP(ctx context.Context, opts AllocateReserveIPOptions) (*InstanceIP, error) { e := "networking/ips" result, err := doPOSTRequest[InstanceIP](ctx, c, e, opts) if err != nil { diff --git a/test/integration/network_ips_test.go b/test/integration/network_ips_test.go index 00b0d9ef0..4dc93c472 100644 --- a/test/integration/network_ips_test.go +++ b/test/integration/network_ips_test.go @@ -517,7 +517,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 1: Valid request - opts := LinodeReserveIPOptions{ + opts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true, @@ -534,7 +534,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { } // Scenario 2: Non-owned Linode - nonOwnedLinodeOpts := LinodeReserveIPOptions{ + nonOwnedLinodeOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true, @@ -548,7 +548,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 3: Omit Linode ID - omitLinodeIDOpts := LinodeReserveIPOptions{ + omitLinodeIDOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true, @@ -564,7 +564,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 4: Account at reserved IP limit - resLimitoOpts := linodego.LinodeReserveIPOptions{ + resLimitoOpts := linodego.AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true, @@ -581,7 +581,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // // Scenario 5: Linode at IPMax limit - // opts = linodego.LinodeReserveIPOptions{ + // opts = linodego.AllocateReserveIPOptions{ // Type: "ipv4", // Public: true, // Reserved: true, @@ -595,7 +595,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 6: Omit Region - omitRegionOpts := LinodeReserveIPOptions{ + omitRegionOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true, @@ -614,7 +614,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 7: Omit both Region and Linode ID - omitRegionAndLinodeIDopts := LinodeReserveIPOptions{ + omitRegionAndLinodeIDopts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true, @@ -627,7 +627,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 8: Reserved true, Public false - publicFalseOpts := LinodeReserveIPOptions{ + publicFalseOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: false, Reserved: true, @@ -641,7 +641,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 9: Reserved false - reservedFalseOpts := LinodeReserveIPOptions{ + reservedFalseOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: false, @@ -660,7 +660,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 10: Omit Reserved field - omitReservedOpts := LinodeReserveIPOptions{ + omitReservedOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Region: instance.Region, @@ -678,7 +678,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 11: Omit Linode ID, Reserved false - omitOpts := LinodeReserveIPOptions{ + omitOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: false, @@ -691,7 +691,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 12: Omit Linode ID and Reserved fields - omitIDResopts := LinodeReserveIPOptions{ + omitIDResopts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Region: instance.Region, @@ -703,7 +703,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 13: Reserved true, Type IPv6 - typeIPv6opts := LinodeReserveIPOptions{ + typeIPv6opts := AllocateReserveIPOptions{ Type: "ipv6", Public: true, Reserved: true, @@ -717,7 +717,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 14: Reserved false, Type IPv6 - resFalseIPv6opts := LinodeReserveIPOptions{ + resFalseIPv6opts := AllocateReserveIPOptions{ Type: "ipv6", Public: true, Reserved: false, @@ -731,7 +731,7 @@ func TestIPAddress_Instance_Allocate(t *testing.T) { // Scenario 15: Region mismatch - regionMismatchOpts := LinodeReserveIPOptions{ + regionMismatchOpts := AllocateReserveIPOptions{ Type: "ipv4", Public: true, Reserved: true,