From 8359ed41184f582fede0fe3da3ea56ab3d29ae1f Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Wed, 29 Apr 2026 09:24:02 -0400 Subject: [PATCH 01/17] TPT-4423: Drop resty as a dependency (#938) * Ported resty removal changes to new branch from up-to-date main and made additional changes to monitor client * Fixed lint * Updated log formatting to more closely resemble Resty's * Fixed lint * redact request header log * Fixes * Fixed CoPilot suggestions * Sanitize log output * Addressed CoPilot comments --------- Co-authored-by: Zhiwei Liang --- client.go | 941 ++++++++++-------- client_http.go | 56 -- client_monitor.go | 142 ++- client_test.go | 235 +++-- config_test.go | 14 +- errors.go | 107 +- errors_test.go | 192 ++-- go.mod | 1 - go.sum | 4 - images.go | 51 +- internal/testutil/mock.go | 6 +- k8s/go.mod | 1 - k8s/go.sum | 2 - logger.go | 34 +- monitor_alert_definitions.go | 23 +- monitor_api_services.go | 14 +- pagination.go | 52 +- request_helpers.go | 101 +- request_helpers_test.go | 41 +- request_log_template.tmpl | 8 + response_log_template.tmpl | 10 + retries.go | 139 ++- retries_http.go | 132 --- retries_http_test.go | 81 -- retries_test.go | 65 +- test/go.mod | 1 - test/go.sum | 2 - test/integration/cache_test.go | 8 +- .../TestMaintenancePolicies_List.yaml | 28 +- test/integration/maintenance_test.go | 18 +- test/unit/images_test.go | 8 + 31 files changed, 1201 insertions(+), 1316 deletions(-) delete mode 100644 client_http.go create mode 100644 request_log_template.tmpl create mode 100644 response_log_template.tmpl delete mode 100644 retries_http.go delete mode 100644 retries_http_test.go diff --git a/client.go b/client.go index 0273d4565..57737701e 100644 --- a/client.go +++ b/client.go @@ -3,6 +3,9 @@ package linodego import ( "bytes" "context" + "crypto/tls" + "crypto/x509" + _ "embed" "encoding/json" "fmt" "io" @@ -14,13 +17,13 @@ import ( "path/filepath" "reflect" "regexp" + "runtime" + "sort" "strconv" "strings" "sync" "text/template" "time" - - "github.com/go-resty/resty/v2" ) const ( @@ -50,20 +53,35 @@ const ( APIDefaultCacheExpiration = time.Minute * 15 ) -//nolint:unused +// Embed the log template files +// +//go:embed request_log_template.tmpl +var requestTemplateStr string + +//go:embed response_log_template.tmpl +var responseTemplateStr string + var ( - reqLogTemplate = template.Must(template.New("request").Parse(`Sending request: -Method: {{.Method}} -URL: {{.URL}} -Headers: {{.Headers}} -Body: {{.Body}}`)) - - respLogTemplate = template.Must(template.New("response").Parse(`Received response: -Status: {{.Status}} -Headers: {{.Headers}} -Body: {{.Body}}`)) + reqLogTemplate = template.Must(template.New("request").Parse(requestTemplateStr)) + respLogTemplate = template.Must(template.New("response").Parse(responseTemplateStr)) ) +type RequestLog struct { + Request string + Host string + Headers http.Header + Body string +} + +type ResponseLog struct { + Status string + Proto string + ReceivedAt string + TimeDuration string + Headers http.Header + Body string +} + var envDebug = false // redactHeadersMap is a map of headers that should be redacted in logs, @@ -72,18 +90,19 @@ var redactHeadersMap = map[string]string{ "Authorization": "Bearer *******************************", } -// Client is a wrapper around the Resty client +// Client is a wrapper around the http client type Client struct { - resty *resty.Client - userAgent string - debug bool - retryConditionals []RetryConditional + httpClient *http.Client + userAgent string + debug bool pollInterval time.Duration baseURL string apiVersion string apiProto string + hostURL string + header http.Header selectedProfile string loadedProfile string @@ -94,6 +113,16 @@ type Client struct { cacheExpiration time.Duration cachedEntries map[string]clientCacheEntry cachedEntryLock *sync.RWMutex + logger Logger + requestLog func(*RequestLog) error + onBeforeRequest []func(*http.Request) error + onAfterResponse []func(*http.Response) error + + retryConditionals []RetryConditional + retryMaxWaitTime time.Duration + retryMinWaitTime time.Duration + retryAfter RetryAfter + retryCount int } type EnvDefaults struct { @@ -110,13 +139,11 @@ type clientCacheEntry struct { } type ( - Request = resty.Request - Response = resty.Response - Logger = resty.Logger + Request = http.Request + Response = http.Response ) func init() { - // Whether we will enable Resty debugging output if apiDebug, ok := os.LookupEnv("LINODE_DEBUG"); ok { if parsed, err := strconv.ParseBool(apiDebug); err == nil { envDebug = parsed @@ -128,22 +155,37 @@ func init() { } // NewClient factory to create new Client struct +// nolint:funlen func NewClient(hc *http.Client) (client Client) { if hc != nil { - client.resty = resty.NewWithClient(hc) + client.httpClient = hc } else { - client.resty = resty.New() + client.httpClient = &http.Client{} + } + + // Ensure that the Header map is not nil + if client.httpClient.Transport == nil { + client.httpClient.Transport = &http.Transport{} } client.shouldCache = true client.cacheExpiration = APIDefaultCacheExpiration client.cachedEntries = make(map[string]clientCacheEntry) client.cachedEntryLock = &sync.RWMutex{} + client.configProfiles = make(map[string]ConfigProfile) + + const ( + retryMinWaitDuration = 100 * time.Millisecond + retryMaxWaitDuration = 2 * time.Second + ) + + client.retryMinWaitTime = retryMinWaitDuration + client.retryMaxWaitTime = retryMaxWaitDuration client.SetUserAgent(DefaultUserAgent) + client.SetLogger(createLogger()) baseURL, baseURLExists := os.LookupEnv(APIHostVar) - if baseURLExists { client.SetBaseURL(baseURL) } @@ -156,17 +198,11 @@ func NewClient(hc *http.Client) (client Client) { } certPath, certPathExists := os.LookupEnv(APIHostCert) - - if certPathExists && !hasCustomTransport(hc) { - cert, err := os.ReadFile(filepath.Clean(certPath)) - if err != nil { - log.Fatalf("[ERROR] Error when reading cert at %s: %s\n", certPath, err.Error()) - } - + if certPathExists { client.SetRootCertificate(certPath) if envDebug { - log.Printf("[DEBUG] Set API root certificate to %s with contents %s\n", certPath, cert) + log.Printf("[DEBUG] Set API root certificate to %s\n", certPath) } } @@ -174,6 +210,7 @@ func NewClient(hc *http.Client) (client Client) { SetRetryWaitTime(APISecondsPerPoll * time.Second). SetPollDelay(APISecondsPerPoll * time.Second). SetRetries(). + SetLogger(createLogger()). SetDebug(envDebug). enableLogSanitization() @@ -213,8 +250,8 @@ func NewClientFromEnv(hc *http.Client) (*Client, error) { client.selectedProfile = configProfile // We should only load the config if the config file exists - if _, err = os.Stat(configPath); err != nil { - return nil, fmt.Errorf("error loading config file %s: %w", configPath, err) + if _, statErr := os.Stat(configPath); statErr != nil { + return nil, fmt.Errorf("error loading config file %s: %w", configPath, statErr) } err = client.preLoadConfig(configPath) @@ -225,42 +262,284 @@ func NewClientFromEnv(hc *http.Client) (*Client, error) { // SetUserAgent sets a custom user-agent for HTTP requests func (c *Client) SetUserAgent(ua string) *Client { c.userAgent = ua - c.resty.SetHeader("User-Agent", c.userAgent) + c.SetHeader("User-Agent", c.userAgent) return c } -type RequestParams struct { - Body any +type requestParams struct { + Body *bytes.Reader Response any + // Headers are per-request headers that will be applied only to + // the individual request, not stored on the shared client state. + Headers http.Header +} + +func (c *Client) ErrorAndLogf(format string, args ...any) error { + if c.debug && c.logger != nil { + c.logger.Errorf(format, args...) + } + + return fmt.Errorf(format, args...) +} + +// SetRootCertificate adds a root certificate to the underlying TLS client config +func (c *Client) SetRootCertificate(certPath string) *Client { + config, err := c.tlsConfig() + if err != nil { + log.Println("[WARN] Custom transport is not allowed with a custom root CA") + return c + } + + if config.RootCAs == nil { + config.RootCAs = x509.NewCertPool() + } + + pem, err := os.ReadFile(filepath.Clean(certPath)) + if err != nil { + log.Printf("[ERROR] Failed to read root certificate at %s: %s\n", certPath, err.Error()) + return c + } + + config.RootCAs.AppendCertsFromPEM(pem) + + return c +} + +// SetToken sets the API token for all requests from this client +// Only necessary if you haven't already provided the http client to NewClient() configured with the token. +func (c *Client) SetToken(token string) *Client { + c.SetHeader("Authorization", fmt.Sprintf("Bearer %s", token)) + return c +} + +// SetRetries adds retry conditions for "Linode Busy." errors and 429s. +func (c *Client) SetRetries() *Client { + c. + AddRetryCondition(LinodeBusyRetryCondition). + AddRetryCondition(TooManyRequestsRetryCondition). + AddRetryCondition(ServiceUnavailableRetryCondition). + AddRetryCondition(RequestTimeoutRetryCondition). + AddRetryCondition(RequestGOAWAYRetryCondition). + AddRetryCondition(RequestNGINXRetryCondition). + SetRetryMaxWaitTime(APIRetryMaxWaitTime) + ConfigureRetries(c) + + return c +} + +// AddRetryCondition adds a RetryConditional function to the Client +func (c *Client) AddRetryCondition(retryCondition RetryConditional) *Client { + c.retryConditionals = append(c.retryConditionals, retryCondition) + + return c +} + +func (c *Client) SetDebug(debug bool) *Client { + c.debug = debug + + return c +} + +func (c *Client) SetLogger(logger Logger) *Client { + c.logger = logger + + return c +} + +func (c *Client) OnBeforeRequest(m func(*http.Request) error) { + c.onBeforeRequest = append(c.onBeforeRequest, m) +} + +func (c *Client) OnAfterResponse(m func(*http.Response) error) { + c.onAfterResponse = append(c.onAfterResponse, m) +} + +// UseURL parses the individual components of the given API URL and configures the client +// accordingly. For example, a valid URL. +// For example: +// +// client.UseURL("https://api.test.linode.com/v4beta") +func (c *Client) UseURL(apiURL string) (*Client, error) { + parsedURL, err := url.Parse(apiURL) + if err != nil { + return nil, fmt.Errorf("failed to parse URL: %w", err) + } + + if parsedURL.Scheme == "" || parsedURL.Host == "" { + return nil, fmt.Errorf("need both scheme and host in API URL, got %q", apiURL) + } + + // Create a new URL excluding the path to use as the base URL + baseURL := &url.URL{ + Host: parsedURL.Host, + Scheme: parsedURL.Scheme, + } + + c.SetBaseURL(baseURL.String()) + + versionMatches := regexp.MustCompile(`/v[a-zA-Z0-9]+`).FindAllString(parsedURL.Path, -1) + + // Only set the version if a version is found in the URL, else use the default + if len(versionMatches) > 0 { + c.SetAPIVersion( + strings.Trim(versionMatches[len(versionMatches)-1], "/"), + ) + } + + return c, nil +} + +func (c *Client) SetBaseURL(baseURL string) *Client { + baseURLPath, _ := url.Parse(baseURL) + + c.baseURL = path.Join(baseURLPath.Host, baseURLPath.Path) + c.apiProto = baseURLPath.Scheme + + c.updateHostURL() + + return c +} + +// SetAPIVersion sets the version of the API to interface with +func (c *Client) SetAPIVersion(apiVersion string) *Client { + c.apiVersion = apiVersion + + c.updateHostURL() + + return c +} + +// InvalidateCache clears all cached responses for all endpoints. +func (c *Client) InvalidateCache() { + c.cachedEntryLock.Lock() + defer c.cachedEntryLock.Unlock() + + // GC will handle the old map + c.cachedEntries = make(map[string]clientCacheEntry) +} + +// InvalidateCacheEndpoint invalidates a single cached endpoint. +func (c *Client) InvalidateCacheEndpoint(endpoint string) error { + u, err := url.Parse(endpoint) + if err != nil { + return fmt.Errorf("failed to parse URL for caching: %w", err) + } + + c.cachedEntryLock.Lock() + defer c.cachedEntryLock.Unlock() + + delete(c.cachedEntries, u.Path) + + return nil +} + +// SetGlobalCacheExpiration sets the desired time for any cached response +// to be valid for. +func (c *Client) SetGlobalCacheExpiration(expiryTime time.Duration) { + c.cacheExpiration = expiryTime +} + +// UseCache sets whether response caching should be used +func (c *Client) UseCache(value bool) { + c.shouldCache = value +} + +// SetRetryMaxWaitTime sets the maximum delay before retrying a request. +func (c *Client) SetRetryMaxWaitTime(maxWaitTime time.Duration) *Client { + c.retryMaxWaitTime = maxWaitTime + return c +} + +// SetRetryWaitTime sets the default (minimum) delay before retrying a request. +func (c *Client) SetRetryWaitTime(minWaitTime time.Duration) *Client { + c.retryMinWaitTime = minWaitTime + return c +} + +// SetRetryAfter sets the callback function to be invoked with a failed request +// to determine wben it should be retried. +func (c *Client) SetRetryAfter(callback RetryAfter) *Client { + c.retryAfter = callback + return c +} + +// SetRetryCount sets the maximum retry attempts before aborting. +func (c *Client) SetRetryCount(count int) *Client { + c.retryCount = count + return c +} + +// SetPollDelay sets the number of milliseconds to wait between events or status polls. +// Affects all WaitFor* functions and retries. +func (c *Client) SetPollDelay(delay time.Duration) *Client { + c.pollInterval = delay + return c +} + +// GetPollDelay gets the number of milliseconds to wait between events or status polls. +// Affects all WaitFor* functions and retries. +func (c *Client) GetPollDelay() time.Duration { + return c.pollInterval +} + +// SetHeader sets a custom header to be used in all API requests made with the current +// client. +// NOTE: Some headers may be overridden by the individual request functions. +func (c *Client) SetHeader(name, value string) { + if c.header == nil { + c.header = make(http.Header) // Initialize header if nil + } + + c.header.Set(name, value) +} + +func (c *Client) Transport() (*http.Transport, error) { + if transport, ok := c.httpClient.Transport.(*http.Transport); ok { + return transport, nil + } + + return nil, fmt.Errorf("current transport is not an *http.Transport instance") } // 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) error { +// nolint:funlen, gocognit, nestif +func (c *Client) doRequest(ctx context.Context, method, endpoint string, params requestParams, paginationMutator *func(*http.Request) error) error { var ( - req *http.Request - bodyBuffer *bytes.Buffer - resp *http.Response - err error + req *http.Request + resp *http.Response + err error ) - for range httpDefaultRetryCount { - req, bodyBuffer, err = c.createRequest(ctx, method, url, params) + for range c.retryCount { + // Reset the body to the start for each retry if it's not nil + if params.Body != nil { + if _, seekErr := params.Body.Seek(0, io.SeekStart); seekErr != nil { + return c.ErrorAndLogf("failed to seek to the start of the body: %v", seekErr.Error()) + } + } + + req, err = c.createRequest(ctx, method, endpoint, params) if err != nil { return err } + if paginationMutator != nil { + if mutErr := (*paginationMutator)(req); mutErr != nil { + return c.ErrorAndLogf("failed to mutate before request: %v", mutErr.Error()) + } + } + if err = c.applyBeforeRequest(req); err != nil { return err } if c.debug && c.logger != nil { - c.logRequest(req, method, url, bodyBuffer) + req = c.logRequest(req) } - processResponse := func() error { + processResponse := func(start, end time.Time) error { defer func() { closeErr := resp.Body.Close() if closeErr != nil && err == nil { @@ -273,12 +552,7 @@ func (c *httpClient) doRequest(ctx context.Context, method, url string, params R } if c.debug && c.logger != nil { - var logErr error - - resp, logErr = c.logResponse(resp) - if logErr != nil { - return logErr - } + resp = c.logResponse(resp, start, end) } if params.Response != nil { @@ -295,9 +569,12 @@ func (c *httpClient) doRequest(ctx context.Context, method, url string, params R return nil } + startTime := time.Now() resp, err = c.sendRequest(req) + endTime := time.Now() + if err == nil { - if err = processResponse(); err == nil { + if err = processResponse(startTime, endTime); err == nil { return nil } } @@ -311,19 +588,33 @@ func (c *httpClient) doRequest(ctx context.Context, method, url string, params R return retryErr } - // Sleep for the specified duration before retrying. - // If retryAfter is 0 (i.e., Retry-After header is not found), - // no delay is applied. - time.Sleep(retryAfter) + // Determine wait time before retrying. + // If the server provided a Retry-After duration, use it (clamped to bounds). + // Otherwise, fall back to the configured minimum wait time. + waitTime := c.retryMinWaitTime + + if retryAfter > 0 { + waitTime = retryAfter + } + + // Ensure the wait time is within the defined bounds + if waitTime < c.retryMinWaitTime { + waitTime = c.retryMinWaitTime + } else if waitTime > c.retryMaxWaitTime { + waitTime = c.retryMaxWaitTime + } + + // Sleep for the calculated duration before retrying + time.Sleep(waitTime) } return err } -// nolint:unused -func (c *httpClient) shouldRetry(resp *http.Response, err error) bool { +func (c *Client) shouldRetry(resp *http.Response, err error) bool { for _, retryConditional := range c.retryConditionals { if retryConditional(resp, err) { + log.Printf("[INFO] Received error %v - Retrying", err) return true } } @@ -331,35 +622,26 @@ func (c *httpClient) shouldRetry(resp *http.Response, err error) bool { return false } -// nolint:unused -func (c *httpClient) createRequest(ctx context.Context, method, url string, params RequestParams) (*http.Request, *bytes.Buffer, error) { - var ( - bodyReader io.Reader - bodyBuffer *bytes.Buffer - ) +func (c *Client) createRequest(ctx context.Context, method, endpoint string, params requestParams) (*http.Request, error) { + var bodyReader io.Reader if params.Body != nil { - bodyBuffer = new(bytes.Buffer) - if err := json.NewEncoder(bodyBuffer).Encode(params.Body); err != nil { - if c.debug && c.logger != nil { - c.logger.Errorf("failed to encode body: %v", err) - } - - return nil, nil, fmt.Errorf("failed to encode body: %w", err) + // Reset the body position to the start before using it + _, err := params.Body.Seek(0, io.SeekStart) + if err != nil { + return nil, c.ErrorAndLogf("failed to seek to the start of the body: %v", err.Error()) } - bodyReader = bodyBuffer + bodyReader = params.Body } - req, err := http.NewRequestWithContext(ctx, method, url, bodyReader) + req, err := http.NewRequestWithContext(ctx, method, fmt.Sprintf("%s/%s", strings.TrimRight(c.hostURL, "/"), + strings.TrimLeft(endpoint, "/")), bodyReader) if err != nil { - if c.debug && c.logger != nil { - c.logger.Errorf("failed to create request: %v", err) - } - - return nil, nil, fmt.Errorf("failed to create request: %w", err) + return nil, c.ErrorAndLogf("failed to create request: %v", err.Error()) } + // Set the default headers req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") @@ -367,40 +649,43 @@ func (c *httpClient) createRequest(ctx context.Context, method, url string, para req.Header.Set("User-Agent", c.userAgent) } - return req, bodyBuffer, nil + // Set additional headers added to the client + for name, values := range c.header { + for _, value := range values { + req.Header.Set(name, value) + } + } + + // Apply per-request headers (these take priority over client headers) + for name, values := range params.Headers { + for _, value := range values { + req.Header.Set(name, value) + } + } + + return req, nil } -// nolint:unused -func (c *httpClient) applyBeforeRequest(req *http.Request) error { +func (c *Client) 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 before request: %v", err) - } - - return fmt.Errorf("failed to mutate before request: %w", err) + return c.ErrorAndLogf("failed to mutate before request: %v", err.Error()) } } return nil } -// nolint:unused -func (c *httpClient) applyAfterResponse(resp *http.Response) error { +func (c *Client) 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 after response: %w", err) + return c.ErrorAndLogf("failed to mutate after response: %v", err.Error()) } } return nil } -// nolint:unused func redactHeaders(headers http.Header) http.Header { redacted := headers.Clone() @@ -413,333 +698,224 @@ func redactHeaders(headers http.Header) http.Header { return redacted } -// nolint:unused -func (c *httpClient) logRequest(req *http.Request, method, url string, bodyBuffer *bytes.Buffer) { - var reqBody string - if bodyBuffer != nil { - reqBody = bodyBuffer.String() - } else { - reqBody = "nil" - } - - var logBuf bytes.Buffer +func (c *Client) logRequest(req *http.Request) *http.Request { + var reqBody bytes.Buffer + if req.Body != nil { + if _, err := io.Copy(&reqBody, req.Body); err != nil { + c.logger.Errorf("failed to read request body: %v", err) + } - err := reqLogTemplate.Execute(&logBuf, map[string]any{ - "Method": method, - "URL": url, - "Headers": redactHeaders(req.Header), - "Body": reqBody, - }) - if err == nil { - c.logger.Debugf(logBuf.String()) + req.Body = io.NopCloser(bytes.NewReader(reqBody.Bytes())) } -} -// nolint:unused -func (c *httpClient) sendRequest(req *http.Request) (*http.Response, error) { - // #nosec G704 - resp, err := c.httpClient.Do(req) - if err != nil { - if c.debug && c.logger != nil { - c.logger.Errorf("failed to send request: %v", err) - } + reqLog := &RequestLog{ + Request: strings.Join([]string{req.Method, req.URL.Path, req.Proto}, " "), + Host: req.Host, + Headers: redactHeaders(req.Header.Clone()), + Body: reqBody.String(), + } - return nil, fmt.Errorf("failed to send request: %w", err) + e := c.requestLog(reqLog) + if e != nil { + _ = c.ErrorAndLogf("failed to log request: %v", e.Error()) } - return resp, nil -} + sanitizedBody := sanitizeLogValue(reqLog.Body) -// nolint:unused -func (c *httpClient) checkHTTPError(resp *http.Response) error { - _, err := coupleAPIErrorsHTTP(resp, nil) - if err != nil { + body, jsonErr := formatBody(sanitizedBody) + if jsonErr != nil { if c.debug && c.logger != nil { - c.logger.Errorf("received HTTP error: %v", err) + c.logger.Errorf("%v", jsonErr) } - - return err - } - - return nil -} - -// nolint:unused -func (c *httpClient) logResponse(resp *http.Response) (*http.Response, error) { - var respBody bytes.Buffer - if _, err := io.Copy(&respBody, resp.Body); err != nil { - c.logger.Errorf("failed to read response body: %v", err) } var logBuf bytes.Buffer - err := respLogTemplate.Execute(&logBuf, map[string]any{ - "Status": resp.Status, - "Headers": redactHeaders(resp.Header), - "Body": respBody.String(), + err := reqLogTemplate.Execute(&logBuf, map[string]any{ + "Request": reqLog.Request, + "Host": reqLog.Host, + "Headers": formatHeaders(reqLog.Headers), + "Body": body, }) if err == nil { - c.logger.Debugf(logBuf.String()) + c.logger.Debugf(sanitizeLogValue(logBuf.String())) } - resp.Body = io.NopCloser(bytes.NewReader(respBody.Bytes())) - - return resp, nil + return req } -// nolint:unused -func (c *httpClient) decodeResponseBody(resp *http.Response, response any) error { - if err := json.NewDecoder(resp.Body).Decode(response); err != nil { - if c.debug && c.logger != nil { - c.logger.Errorf("failed to decode response: %v", err) - } +func formatHeaders(headers map[string][]string) string { + var builder strings.Builder + builder.WriteString("\n") - return fmt.Errorf("failed to decode response: %w", err) + keys := make([]string, 0, len(headers)) + for key := range headers { + keys = append(keys, key) } - return nil -} + sort.Strings(keys) -// R wraps resty's R method -func (c *Client) R(ctx context.Context) *resty.Request { - return c.resty.R(). - ExpectContentType("application/json"). - SetHeader("Content-Type", "application/json"). - SetContext(ctx). - SetError(APIError{}) -} - -// SetDebug sets the debug on resty's client -func (c *Client) SetDebug(debug bool) *Client { - c.debug = debug - c.resty.SetDebug(debug) + for _, key := range keys { + builder.WriteString(fmt.Sprintf(" %s: %s\n", key, strings.Join(headers[key], ", "))) + } - return c + return strings.TrimSuffix(builder.String(), "\n") } -// SetLogger allows the user to override the output -// logger for debug logs. -func (c *Client) SetLogger(logger Logger) *Client { - c.resty.SetLogger(logger) +// sanitizeLogValue removes or escapes control characters that could +// enable log injection (e.g., \r, \n) from a string before it is written +// to a log entry. Uses strings.ReplaceAll so static-analysis tools +// (e.g., CodeQL) can recognize the sanitization. +func sanitizeLogValue(s string) string { + s = strings.ReplaceAll(s, "\r\n", "\\n") + s = strings.ReplaceAll(s, "\r", "\\n") + s = strings.ReplaceAll(s, "\n", "\\n") - return c + return s } -//nolint:unused -func (c *httpClient) httpSetDebug(debug bool) *httpClient { - c.debug = debug +func formatBody(body string) (string, error) { + body = strings.TrimSpace(body) + if body == "null" || body == "nil" || body == "" { + return "", nil + } - return c -} + var jsonData any -//nolint:unused -func (c *httpClient) httpSetLogger(logger httpLogger) *httpClient { - c.logger = logger + err := json.Unmarshal([]byte(body), &jsonData) + if err != nil { + return "", fmt.Errorf("error unmarshalling JSON: %w", err) + } - return c -} + prettyJSON, err := json.MarshalIndent(jsonData, "", " ") + if err != nil { + return "", fmt.Errorf("error marshalling JSON: %w", err) + } -// OnBeforeRequest adds a handler to the request body to run before the request is sent -func (c *Client) OnBeforeRequest(m func(request *Request) error) { - c.resty.OnBeforeRequest(func(_ *resty.Client, req *resty.Request) error { - return m(req) - }) + return "\n" + string(prettyJSON), nil } -// OnAfterResponse adds a handler to the request body to run before the request is sent -func (c *Client) OnAfterResponse(m func(response *Response) error) { - c.resty.OnAfterResponse(func(_ *resty.Client, req *resty.Response) error { - return m(req) - }) -} +func formatDate(dateStr string) (string, error) { + parsedTime, err := time.Parse(time.RFC1123, dateStr) + if err != nil { + return "", fmt.Errorf("error parsing date: %v", err) + } -// nolint:unused -func (c *httpClient) httpOnBeforeRequest(m func(*http.Request) error) *httpClient { - c.onBeforeRequest = append(c.onBeforeRequest, m) + formattedDate := parsedTime.In(time.Local).Format("2006-01-02T15:04:05-07:00") // nolint:gosmopolitan - return c + return formattedDate, nil } -// nolint:unused -func (c *httpClient) httpOnAfterResponse(m func(*http.Response) error) *httpClient { - c.onAfterResponse = append(c.onAfterResponse, m) +func (c *Client) sendRequest(req *http.Request) (*http.Response, error) { + resp, err := c.httpClient.Do(req) //#nosec G704 // URL is constructed from client-configured base URL + endpoint + if err != nil { + return nil, c.ErrorAndLogf("failed to send request: %w", err) + } - return c + return resp, nil } -// UseURL parses the individual components of the given API URL and configures the client -// accordingly. For example, a valid URL. -// For example: -// -// client.UseURL("https://api.test.linode.com/v4beta") -func (c *Client) UseURL(apiURL string) (*Client, error) { - parsedURL, err := url.Parse(apiURL) +func (c *Client) checkHTTPError(resp *http.Response) error { + _, err := coupleAPIErrors(resp, nil) if err != nil { - return nil, fmt.Errorf("failed to parse URL: %w", err) + _ = c.ErrorAndLogf("received HTTP error: %v", err.Error()) + return err } - if parsedURL.Scheme == "" || parsedURL.Host == "" { - return nil, fmt.Errorf("need both scheme and host in API URL, got %q", apiURL) - } + return nil +} - // Create a new URL excluding the path to use as the base URL - baseURL := &url.URL{ - Host: parsedURL.Host, - Scheme: parsedURL.Scheme, +func (c *Client) logResponse(resp *http.Response, start, end time.Time) *http.Response { + var respBody bytes.Buffer + if _, err := io.Copy(&respBody, resp.Body); err != nil { + c.logger.Errorf("failed to read response body: %v", err) } - c.SetBaseURL(baseURL.String()) - - versionMatches := regexp.MustCompile(`/v[a-zA-Z0-9]+`).FindAllString(parsedURL.Path, -1) - - // Only set the version if a version is found in the URL, else use the default - if len(versionMatches) > 0 { - c.SetAPIVersion( - strings.Trim(versionMatches[len(versionMatches)-1], "/"), - ) + receivedAt, dateErr := formatDate(resp.Header.Get("Date")) + if dateErr != nil { + if c.debug && c.logger != nil { + c.logger.Errorf("failed to format date: %v", dateErr) + } } - return c, nil -} - -// SetBaseURL sets the base URL of the Linode v4 API (https://api.linode.com/v4) -func (c *Client) SetBaseURL(baseURL string) *Client { - baseURLPath, _ := url.Parse(baseURL) - - c.baseURL = path.Join(baseURLPath.Host, baseURLPath.Path) - c.apiProto = baseURLPath.Scheme - - c.updateHostURL() - - return c -} - -// SetAPIVersion sets the version of the API to interface with -func (c *Client) SetAPIVersion(apiVersion string) *Client { - c.apiVersion = apiVersion + duration := end.Sub(start).String() - c.updateHostURL() - - return c -} - -// SetRootCertificate adds a root certificate to the underlying TLS client config -func (c *Client) SetRootCertificate(path string) *Client { - c.resty.SetRootCertificate(path) - return c -} - -// SetToken sets the API token for all requests from this client -// Only necessary if you haven't already provided the http client to NewClient() configured with the token. -func (c *Client) SetToken(token string) *Client { - c.resty.SetHeader("Authorization", fmt.Sprintf("Bearer %s", token)) - return c -} + respLog := &ResponseLog{ + Status: resp.Status, + Proto: resp.Proto, + ReceivedAt: receivedAt, + TimeDuration: duration, + Headers: resp.Header, + Body: respBody.String(), + } -// SetRetries adds retry conditions for "Linode Busy." errors and 429s. -func (c *Client) SetRetries() *Client { - c. - addRetryConditional(linodeBusyRetryCondition). - addRetryConditional(tooManyRequestsRetryCondition). - addRetryConditional(serviceUnavailableRetryCondition). - addRetryConditional(requestTimeoutRetryCondition). - addRetryConditional(requestGOAWAYRetryCondition). - addRetryConditional(requestNGINXRetryCondition). - SetRetryMaxWaitTime(APIRetryMaxWaitTime) - configureRetries(c) + body, jsonErr := formatBody(sanitizeLogValue(respLog.Body)) + if jsonErr != nil { + if c.debug && c.logger != nil { + c.logger.Errorf("%v", jsonErr) + } + } - return c -} + var logBuf bytes.Buffer -// AddRetryCondition adds a RetryConditional function to the Client -func (c *Client) AddRetryCondition(retryCondition RetryConditional) *Client { - c.resty.AddRetryCondition(resty.RetryConditionFunc(retryCondition)) - return c -} + err := respLogTemplate.Execute(&logBuf, map[string]any{ + "Status": respLog.Status, + "Proto": respLog.Proto, + "ReceivedAt": respLog.ReceivedAt, + "TimeDuration": respLog.TimeDuration, + "Headers": formatHeaders(redactHeaders(respLog.Headers)), + "Body": body, + }) + if err == nil { + c.logger.Debugf(sanitizeLogValue(logBuf.String())) + } -// InvalidateCache clears all cached responses for all endpoints. -func (c *Client) InvalidateCache() { - c.cachedEntryLock.Lock() - defer c.cachedEntryLock.Unlock() + resp.Body = io.NopCloser(bytes.NewReader(respBody.Bytes())) - // GC will handle the old map - c.cachedEntries = make(map[string]clientCacheEntry) + return resp } -// InvalidateCacheEndpoint invalidates a single cached endpoint. -func (c *Client) InvalidateCacheEndpoint(endpoint string) error { - u, err := url.Parse(endpoint) - if err != nil { - return fmt.Errorf("failed to parse URL for caching: %w", err) +func (c *Client) decodeResponseBody(resp *http.Response, response any) error { + if err := json.NewDecoder(resp.Body).Decode(response); err != nil { + return c.ErrorAndLogf("failed to decode response: %v", err.Error()) } - c.cachedEntryLock.Lock() - defer c.cachedEntryLock.Unlock() - - delete(c.cachedEntries, u.Path) - return nil } -// SetGlobalCacheExpiration sets the desired time for any cached response -// to be valid for. -func (c *Client) SetGlobalCacheExpiration(expiryTime time.Duration) { - c.cacheExpiration = expiryTime -} - -// UseCache sets whether response caching should be used -func (c *Client) UseCache(value bool) { - c.shouldCache = value -} - -// SetRetryMaxWaitTime sets the maximum delay before retrying a request. -func (c *Client) SetRetryMaxWaitTime(maxWaitTime time.Duration) *Client { - c.resty.SetRetryMaxWaitTime(maxWaitTime) - return c -} +func (c *Client) updateHostURL() { + apiProto := APIProto + baseURL := APIHost + apiVersion := APIVersion -// SetRetryWaitTime sets the default (minimum) delay before retrying a request. -func (c *Client) SetRetryWaitTime(minWaitTime time.Duration) *Client { - c.resty.SetRetryWaitTime(minWaitTime) - return c -} + if c.baseURL != "" { + baseURL = c.baseURL + } -// SetRetryAfter sets the callback function to be invoked with a failed request -// to determine wben it should be retried. -func (c *Client) SetRetryAfter(callback RetryAfter) *Client { - c.resty.SetRetryAfter(resty.RetryAfterFunc(callback)) - return c -} + if c.apiVersion != "" { + apiVersion = c.apiVersion + } -// SetRetryCount sets the maximum retry attempts before aborting. -func (c *Client) SetRetryCount(count int) *Client { - c.resty.SetRetryCount(count) - return c -} + if c.apiProto != "" { + apiProto = c.apiProto + } -// SetPollDelay sets the number of milliseconds to wait between events or status polls. -// Affects all WaitFor* functions and retries. -func (c *Client) SetPollDelay(delay time.Duration) *Client { - c.pollInterval = delay - return c + c.hostURL = strings.TrimRight(fmt.Sprintf("%s://%s/%s", apiProto, baseURL, url.PathEscape(apiVersion)), "/") } -// GetPollDelay gets the number of milliseconds to wait between events or status polls. -// Affects all WaitFor* functions and retries. -func (c *Client) GetPollDelay() time.Duration { - return c.pollInterval -} +func (c *Client) tlsConfig() (*tls.Config, error) { + transport, err := c.Transport() + if err != nil { + return nil, err + } -// SetHeader sets a custom header to be used in all API requests made with the current -// client. -// NOTE: Some headers may be overridden by the individual request functions. -func (c *Client) SetHeader(name, value string) { - c.resty.SetHeader(name, value) -} + if transport.TLSClientConfig == nil { + transport.TLSClientConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + } + } -func (c *Client) addRetryConditional(retryConditional RetryConditional) *Client { - c.retryConditionals = append(c.retryConditionals, retryConditional) - return c + return transport.TLSClientConfig, nil } func (c *Client) addCachedResponse(endpoint string, response any, expiry *time.Duration) { @@ -819,49 +995,25 @@ func (c *Client) getCachedResponse(endpoint string) any { return c.cachedEntries[endpoint].Data } -func (c *Client) updateHostURL() { - apiProto := APIProto - baseURL := APIHost - apiVersion := APIVersion - - if c.baseURL != "" { - baseURL = c.baseURL +func (c *Client) onRequestLog(rl func(*RequestLog) error) *Client { + if c.requestLog != nil { + c.logger.Warnf("Overwriting an existing on-request-log callback from=%s to=%s", + functionName(c.requestLog), functionName(rl)) } - if c.apiVersion != "" { - apiVersion = c.apiVersion - } + c.requestLog = rl - if c.apiProto != "" { - apiProto = c.apiProto - } - - c.resty.SetBaseURL( - fmt.Sprintf( - "%s://%s/%s", - apiProto, - baseURL, - url.PathEscape(apiVersion), - ), - ) + return c } -func redactLogHeaders(header http.Header) { - for h, redactedValue := range redactHeadersMap { - if header.Get(h) != "" { - header.Set(h, redactedValue) - } - } +func functionName(i any) string { + return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() } func (c *Client) enableLogSanitization() *Client { - c.resty.OnRequestLog(func(r *resty.RequestLog) error { - redactLogHeaders(r.Header) - return nil - }) - - c.resty.OnResponseLog(func(r *resty.ResponseLog) error { - redactLogHeaders(r.Header) + c.onRequestLog(func(r *RequestLog) error { + // masking authorization header + r.Headers.Set("Authorization", "Bearer *******************************") return nil }) @@ -958,16 +1110,3 @@ func generateListCacheURL(endpoint string, opts *ListOptions) (string, error) { return fmt.Sprintf("%s:%s", endpoint, hashedOpts), nil } - -func hasCustomTransport(hc *http.Client) bool { - if hc == nil || hc.Transport == nil { - return false - } - - if _, ok := hc.Transport.(*http.Transport); !ok { - log.Println("[WARN] Custom transport is not allowed with a custom root CA.") - return true - } - - return false -} diff --git a/client_http.go b/client_http.go deleted file mode 100644 index 7f16362c5..000000000 --- a/client_http.go +++ /dev/null @@ -1,56 +0,0 @@ -package linodego - -import ( - "net/http" - "sync" - "time" -) - -// Client is a wrapper around the Resty client -// -//nolint:unused -type httpClient struct { - //nolint:unused - httpClient *http.Client - //nolint:unused - userAgent string - //nolint:unused - debug bool - //nolint:unused - retryConditionals []httpRetryConditional - //nolint:unused - retryAfter httpRetryAfter - - //nolint:unused - pollInterval time.Duration - - //nolint:unused - baseURL string - //nolint:unused - apiVersion string - //nolint:unused - apiProto string - //nolint:unused - selectedProfile string - //nolint:unused - loadedProfile string - - //nolint:unused - configProfiles map[string]ConfigProfile - - // Fields for caching endpoint responses - //nolint:unused - shouldCache bool - //nolint:unused - cacheExpiration time.Duration - //nolint:unused - cachedEntries map[string]clientCacheEntry - //nolint:unused - 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_monitor.go b/client_monitor.go index b54dc8284..3cb959854 100644 --- a/client_monitor.go +++ b/client_monitor.go @@ -2,13 +2,17 @@ package linodego import ( "context" + "crypto/tls" + "crypto/x509" + "encoding/json" "fmt" + "io" "net/http" "net/url" "os" "path" - - "github.com/go-resty/resty/v2" + "path/filepath" + "strings" ) const ( @@ -24,25 +28,36 @@ const ( MonitorAPIEnvVar = "MONITOR_API_TOKEN" ) -// MonitorClient is a wrapper around the Resty client +// MonitorClient is a wrapper around the http client type MonitorClient struct { - resty *resty.Client + httpClient *http.Client debug bool apiBaseURL string apiProtocol string apiVersion string + hostURL string userAgent string + header http.Header + logger Logger } // NewMonitorClient is the entry point for user to create a new MonitorClient // It utilizes default values and looks for environment variables to initialize a MonitorClient. func NewMonitorClient(hc *http.Client) (mClient MonitorClient) { if hc != nil { - mClient.resty = resty.NewWithClient(hc) + mClient.httpClient = hc } else { - mClient.resty = resty.New() + mClient.httpClient = &http.Client{} + } + + // Ensure transport is initialized so SetRootCertificate can configure TLS + if mClient.httpClient.Transport == nil { + mClient.httpClient.Transport = &http.Transport{} } + mClient.header = make(http.Header) + mClient.logger = createLogger() + mClient.SetUserAgent(DefaultUserAgent) baseURL, baseURLExists := os.LookupEnv(MonitorAPIHostVar) @@ -72,24 +87,14 @@ func NewMonitorClient(hc *http.Client) (mClient MonitorClient) { // SetUserAgent sets a custom user-agent for HTTP requests func (mc *MonitorClient) SetUserAgent(ua string) *MonitorClient { mc.userAgent = ua - mc.resty.SetHeader("User-Agent", mc.userAgent) + mc.header.Set("User-Agent", ua) return mc } -// R wraps resty's R method -func (mc *MonitorClient) R(ctx context.Context) *resty.Request { - return mc.resty.R(). - ExpectContentType("application/json"). - SetHeader("Content-Type", "application/json"). - SetContext(ctx). - SetError(APIError{}) -} - -// SetDebug sets the debug on resty's client +// SetDebug sets the debug on the client func (mc *MonitorClient) SetDebug(debug bool) *MonitorClient { mc.debug = debug - mc.resty.SetDebug(debug) return mc } @@ -97,7 +102,7 @@ func (mc *MonitorClient) SetDebug(debug bool) *MonitorClient { // SetLogger allows the user to override the output // logger for debug logs. func (mc *MonitorClient) SetLogger(logger Logger) *MonitorClient { - mc.resty.SetLogger(logger) + mc.logger = logger return mc } @@ -124,21 +129,44 @@ func (mc *MonitorClient) SetAPIVersion(apiVersion string) *MonitorClient { } // SetRootCertificate adds a root certificate to the underlying TLS client config -func (mc *MonitorClient) SetRootCertificate(path string) *MonitorClient { - mc.resty.SetRootCertificate(path) +func (mc *MonitorClient) SetRootCertificate(certPath string) *MonitorClient { + transport, ok := mc.httpClient.Transport.(*http.Transport) + if !ok { + mc.logger.Errorf("current transport is not an *http.Transport instance") + return mc + } + + if transport.TLSClientConfig == nil { + transport.TLSClientConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + } + } + + if transport.TLSClientConfig.RootCAs == nil { + transport.TLSClientConfig.RootCAs = x509.NewCertPool() + } + + pem, err := os.ReadFile(filepath.Clean(certPath)) + if err != nil { + mc.logger.Errorf("Failed to read root certificate at %s: %s", certPath, err.Error()) + return mc + } + + transport.TLSClientConfig.RootCAs.AppendCertsFromPEM(pem) + return mc } // SetToken sets the API token for all requests from this client func (mc *MonitorClient) SetToken(token string) *MonitorClient { - mc.resty.SetHeader("Authorization", fmt.Sprintf("Bearer %s", token)) + mc.header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) return mc } // SetHeader sets a custom header to be used in all API requests made with the current client. // NOTE: Some headers may be overridden by the individual request functions. func (mc *MonitorClient) SetHeader(name, value string) { - mc.resty.SetHeader(name, value) + mc.header.Set(name, value) } func (mc *MonitorClient) updateMonitorHostURL() { @@ -158,12 +186,66 @@ func (mc *MonitorClient) updateMonitorHostURL() { apiProto = mc.apiProtocol } - mc.resty.SetBaseURL( - fmt.Sprintf( - "%s://%s/%s", - apiProto, - baseURL, - url.PathEscape(apiVersion), - ), + mc.hostURL = fmt.Sprintf( + "%s://%s/%s", + apiProto, + baseURL, + url.PathEscape(apiVersion), ) } + +// doRequest is a generic helper to execute HTTP requests for the MonitorClient +func (mc *MonitorClient) doRequest(ctx context.Context, method, endpoint string, params requestParams) error { + var bodyReader io.Reader + + if params.Body != nil { + if _, err := params.Body.Seek(0, io.SeekStart); err != nil { + return fmt.Errorf("failed to seek body: %w", err) + } + + bodyReader = params.Body + } + + reqURL := fmt.Sprintf("%s/%s", strings.TrimRight(mc.hostURL, "/"), strings.TrimLeft(endpoint, "/")) + + req, err := http.NewRequestWithContext(ctx, method, reqURL, bodyReader) + if err != nil { + return fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept", "application/json") + + for name, values := range mc.header { + for _, value := range values { + req.Header.Set(name, value) + } + } + + if mc.debug && mc.logger != nil { + mc.logger.Debugf("Sending request: %s %s", method, reqURL) + } + + resp, err := mc.httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %w", err) + } + defer resp.Body.Close() + + _, err = coupleAPIErrors(resp, nil) + if err != nil { + return err + } + + if mc.debug && mc.logger != nil { + mc.logger.Debugf("Received response: %s", resp.Status) + } + + if params.Response != nil { + if err := json.NewDecoder(resp.Body).Decode(params.Response); err != nil { + return fmt.Errorf("failed to decode response: %w", err) + } + } + + return nil +} diff --git a/client_test.go b/client_test.go index f925f3678..da4997c17 100644 --- a/client_test.go +++ b/client_test.go @@ -37,39 +37,39 @@ func TestClient_SetAPIVersion(t *testing.T) { client := NewClient(nil) - if client.resty.BaseURL != defaultURL { - t.Fatal(cmp.Diff(client.resty.BaseURL, defaultURL)) + if client.hostURL != defaultURL { + t.Fatal(cmp.Diff(client.hostURL, defaultURL)) } client.SetBaseURL(baseURL) client.SetAPIVersion(apiVersion) - if client.resty.BaseURL != expectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, expectedHost)) + if client.hostURL != expectedHost { + t.Fatal(cmp.Diff(client.hostURL, expectedHost)) } // Ensure setting twice does not cause conflicts client.SetBaseURL(updatedBaseURL) client.SetAPIVersion(updatedAPIVersion) - if client.resty.BaseURL != updatedExpectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, updatedExpectedHost)) + if client.hostURL != updatedExpectedHost { + t.Fatal(cmp.Diff(client.hostURL, updatedExpectedHost)) } // Revert client.SetBaseURL(baseURL) client.SetAPIVersion(apiVersion) - if client.resty.BaseURL != expectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, expectedHost)) + if client.hostURL != expectedHost { + t.Fatal(cmp.Diff(client.hostURL, expectedHost)) } // Custom protocol client.SetBaseURL(protocolBaseURL) client.SetAPIVersion(protocolAPIVersion) - if client.resty.BaseURL != protocolExpectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, expectedHost)) + if client.hostURL != protocolExpectedHost { + t.Fatal(cmp.Diff(client.hostURL, expectedHost)) } } @@ -111,7 +111,7 @@ func TestClient_NewFromEnvToken(t *testing.T) { t.Fatal(err) } - if client.resty.Header.Get("Authorization") != "Bearer blah" { + if client.header.Get("Authorization") != "Bearer blah" { t.Fatal("token not found in auth header: blah") } } @@ -171,8 +171,8 @@ func TestClient_UseURL(t *testing.T) { t.Fatalf("unexpected error: %v", err) } - if client.resty.BaseURL != tt.wantBaseURL { - t.Fatalf("mismatched base url: got %s, want %s", client.resty.BaseURL, tt.wantBaseURL) + if client.hostURL != tt.wantBaseURL { + t.Fatalf("mismatched base url: got %s, want %s", client.hostURL, tt.wantBaseURL) } }) } @@ -209,12 +209,12 @@ func TestDebugLogSanitization(t *testing.T) { logger.L.SetOutput(&lgr) mockClient.SetDebug(true) - if !mockClient.resty.Debug { + if !mockClient.debug { t.Fatal("debug should be enabled") } mockClient.SetHeader("Authorization", fmt.Sprintf("Bearer %s", plainTextToken)) - if mockClient.resty.Header.Get("Authorization") != fmt.Sprintf("Bearer %s", plainTextToken) { + if mockClient.header.Get("Authorization") != fmt.Sprintf("Bearer %s", plainTextToken) { t.Fatal("token not found in auth header") } @@ -242,22 +242,25 @@ func TestDebugLogSanitization(t *testing.T) { func TestDoRequest_Success(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"}`)) + if r.URL.Path == "/v4/foo/bar" { + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"message":"success"}`)) + } else { + http.NotFound(w, r) + } } server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := &httpClient{ - httpClient: server.Client(), - } + client := NewClient(server.Client()) + client.SetBaseURL(server.URL) - params := RequestParams{ + params := requestParams{ Response: &map[string]string{}, } - err := client.doRequest(context.Background(), http.MethodGet, server.URL, params) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", params, nil) // Pass only the endpoint if err != nil { t.Fatal(cmp.Diff(nil, err)) } @@ -269,31 +272,11 @@ func TestDoRequest_Success(t *testing.T) { } } -func TestDoRequest_FailedEncodeBody(t *testing.T) { - client := &httpClient{ - httpClient: http.DefaultClient, - } - - params := RequestParams{ - Body: map[string]interface{}{ - "invalid": func() {}, - }, - } - - err := client.doRequest(context.Background(), http.MethodPost, "http://example.com", params) - expectedErr := "failed to encode body" - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Fatalf("expected error %q, got: %v", expectedErr, err) - } -} - func TestDoRequest_FailedCreateRequest(t *testing.T) { - client := &httpClient{ - httpClient: http.DefaultClient, - } + client := NewClient(nil) - // Create a request with an invalid URL to simulate a request creation failure - err := client.doRequest(context.Background(), http.MethodGet, "http://invalid url", RequestParams{}) + // Create a request with an invalid method to simulate a request creation failure + err := client.doRequest(context.Background(), "bad method", "/foo/bar", requestParams{}, nil) expectedErr := "failed to create request" if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Fatalf("expected error %q, got: %v", expectedErr, err) @@ -302,26 +285,28 @@ func TestDoRequest_FailedCreateRequest(t *testing.T) { func TestDoRequest_Non2xxStatusCode(t *testing.T) { handler := func(w http.ResponseWriter, r *http.Request) { - http.Error(w, "error", http.StatusInternalServerError) + http.Error(w, "error", http.StatusInternalServerError) // Simulate a 500 Internal Server Error } server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := &httpClient{ - httpClient: server.Client(), - } + client := NewClient(server.Client()) + client.SetBaseURL(server.URL) - err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", requestParams{}, nil) if err == nil { t.Fatal("expected error, got nil") } - httpError, ok := err.(Error) + + httpError, ok := err.(*Error) if !ok { t.Fatalf("expected error to be of type Error, got %T", err) } + if httpError.Code != http.StatusInternalServerError { t.Fatalf("expected status code %d, got %d", http.StatusInternalServerError, httpError.Code) } + if !strings.Contains(httpError.Message, "error") { t.Fatalf("expected error message to contain %q, got %v", "error", httpError.Message) } @@ -331,21 +316,21 @@ func TestDoRequest_FailedDecodeResponse(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(`invalid json`)) + _, _ = w.Write([]byte(`invalid json`)) // Simulate invalid JSON } server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := &httpClient{ - httpClient: server.Client(), - } + client := NewClient(server.Client()) + client.SetBaseURL(server.URL) - params := RequestParams{ + params := requestParams{ Response: &map[string]string{}, } - err := client.doRequest(context.Background(), http.MethodGet, server.URL, params) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", params, nil) expectedErr := "failed to decode response" + if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Fatalf("expected error %q, got: %v", expectedErr, err) } @@ -363,24 +348,21 @@ func TestDoRequest_BeforeRequestSuccess(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := &httpClient{ - httpClient: server.Client(), - } + client := NewClient(server.Client()) + client.SetBaseURL(server.URL) - // 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) + client.OnBeforeRequest(mutator) - err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", requestParams{}, nil) 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) } @@ -395,18 +377,18 @@ func TestDoRequest_BeforeRequestError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := &httpClient{ - httpClient: server.Client(), - } + client := NewClient(server.Client()) + client.SetBaseURL(server.URL) mutator := func(req *http.Request) error { return errors.New("mutator error") } - client.httpOnBeforeRequest(mutator) + client.OnBeforeRequest(mutator) - err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", requestParams{}, nil) expectedErr := "failed to mutate before request" + if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Fatalf("expected error %q, got: %v", expectedErr, err) } @@ -425,23 +407,21 @@ func TestDoRequest_AfterResponseSuccess(t *testing.T) { tr := &testRoundTripper{ Transport: server.Client().Transport, } - client := &httpClient{ - httpClient: &http.Client{Transport: tr}, - } + client := NewClient(&http.Client{Transport: tr}) + client.SetBaseURL(server.URL) mutator := func(resp *http.Response) error { resp.Header.Set("X-Modified-Header", "ModifiedValue") return nil } - client.httpOnAfterResponse(mutator) + client.OnAfterResponse(mutator) - err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", requestParams{}, nil) 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) } @@ -456,17 +436,16 @@ func TestDoRequest_AfterResponseError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := &httpClient{ - httpClient: server.Client(), - } + client := NewClient(server.Client()) + client.SetBaseURL(server.URL) mutator := func(resp *http.Response) error { return errors.New("mutator error") } - client.httpOnAfterResponse(mutator) + client.OnAfterResponse(mutator) - err := client.doRequest(context.Background(), http.MethodGet, server.URL, RequestParams{}) + err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", requestParams{}, nil) expectedErr := "failed to mutate after response" if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Fatalf("expected error %q, got: %v", expectedErr, err) @@ -478,11 +457,9 @@ func TestDoRequestLogging_Success(t *testing.T) { logger := createLogger() logger.l.SetOutput(&logBuffer) // Redirect log output to buffer - client := &httpClient{ - httpClient: http.DefaultClient, - debug: true, - logger: logger, - } + client := NewClient(nil) + client.SetDebug(true) + client.SetLogger(logger) handler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) @@ -490,29 +467,46 @@ func TestDoRequestLogging_Success(t *testing.T) { _, _ = w.Write([]byte(`{"message":"success"}`)) } server := httptest.NewServer(http.HandlerFunc(handler)) + client.SetBaseURL(server.URL) defer server.Close() - params := RequestParams{ + params := requestParams{ Response: &map[string]string{}, } + endpoint := "/foo/bar" - err := client.doRequest(context.Background(), http.MethodGet, server.URL, params) + err := client.doRequest(context.Background(), http.MethodGet, endpoint, params, nil) if err != nil { t.Fatal(cmp.Diff(nil, err)) } logInfo := logBuffer.String() - logInfoWithoutTimestamps := removeTimestamps(logInfo) - // Expected logs with templates filled in - expectedRequestLog := "DEBUG RESTY Sending request:\nMethod: GET\nURL: " + server.URL + "\nHeaders: map[Accept:[application/json] Content-Type:[application/json]]\nBody: " - expectedResponseLog := "DEBUG RESTY Received response:\nStatus: 200 OK\nHeaders: map[Content-Length:[21] Content-Type:[text/plain; charset=utf-8]]\nBody: {\"message\":\"success\"}" + expectedRequestParts := []string{ + "GET /v4/foo/bar HTTP/1.1", + "Accept: application/json", + "Authorization: Bearer *******************************", + "Content-Type: application/json", + "User-Agent: linodego/dev https://github.com/linode/linodego", + } - if !strings.Contains(logInfo, expectedRequestLog) { - t.Fatalf("expected log %q not found in logs", expectedRequestLog) + expectedResponseParts := []string{ + "STATUS: 200 OK", + "PROTO: HTTP/1.1", + "Content-Length: 21", + "Content-Type: application/json", + `"message": "success"`, } - if !strings.Contains(logInfoWithoutTimestamps, expectedResponseLog) { - t.Fatalf("expected log %q not found in logs", expectedResponseLog) + + for _, part := range expectedRequestParts { + if !strings.Contains(logInfo, part) { + t.Fatalf("expected request part %q not found in logs", part) + } + } + for _, part := range expectedResponseParts { + if !strings.Contains(logInfo, part) { + t.Fatalf("expected response part %q not found in logs", part) + } } } @@ -521,26 +515,19 @@ func TestDoRequestLogging_Error(t *testing.T) { logger := createLogger() logger.l.SetOutput(&logBuffer) // Redirect log output to buffer - client := &httpClient{ - httpClient: http.DefaultClient, - debug: true, - logger: logger, - } - - params := RequestParams{ - Body: map[string]interface{}{ - "invalid": func() {}, - }, - } + client := NewClient(nil) + client.SetDebug(true) + client.SetLogger(logger) - err := client.doRequest(context.Background(), http.MethodPost, "http://example.com", params) - expectedErr := "failed to encode body" + // Create a request with an invalid method to simulate a request creation failure + err := client.doRequest(context.Background(), "bad method", "/foo/bar", requestParams{}, nil) + expectedErr := "failed to create request" if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Fatalf("expected error %q, got: %v", expectedErr, err) } logInfo := logBuffer.String() - expectedLog := "ERROR RESTY failed to encode body" + expectedLog := "ERROR failed to create request" if !strings.Contains(logInfo, expectedLog) { t.Fatalf("expected log %q not found in logs", expectedLog) @@ -638,9 +625,9 @@ func TestClient_CustomRootCAWithoutCustomRoundTripper(t *testing.T) { } client := NewClient(test.httpClient) - transport, err := client.resty.Transport() - if err != nil { - t.Fatal(err) + transport, ok := client.httpClient.Transport.(*http.Transport) + if !ok { + t.Fatal("expected *http.Transport") } if test.setCA && (transport.TLSClientConfig == nil || transport.TLSClientConfig.RootCAs == nil) { t.Error("expected root CAs to be set") @@ -669,39 +656,39 @@ func TestMonitorClient_SetAPIBasics(t *testing.T) { client := NewMonitorClient(nil) - if client.resty.BaseURL != defaultURL { - t.Fatal(cmp.Diff(client.resty.BaseURL, defaultURL)) + if client.hostURL != defaultURL { + t.Fatal(cmp.Diff(client.hostURL, defaultURL)) } client.SetBaseURL(baseURL) client.SetAPIVersion(apiVersion) - if client.resty.BaseURL != expectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, expectedHost)) + if client.hostURL != expectedHost { + t.Fatal(cmp.Diff(client.hostURL, expectedHost)) } // Ensure setting twice does not cause conflicts client.SetBaseURL(updatedBaseURL) client.SetAPIVersion(updatedAPIVersion) - if client.resty.BaseURL != updatedExpectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, updatedExpectedHost)) + if client.hostURL != updatedExpectedHost { + t.Fatal(cmp.Diff(client.hostURL, updatedExpectedHost)) } // Revert client.SetBaseURL(baseURL) client.SetAPIVersion(apiVersion) - if client.resty.BaseURL != expectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, expectedHost)) + if client.hostURL != expectedHost { + t.Fatal(cmp.Diff(client.hostURL, expectedHost)) } // Custom protocol client.SetBaseURL(protocolBaseURL) client.SetAPIVersion(protocolAPIVersion) - if client.resty.BaseURL != protocolExpectedHost { - t.Fatal(cmp.Diff(client.resty.BaseURL, expectedHost)) + if client.hostURL != protocolExpectedHost { + t.Fatal(cmp.Diff(client.hostURL, expectedHost)) } } @@ -787,7 +774,7 @@ func TestEnableLogSanitization(t *testing.T) { "Authorization": []string{"Bearer " + plainTextToken}, })) - _, err := mockClient.resty.R().Get("https://api.linode.com/v4/test") + err := mockClient.doRequest(context.Background(), http.MethodGet, "/test", requestParams{}, nil) require.NoError(t, err) logOutput := logBuf.String() diff --git a/config_test.go b/config_test.go index b4b3db418..628cc1415 100644 --- a/config_test.go +++ b/config_test.go @@ -42,11 +42,11 @@ func TestConfig_LoadWithDefaults(t *testing.T) { expectedURL := "https://api.cool.linode.com/v4beta" - if client.resty.BaseURL != expectedURL { - t.Fatalf("mismatched host url: %s != %s", client.resty.BaseURL, expectedURL) + if client.hostURL != expectedURL { + t.Fatalf("mismatched host url: %s != %s", client.hostURL, expectedURL) } - if client.resty.Header.Get("Authorization") != "Bearer "+p.APIToken { + if client.header.Get("Authorization") != "Bearer "+p.APIToken { t.Fatalf("token not found in auth header: %s", p.APIToken) } } @@ -88,11 +88,11 @@ func TestConfig_OverrideDefaults(t *testing.T) { expectedURL := "https://api.cool.linode.com/v4" - if client.resty.BaseURL != expectedURL { - t.Fatalf("mismatched host url: %s != %s", client.resty.BaseURL, expectedURL) + if client.hostURL != expectedURL { + t.Fatalf("mismatched host url: %s != %s", client.hostURL, expectedURL) } - if client.resty.Header.Get("Authorization") != "Bearer "+p.APIToken { + if client.header.Get("Authorization") != "Bearer "+p.APIToken { t.Fatalf("token not found in auth header: %s", p.APIToken) } } @@ -124,7 +124,7 @@ func TestConfig_NoDefaults(t *testing.T) { t.Fatalf("mismatched api token: %s != %s", p.APIToken, "mytoken") } - if client.resty.Header.Get("Authorization") != "Bearer "+p.APIToken { + if client.header.Get("Authorization") != "Bearer "+p.APIToken { t.Fatalf("token not found in auth header: %s", p.APIToken) } } diff --git a/errors.go b/errors.go index 873b40450..db7fc2a34 100644 --- a/errors.go +++ b/errors.go @@ -1,7 +1,7 @@ package linodego import ( - "encoding/json" + "bytes" "errors" "fmt" "io" @@ -9,8 +9,6 @@ import ( "reflect" "slices" "strings" - - "github.com/go-resty/resty/v2" ) const ( @@ -49,74 +47,43 @@ type APIError struct { Errors []APIErrorReason `json:"errors"` } -// String returns the error reason in a formatted string -func (r APIErrorReason) String() string { - return fmt.Sprintf("[%s] %s", r.Field, r.Reason) -} - -func coupleAPIErrors(r *resty.Response, err error) (*resty.Response, error) { +//nolint:nestif,unparam +func coupleAPIErrors(resp *http.Response, err error) (*http.Response, error) { if err != nil { - // an error was raised in go code, no need to check the resty Response return nil, NewError(err) } - if r.Error() == nil { - // no error in the resty Response - return r, nil - } - - // handle the resty Response errors - - // Check that response is of the correct content-type before unmarshalling - expectedContentType := r.Request.Header.Get("Accept") - responseContentType := r.Header().Get("Content-Type") - - // If the upstream Linode API server being fronted fails to respond to the request, - // the http server will respond with a default "Bad Gateway" page with Content-Type - // "text/html". - if r.StatusCode() == http.StatusBadGateway && responseContentType == "text/html" { //nolint:goconst - return nil, Error{Code: http.StatusBadGateway, Message: http.StatusText(http.StatusBadGateway)} - } - - if responseContentType != expectedContentType { - msg := fmt.Sprintf( - "Unexpected Content-Type: Expected: %v, Received: %v\nResponse body: %s", - expectedContentType, - responseContentType, - string(r.Body()), - ) - - return nil, Error{Code: r.StatusCode(), Message: msg} - } - - apiError, ok := r.Error().(*APIError) - if !ok || (ok && len(apiError.Errors) == 0) { - return r, nil + if resp == nil { + return nil, NewError(fmt.Errorf("response is nil")) } - return nil, NewError(r) -} - -//nolint:unused -func coupleAPIErrorsHTTP(resp *http.Response, err error) (*http.Response, error) { - if err != nil { - // an error was raised in go code, no need to check the http.Response - return nil, NewError(err) - } - - if resp == nil || resp.StatusCode < 200 || resp.StatusCode >= 300 { + if resp.StatusCode < 200 || resp.StatusCode >= 300 { // Check that response is of the correct content-type before unmarshalling - expectedContentType := resp.Request.Header.Get("Accept") + expectedContentType := "" + if resp.Request != nil && resp.Request.Header != nil { + expectedContentType = resp.Request.Header.Get("Accept") + } + responseContentType := resp.Header.Get("Content-Type") // If the upstream server fails to respond to the request, - // the http server will respond with a default error page with Content-Type "text/html". - if resp.StatusCode == http.StatusBadGateway && responseContentType == "text/html" { //nolint:goconst - return nil, Error{Code: http.StatusBadGateway, Message: http.StatusText(http.StatusBadGateway)} + // the HTTP server will respond with a default error page with Content-Type "text/html". + if resp.StatusCode == http.StatusBadGateway && responseContentType == "text/html" { + return nil, &Error{Code: http.StatusBadGateway, Message: http.StatusText(http.StatusBadGateway), Response: resp} } if responseContentType != expectedContentType { - bodyBytes, _ := io.ReadAll(resp.Body) + if resp.Body == nil { + return nil, NewError(fmt.Errorf("response body is nil")) + } + + bodyBytes, readErr := io.ReadAll(resp.Body) + if readErr != nil { + return nil, NewError(fmt.Errorf("failed to read response body: %w", readErr)) + } + + resp.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) + msg := fmt.Sprintf( "Unexpected Content-Type: Expected: %v, Received: %v\nResponse body: %s", expectedContentType, @@ -124,22 +91,22 @@ func coupleAPIErrorsHTTP(resp *http.Response, err error) (*http.Response, error) string(bodyBytes), ) - return nil, Error{Code: resp.StatusCode, Message: msg} + return nil, &Error{Code: resp.StatusCode, Message: msg, Response: resp} } - var apiError APIError - if err := json.NewDecoder(resp.Body).Decode(&apiError); err != nil { - return nil, NewError(fmt.Errorf("failed to decode response body: %w", err)) + // Must check if there is no list of reasons in the error before making a call to NewError + apiError, ok := getAPIError(resp) + if !ok { + return nil, NewError(fmt.Errorf("failed to decode response body")) } if len(apiError.Errors) == 0 { return resp, nil } - return nil, Error{Code: resp.StatusCode, Message: apiError.Errors[0].String()} + return nil, NewError(resp) } - // no error in the http.Response return resp, nil } @@ -156,7 +123,7 @@ func (e APIError) Error() string { // - ErrorFromString (1) from a string // - ErrorFromError (2) for an error // - ErrorFromStringer (3) for a Stringer -// - HTTP Status Codes (100-600) for a resty.Response object +// - HTTP Status Codes (100-600) for a http.Response object func NewError(err any) *Error { if err == nil { return nil @@ -165,17 +132,17 @@ func NewError(err any) *Error { switch e := err.(type) { case *Error: return e - case *resty.Response: - apiError, ok := e.Error().(*APIError) + case *http.Response: + apiError, ok := getAPIError(e) if !ok { - return &Error{Code: ErrorUnsupported, Message: "Unexpected Resty Error Response, no error"} + return &Error{Code: ErrorUnsupported, Message: "Unexpected HTTP Error Response, no error"} } return &Error{ - Code: e.RawResponse.StatusCode, + Code: e.StatusCode, Message: apiError.Error(), - Response: e.RawResponse, + Response: e, } case error: return &Error{Code: ErrorFromError, Message: e.Error()} diff --git a/errors_test.go b/errors_test.go index 68428fcd6..4a182c36e 100644 --- a/errors_test.go +++ b/errors_test.go @@ -9,9 +9,10 @@ import ( "io" "net/http" "net/http/httptest" + "strconv" + "strings" "testing" - "github.com/go-resty/resty/v2" "github.com/google/go-cmp/cmp" ) @@ -27,10 +28,10 @@ func (e testError) Error() string { return string(e) } -func restyError(reason, field string) *resty.Response { +func httpError(reason, field string) *http.Response { var reasons []APIErrorReason - // allow for an empty reasons + // Allow for an empty reasons if reason != "" && field != "" { reasons = append(reasons, APIErrorReason{ Reason: reason, @@ -38,15 +39,18 @@ func restyError(reason, field string) *resty.Response { }) } - return &resty.Response{ - RawResponse: &http.Response{ - StatusCode: 500, - }, - Request: &resty.Request{ - Error: &APIError{ - Errors: reasons, - }, - }, + apiError := &APIError{ + Errors: reasons, + } + + body, err := json.Marshal(apiError) + if err != nil { + panic("Failed to marshal APIError") + } + + return &http.Response{ + StatusCode: 500, + Body: io.NopCloser(bytes.NewReader(body)), } } @@ -73,12 +77,12 @@ func TestNewError(t *testing.T) { t.Error("Error should be itself") } - if err := NewError(&resty.Response{Request: &resty.Request{}}); err.Message != "Unexpected Resty Error Response, no error" { - t.Error("Unexpected Resty Error Response, no error") + if err := NewError(&http.Response{Request: &http.Request{}}); err.Message != "Unexpected HTTP Error Response, no error" { + t.Error("Unexpected HTTP Error Response, no error") } - if err := NewError(restyError("testreason", "testfield")); err.Message != "[testfield] testreason" { - t.Error("rest response error should should be set") + if err := NewError(httpError("testreason", "testfield")); err.Message != "[testfield] testreason" { + t.Error("http response error should should be set") } if err := NewError("stringerror"); err.Message != "stringerror" || err.Code != ErrorFromString { @@ -119,98 +123,6 @@ func TestCoupleAPIErrors(t *testing.T) { } }) - t.Run("resty 500 response error with reasons", func(t *testing.T) { - if _, err := coupleAPIErrors(restyError("testreason", "testfield"), nil); err.Error() != "[500] [testfield] testreason" { - t.Error("resty error should return with proper format [code] [field] reason") - } - }) - - t.Run("resty 500 response error without reasons", func(t *testing.T) { - if _, err := coupleAPIErrors(restyError("", ""), nil); err != nil { - t.Error("resty error with no reasons should return no error") - } - }) - - t.Run("resty response with nil error", func(t *testing.T) { - emptyErr := &resty.Response{ - RawResponse: &http.Response{ - StatusCode: 500, - }, - Request: &resty.Request{ - Error: nil, - }, - } - if _, err := coupleAPIErrors(emptyErr, nil); err != nil { - t.Error("resty error with no reasons should return no error") - } - }) - - t.Run("generic html error", func(t *testing.T) { - rawResponse := ` -500 Internal Server Error - -

500 Internal Server Error

-
nginx
- -` - route := "/v4/linode/instances/123" - ts, client := createTestServer(http.MethodGet, route, "text/html", rawResponse, http.StatusInternalServerError) - // client.SetDebug(true) - defer ts.Close() - - expectedError := Error{ - Code: http.StatusInternalServerError, - Message: "Unexpected Content-Type: Expected: application/json, Received: text/html\nResponse body: " + rawResponse, - } - - _, err := coupleAPIErrors(client.R(context.Background()).SetResult(&Instance{}).Get(ts.URL + route)) - if diff := cmp.Diff(expectedError, err); diff != "" { - t.Errorf("expected error to match but got diff:\n%s", diff) - } - }) - - t.Run("bad gateway error", func(t *testing.T) { - rawResponse := []byte(` -502 Bad Gateway - -

502 Bad Gateway

-
nginx
- -`) - buf := io.NopCloser(bytes.NewBuffer(rawResponse)) - - resp := &resty.Response{ - Request: &resty.Request{ - Error: errors.New("Bad Gateway"), - }, - RawResponse: &http.Response{ - Header: http.Header{ - "Content-Type": []string{"text/html"}, - }, - StatusCode: http.StatusBadGateway, - Body: buf, - }, - } - - expectedError := Error{ - Code: http.StatusBadGateway, - Message: http.StatusText(http.StatusBadGateway), - } - - if _, err := coupleAPIErrors(resp, nil); !cmp.Equal(err, expectedError) { - t.Errorf("expected error %#v to match error %#v", err, expectedError) - } - }) -} - -func TestCoupleAPIErrorsHTTP(t *testing.T) { - t.Run("not nil error generates error", func(t *testing.T) { - err := errors.New("test") - if _, err := coupleAPIErrorsHTTP(nil, err); !cmp.Equal(err, NewError(err)) { - t.Errorf("expect a not nil error to be returned as an Error") - } - }) - t.Run("http 500 response error with reasons", func(t *testing.T) { // Create the simulated HTTP response with a 500 status and a JSON body containing the error details apiError := APIError{ @@ -228,7 +140,7 @@ func TestCoupleAPIErrorsHTTP(t *testing.T) { Request: &http.Request{Header: http.Header{"Accept": []string{"application/json"}}}, } - _, err := coupleAPIErrorsHTTP(resp, nil) + _, err := coupleAPIErrors(resp, nil) expectedMessage := "[500] [testfield] testreason" if err == nil || err.Error() != expectedMessage { t.Errorf("expected error message %q, got: %v", expectedMessage, err) @@ -250,7 +162,7 @@ func TestCoupleAPIErrorsHTTP(t *testing.T) { Request: &http.Request{Header: http.Header{"Accept": []string{"application/json"}}}, } - _, err := coupleAPIErrorsHTTP(resp, nil) + _, err := coupleAPIErrors(resp, nil) if err != nil { t.Error("http error with no reasons should return no error") } @@ -265,7 +177,7 @@ func TestCoupleAPIErrorsHTTP(t *testing.T) { Request: &http.Request{Header: http.Header{"Accept": []string{"application/json"}}}, } - _, err := coupleAPIErrorsHTTP(resp, nil) + _, err := coupleAPIErrors(resp, nil) if err != nil { t.Error("http error with no reasons should return no error") } @@ -288,15 +200,10 @@ func TestCoupleAPIErrorsHTTP(t *testing.T) { })) defer ts.Close() - client := &httpClient{ + client := &Client{ httpClient: ts.Client(), } - expectedError := Error{ - Code: http.StatusInternalServerError, - Message: "Unexpected Content-Type: Expected: application/json, Received: text/html\nResponse body: " + rawResponse, - } - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, ts.URL+route, nil) if err != nil { t.Fatalf("failed to create request: %v", err) @@ -308,11 +215,23 @@ func TestCoupleAPIErrorsHTTP(t *testing.T) { if err != nil { t.Fatalf("failed to send request: %v", err) } + + expectedError := &Error{ + Response: resp, + Code: http.StatusInternalServerError, + Message: "Unexpected Content-Type: Expected: application/json, Received: text/html\nResponse body: " + rawResponse, + } + defer resp.Body.Close() - _, err = coupleAPIErrorsHTTP(resp, nil) - if diff := cmp.Diff(expectedError, err); diff != "" { - t.Errorf("expected error to match but got diff:\n%s", diff) + _, err = coupleAPIErrors(resp, nil) + + if !strings.Contains(err.Error(), strconv.Itoa(expectedError.Code)) { + t.Errorf("expected error code %d, got %d", expectedError.Code, resp.StatusCode) + } + + if !strings.Contains(err.Error(), expectedError.Message) { + t.Errorf("expected error message %s, got %s", expectedError.Message, err.Error()) } }) @@ -337,14 +256,19 @@ func TestCoupleAPIErrorsHTTP(t *testing.T) { }, } - expectedError := Error{ - Code: http.StatusBadGateway, - Message: http.StatusText(http.StatusBadGateway), + expectedError := &Error{ + Response: resp, + Code: http.StatusBadGateway, + Message: http.StatusText(http.StatusBadGateway), + } + + _, err := coupleAPIErrors(resp, nil) + if !strings.Contains(err.Error(), strconv.Itoa(expectedError.Code)) { + t.Errorf("expected error code %d, got %d", expectedError.Code, resp.StatusCode) } - _, err := coupleAPIErrorsHTTP(resp, nil) - if !cmp.Equal(err, expectedError) { - t.Errorf("expected error %#v to match error %#v", err, expectedError) + if !strings.Contains(err.Error(), expectedError.Message) { + t.Errorf("expected error message %s, got %s", expectedError.Message, err.Error()) } }) } @@ -382,26 +306,26 @@ func TestErrorIs(t *testing.T) { expectedResult: true, }, { - testName: "default and Error from empty resty error", - err1: NewError(restyError("", "")), + testName: "default and Error from empty http error", + err1: NewError(httpError("", "")), err2: defaultError, expectedResult: true, }, { - testName: "default and Error from resty error with field", - err1: NewError(restyError("", "test field")), + testName: "default and Error from http error with field", + err1: NewError(httpError("", "test field")), err2: defaultError, expectedResult: true, }, { - testName: "default and Error from resty error with field and reason", - err1: NewError(restyError("test reason", "test field")), + testName: "default and Error from http error with field and reason", + err1: NewError(httpError("test reason", "test field")), err2: defaultError, expectedResult: true, }, { - testName: "default and Error from resty error with reason", - err1: NewError(restyError("test reason", "")), + testName: "default and Error from http error with reason", + err1: NewError(httpError("test reason", "")), err2: defaultError, expectedResult: true, }, diff --git a/go.mod b/go.mod index b00d38c4c..6cc016482 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,6 @@ module github.com/linode/linodego require ( - github.com/go-resty/resty/v2 v2.17.2 github.com/google/go-cmp v0.7.0 github.com/google/go-querystring v1.2.0 github.com/jarcoal/httpmock v1.4.1 diff --git a/go.sum b/go.sum index fcb368761..5b27625ab 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= -github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -29,8 +27,6 @@ golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k= diff --git a/images.go b/images.go index 5fdf644fb..da2287047 100644 --- a/images.go +++ b/images.go @@ -4,9 +4,9 @@ import ( "context" "encoding/json" "io" + "net/http" "time" - "github.com/go-resty/resty/v2" "github.com/linode/linodego/internal/parseabletime" ) @@ -297,17 +297,48 @@ func (c *Client) CreateImageUpload(ctx context.Context, opts ImageCreateUploadOp // UploadImageToURL uploads the given image to the given upload URL. func (c *Client) UploadImageToURL(ctx context.Context, uploadURL string, image io.Reader) error { - // Linode-specific headers do not need to be sent to this endpoint - req := resty.New().SetDebug(c.resty.Debug).R(). - SetContext(ctx). - SetContentLength(true). - SetHeader("Content-Type", "application/octet-stream"). - SetBody(image) + clonedClient := *c.httpClient + clonedClient.Transport = http.DefaultTransport - _, err := coupleAPIErrors(req. - Put(uploadURL)) + var contentLength int64 = -1 - return err + if seeker, ok := image.(io.Seeker); ok { + size, err := seeker.Seek(0, io.SeekEnd) + if err != nil { + return err + } + + _, err = seeker.Seek(0, io.SeekStart) + if err != nil { + return err + } + + contentLength = size + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPut, uploadURL, image) + if err != nil { + return err + } + + if contentLength >= 0 { + req.ContentLength = contentLength + } + + req.Header.Set("Content-Type", "application/octet-stream") + req.Header.Set("User-Agent", c.userAgent) + + resp, err := clonedClient.Do(req) + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + _, err = coupleAPIErrors(resp, err) + if err != nil { + return err + } + + return nil } // UploadImage creates and uploads an image. diff --git a/internal/testutil/mock.go b/internal/testutil/mock.go index c8235ce65..752b27f9f 100644 --- a/internal/testutil/mock.go +++ b/internal/testutil/mock.go @@ -116,15 +116,15 @@ type TestLogger struct { } func (l *TestLogger) Errorf(format string, v ...any) { - l.outputf("ERROR RESTY "+format, v...) + l.outputf("ERROR "+format, v...) } func (l *TestLogger) Warnf(format string, v ...any) { - l.outputf("WARN RESTY "+format, v...) + l.outputf("WARN "+format, v...) } func (l *TestLogger) Debugf(format string, v ...any) { - l.outputf("DEBUG RESTY "+format, v...) + l.outputf("DEBUG "+format, v...) } func (l *TestLogger) outputf(format string, v ...any) { diff --git a/k8s/go.mod b/k8s/go.mod index 4e148b8c5..fe876ba3c 100644 --- a/k8s/go.mod +++ b/k8s/go.mod @@ -14,7 +14,6 @@ require ( github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-resty/resty/v2 v2.17.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect diff --git a/k8s/go.sum b/k8s/go.sum index 4e571690a..f93e11a91 100644 --- a/k8s/go.sum +++ b/k8s/go.sum @@ -12,8 +12,6 @@ github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2Kv github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= -github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/logger.go b/logger.go index 890327e2b..fc9504b50 100644 --- a/logger.go +++ b/logger.go @@ -1,52 +1,54 @@ package linodego import ( + "fmt" "log" "os" + "strings" ) -//nolint:unused -type httpLogger interface { +type Logger interface { Errorf(format string, v ...any) Warnf(format string, v ...any) Debugf(format string, v ...any) } -//nolint:unused type logger struct { l *log.Logger } -//nolint:unused func createLogger() *logger { l := &logger{l: log.New(os.Stderr, "", log.Ldate|log.Lmicroseconds)} return l } -//nolint:unused -var _ httpLogger = (*logger)(nil) +var _ Logger = (*logger)(nil) -//nolint:unused func (l *logger) Errorf(format string, v ...any) { - l.output("ERROR RESTY "+format, v...) + l.output("ERROR "+format, v...) } -//nolint:unused func (l *logger) Warnf(format string, v ...any) { - l.output("WARN RESTY "+format, v...) + l.output("WARN "+format, v...) } -//nolint:unused func (l *logger) Debugf(format string, v ...any) { - l.output("DEBUG RESTY "+format, v...) + l.output("DEBUG "+format, v...) } -//nolint:unused func (l *logger) output(format string, v ...any) { //nolint:goprintffuncname + // Render the final message first, then sanitize control characters + // to prevent log injection via both the format string and variadic args. + var msg string if len(v) == 0 { - l.l.Print(format) - return + msg = format + } else { + msg = fmt.Sprintf(format, v...) } - l.l.Printf(format, v...) + msg = strings.ReplaceAll(msg, "\r\n", "\\n") + msg = strings.ReplaceAll(msg, "\r", "\\n") + msg = strings.ReplaceAll(msg, "\n", "\\n") + + l.l.Print(msg) } diff --git a/monitor_alert_definitions.go b/monitor_alert_definitions.go index 730665655..7988ab673 100644 --- a/monitor_alert_definitions.go +++ b/monitor_alert_definitions.go @@ -1,8 +1,10 @@ package linodego import ( + "bytes" "context" "encoding/json" + "net/http" "time" "github.com/linode/linodego/internal/parseabletime" @@ -263,25 +265,28 @@ func (c *Client) CreateMonitorAlertDefinitionWithIdempotency( var result AlertDefinition - req := c.R(ctx).SetResult(&result) - - if idempotencyKey != "" { - req.SetHeader("Idempotency-Key", idempotencyKey) - } - body, err := json.Marshal(opts) if err != nil { return nil, err } - req.SetBody(string(body)) + params := requestParams{ + Response: &result, + Body: bytes.NewReader(body), + } + + if idempotencyKey != "" { + params.Headers = http.Header{ + "Idempotency-Key": {idempotencyKey}, + } + } - r, err := coupleAPIErrors(req.Post(e)) + err = c.doRequest(ctx, http.MethodPost, e, params, nil) if err != nil { return nil, err } - return r.Result().(*AlertDefinition), nil + return &result, nil } // UpdateMonitorAlertDefinition updates an ACLP Monitor Alert Definition. diff --git a/monitor_api_services.go b/monitor_api_services.go index 9d379353e..a7ee4ca6d 100644 --- a/monitor_api_services.go +++ b/monitor_api_services.go @@ -4,8 +4,10 @@ package linodego import ( + "bytes" "context" "encoding/json" + "net/http" "time" ) @@ -101,7 +103,11 @@ type MetricAbsoluteTimeDuration struct { func (mc *MonitorClient) FetchEntityMetrics(ctx context.Context, serviceType string, opts *EntityMetricsFetchOptions) (*EntityMetrics, error) { endpoint := formatAPIPath("monitor/services/%s/metrics", serviceType) - req := mc.R(ctx).SetResult(&EntityMetrics{}) + var result EntityMetrics + + params := requestParams{ + Response: &result, + } if opts != nil { body, err := json.Marshal(opts) @@ -109,13 +115,13 @@ func (mc *MonitorClient) FetchEntityMetrics(ctx context.Context, serviceType str return nil, err } - req.SetBody(string(body)) + params.Body = bytes.NewReader(body) } - r, err := coupleAPIErrors(req.Post(endpoint)) + err := mc.doRequest(ctx, http.MethodPost, endpoint, params) if err != nil { return nil, err } - return r.Result().(*EntityMetrics), nil + return &result, nil } diff --git a/pagination.go b/pagination.go index 074720e82..b0fec7040 100644 --- a/pagination.go +++ b/pagination.go @@ -9,10 +9,9 @@ import ( "encoding/hex" "encoding/json" "fmt" + "net/http" "reflect" "strconv" - - "github.com/go-resty/resty/v2" ) // PageOptions are the pagination parameters for List endpoints @@ -56,38 +55,51 @@ func (l ListOptions) Hash() (string, error) { return hex.EncodeToString(h.Sum(nil)), nil } -func applyListOptionsToRequest(opts *ListOptions, req *resty.Request) error { +func createListOptionsToRequestMutator(opts *ListOptions) func(*http.Request) error { if opts == nil { return nil } - if opts.QueryParams != nil { - params, err := flattenQueryStruct(opts.QueryParams) - if err != nil { - return fmt.Errorf("failed to apply list options: %w", err) + // Return a mutator to apply query parameters and headers + return func(req *http.Request) error { + query := req.URL.Query() + + // Apply QueryParams from ListOptions if present + if opts.QueryParams != nil { + params, err := flattenQueryStruct(opts.QueryParams) + if err != nil { + return fmt.Errorf("failed to apply list options: %w", err) + } + + for key, value := range params { + query.Set(key, value) + } } - req.SetQueryParams(params) - } + // Apply pagination options + if opts.PageOptions != nil && opts.Page > 0 { + query.Set("page", strconv.Itoa(opts.Page)) + } - if opts.PageOptions != nil && opts.Page > 0 { - req.SetQueryParam("page", strconv.Itoa(opts.Page)) - } + if opts.PageSize > 0 { + query.Set("page_size", strconv.Itoa(opts.PageSize)) + } - if opts.PageSize > 0 { - req.SetQueryParam("page_size", strconv.Itoa(opts.PageSize)) - } + // Apply filters as headers + if len(opts.Filter) > 0 { + req.Header.Set("X-Filter", opts.Filter) + } - if len(opts.Filter) > 0 { - req.SetHeader("X-Filter", opts.Filter) - } + // Assign the updated query back to the request URL + req.URL.RawQuery = query.Encode() - return nil + return nil + } } type PagedResponse interface { endpoint(...any) string - castResult(*resty.Request, string) (int, int, error) + castResult(*http.Request, string) (int, int, error) } // flattenQueryStruct flattens a structure into a Resty-compatible query param map. diff --git a/request_helpers.go b/request_helpers.go index d70e515ea..e50e4ec6d 100644 --- a/request_helpers.go +++ b/request_helpers.go @@ -1,9 +1,11 @@ package linodego import ( + "bytes" "context" "encoding/json" "fmt" + "net/http" "net/url" "reflect" ) @@ -60,56 +62,33 @@ func handlePaginatedResults[T any, O any]( handlePage := func(page int) error { var resultType paginatedResponse[T] - // Override the page to be applied in applyListOptionsToRequest(...) + // Override the page to be applied in createListOptionsToRequestMutator(...) opts.Page = page - // This request object cannot be reused for each page request - // because it can lead to possible data corruption - req := client.R(ctx).SetResult(&resultType) - - // Apply all user-provided list options to the request - if err := applyListOptionsToRequest(opts, req); err != nil { - return err + params := requestParams{ + Response: &resultType, } - // Set request body if provided if reqBody != "" { - req.SetBody(reqBody) + params.Body = bytes.NewReader([]byte(reqBody)) } - var response *paginatedResponse[T] - // Execute the appropriate HTTP method - switch method { - case "GET": - res, err := coupleAPIErrors(req.Get(endpoint)) - if err != nil { - return err - } - - response = res.Result().(*paginatedResponse[T]) - case "PUT": - res, err := coupleAPIErrors(req.Put(endpoint)) - if err != nil { - return err - } - - response = res.Result().(*paginatedResponse[T]) - case "POST": - res, err := coupleAPIErrors(req.Post(endpoint)) - if err != nil { - return err - } - - response = res.Result().(*paginatedResponse[T]) - default: - return fmt.Errorf("unsupported HTTP method: %s", method) + // Create a mutator to apply all user-provided list options to the request + mutator := createListOptionsToRequestMutator(opts) + + // Make the request using doRequest + err := client.doRequest(ctx, method, endpoint, params, &mutator) + if err != nil { + return err } // Update pagination metadata opts.Page = page - opts.Pages = response.Pages - opts.Results = response.Results - result = append(result, response.Data...) + opts.Pages = resultType.Pages + opts.Results = resultType.Results + + // Append the data to the result slice + result = append(result, resultType.Data...) return nil } @@ -127,13 +106,12 @@ func handlePaginatedResults[T any, O any]( return nil, err } - // If the user has explicitly specified a page, we don't - // need to get any other pages. + // If a specific page is defined, return the result if pageDefined { return result, nil } - // Get the rest of the pages + // Get the remaining pages for page := 2; page <= opts.Pages; page++ { if err := handlePage(page); err != nil { return nil, err @@ -187,14 +165,16 @@ func doGETRequest[T any]( ) (*T, error) { var resultType T - req := client.R(ctx).SetResult(&resultType) + params := requestParams{ + Response: &resultType, + } - r, err := coupleAPIErrors(req.Get(endpoint)) + err := client.doRequest(ctx, http.MethodGet, endpoint, params, nil) if err != nil { return nil, err } - return r.Result().(*T), nil + return &resultType, nil } // doPOSTRequest runs a PUT request using the given client, API endpoint, @@ -208,12 +188,13 @@ func doPOSTRequest[T, O any]( var resultType T numOpts := len(options) - if numOpts > 1 { - return nil, fmt.Errorf("invalid number of options: %d", len(options)) + return nil, fmt.Errorf("invalid number of options: %d", numOpts) } - req := client.R(ctx).SetResult(&resultType) + params := requestParams{ + Response: &resultType, + } if numOpts > 0 && !isNil(options[0]) { body, err := json.Marshal(options[0]) @@ -221,15 +202,15 @@ func doPOSTRequest[T, O any]( return nil, err } - req.SetBody(string(body)) + params.Body = bytes.NewReader(body) } - r, err := coupleAPIErrors(req.Post(endpoint)) + err := client.doRequest(ctx, http.MethodPost, endpoint, params, nil) if err != nil { return nil, err } - return r.Result().(*T), nil + return &resultType, nil } // doPOSTRequestNoResponseBody runs a POST request using the given client, API endpoint, @@ -241,6 +222,7 @@ func doPOSTRequestNoResponseBody[T any]( options ...T, ) error { _, err := doPOSTRequest[any, T](ctx, client, endpoint, options...) + return err } @@ -265,12 +247,13 @@ func doPUTRequest[T, O any]( var resultType T numOpts := len(options) - if numOpts > 1 { - return nil, fmt.Errorf("invalid number of options: %d", len(options)) + return nil, fmt.Errorf("invalid number of options: %d", numOpts) } - req := client.R(ctx).SetResult(&resultType) + params := requestParams{ + Response: &resultType, + } if numOpts > 0 && !isNil(options[0]) { body, err := json.Marshal(options[0]) @@ -278,15 +261,15 @@ func doPUTRequest[T, O any]( return nil, err } - req.SetBody(string(body)) + params.Body = bytes.NewReader(body) } - r, err := coupleAPIErrors(req.Put(endpoint)) + err := client.doRequest(ctx, http.MethodPut, endpoint, params, nil) if err != nil { return nil, err } - return r.Result().(*T), nil + return &resultType, nil } // doDELETERequest runs a DELETE request using the given client @@ -296,8 +279,8 @@ func doDELETERequest( client *Client, endpoint string, ) error { - req := client.R(ctx) - _, err := coupleAPIErrors(req.Delete(endpoint)) + params := requestParams{} + err := client.doRequest(ctx, http.MethodDelete, endpoint, params, nil) return err } diff --git a/request_helpers_test.go b/request_helpers_test.go index ce4bf80b5..033c86628 100644 --- a/request_helpers_test.go +++ b/request_helpers_test.go @@ -80,11 +80,8 @@ func TestRequestHelpers_post(t *testing.T) { func TestRequestHelpers_postNoOptions(t *testing.T) { client := testutil.CreateMockClient(t, NewClient) - httpmock.RegisterRegexpResponder( - "POST", - testutil.MockRequestURL("/foo/bar"), - testutil.MockRequestBodyValidateNoBody(t, testResponse), - ) + httpmock.RegisterRegexpResponder("POST", testutil.MockRequestURL("/foo/bar"), + testutil.MockRequestBodyValidateNoBody(t, testResponse)) result, err := doPOSTRequest[testResultType, any]( context.Background(), @@ -124,11 +121,8 @@ func TestRequestHelpers_put(t *testing.T) { func TestRequestHelpers_putNoOptions(t *testing.T) { client := testutil.CreateMockClient(t, NewClient) - httpmock.RegisterRegexpResponder( - "PUT", - testutil.MockRequestURL("/foo/bar"), - testutil.MockRequestBodyValidateNoBody(t, testResponse), - ) + httpmock.RegisterRegexpResponder("PUT", testutil.MockRequestURL("/foo/bar"), + testutil.MockRequestBodyValidateNoBody(t, testResponse)) result, err := doPUTRequest[testResultType, any]( context.Background(), @@ -147,11 +141,8 @@ func TestRequestHelpers_putNoOptions(t *testing.T) { func TestRequestHelpers_delete(t *testing.T) { client := testutil.CreateMockClient(t, NewClient) - httpmock.RegisterRegexpResponder( - "DELETE", - testutil.MockRequestURL("/foo/bar/foo%20bar"), - httpmock.NewStringResponder(200, "{}"), - ) + httpmock.RegisterRegexpResponder("DELETE", testutil.MockRequestURL("/foo/bar/foo%20bar"), + httpmock.NewStringResponder(200, "{}")) if err := doDELETERequest( context.Background(), @@ -169,14 +160,8 @@ func TestRequestHelpers_paginateAll(t *testing.T) { numRequests := 0 - httpmock.RegisterRegexpResponder( - "GET", - testutil.MockRequestURL("/foo/bar"), - mockPaginatedResponse( - buildPaginatedEntries(totalResults), - &numRequests, - ), - ) + httpmock.RegisterRegexpResponder("GET", testutil.MockRequestURL("/foo/bar"), + mockPaginatedResponse(buildPaginatedEntries(totalResults), &numRequests)) response, err := getPaginatedResults[testResultType]( context.Background(), @@ -205,14 +190,8 @@ func TestRequestHelpers_paginateSingle(t *testing.T) { numRequests := 0 - httpmock.RegisterRegexpResponder( - "GET", - testutil.MockRequestURL("/foo/bar"), - mockPaginatedResponse( - buildPaginatedEntries(12), - &numRequests, - ), - ) + httpmock.RegisterRegexpResponder("GET", testutil.MockRequestURL("/foo/bar"), + mockPaginatedResponse(buildPaginatedEntries(12), &numRequests)) response, err := getPaginatedResults[testResultType]( context.Background(), diff --git a/request_log_template.tmpl b/request_log_template.tmpl new file mode 100644 index 000000000..250547bd8 --- /dev/null +++ b/request_log_template.tmpl @@ -0,0 +1,8 @@ + +============================================================================================ +~~~ REQUEST ~~~ +{{.Request}} +HOST: {{.Host}} +HEADERS: {{.Headers}} +BODY: {{.Body}} +-------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/response_log_template.tmpl b/response_log_template.tmpl new file mode 100644 index 000000000..7bd5f38d8 --- /dev/null +++ b/response_log_template.tmpl @@ -0,0 +1,10 @@ + +============================================================================================ +~~~ RESPONSE ~~~ +STATUS: {{.Status}} +PROTO: {{.Proto}} +RECEIVED AT: {{.ReceivedAt}} +TIME DURATION: {{.TimeDuration}} +HEADERS: {{.Headers}} +BODY: {{.Body}} +-------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/retries.go b/retries.go index 047fed84e..24cbf2454 100644 --- a/retries.go +++ b/retries.go @@ -1,74 +1,91 @@ package linodego import ( + "bytes" + "encoding/json" "errors" + "io" "log" "net/http" "strconv" "time" - "github.com/go-resty/resty/v2" "golang.org/x/net/http2" ) const ( - retryAfterHeaderName = "Retry-After" - maintenanceModeHeaderName = "X-Maintenance-Mode" - - defaultRetryCount = 1000 + RetryAfterHeaderName = "Retry-After" + MaintenanceModeHeaderName = "X-Maintenance-Mode" + DefaultRetryCount = 1000 ) -// RetryConditional func(r *resty.Response) (shouldRetry bool) -type RetryConditional resty.RetryConditionFunc +// RetryConditional is a type alias for a function that determines if a request should be retried based on the response and error. +type RetryConditional func(*http.Response, error) bool -// RetryAfter func(c *resty.Client, r *resty.Response) (time.Duration, error) -type RetryAfter resty.RetryAfterFunc +// RetryAfter is a type alias for a function that determines the duration to wait before retrying based on the response. +type RetryAfter func(*http.Response) (time.Duration, error) -// Configures resty to -// lock until enough time has passed to retry the request as determined by the Retry-After response header. -// If the Retry-After header is not set, we fall back to value of SetPollDelay. -func configureRetries(c *Client) { - c.resty. - SetRetryCount(defaultRetryCount). - AddRetryCondition(checkRetryConditionals(c)). - SetRetryAfter(respectRetryAfter) +// ConfigureRetries configures http.Client to lock until enough time has passed to retry the request as determined by the Retry-After response header. +// If the Retry-After header is not set, we fall back to the value of SetPollDelay. +func ConfigureRetries(c *Client) { + c.SetRetryAfter(RespectRetryAfter) + c.SetRetryCount(DefaultRetryCount) } -func checkRetryConditionals(c *Client) func(*resty.Response, error) bool { - return func(r *resty.Response, err error) bool { - for _, retryConditional := range c.retryConditionals { - retry := retryConditional(r, err) - if retry { - log.Printf("[INFO] Received error %s - Retrying", r.Error()) - return true - } - } +func RespectRetryAfter(resp *http.Response) (time.Duration, error) { + if resp == nil { + return 0, nil + } - return false + retryAfterStr := resp.Header.Get(RetryAfterHeaderName) + if retryAfterStr == "" { + return 0, nil + } + + retryAfter, err := strconv.Atoi(retryAfterStr) + if err != nil { + return 0, err } + + duration := time.Duration(retryAfter) * time.Second + log.Printf("[INFO] Respecting Retry-After Header of %d (%s)", retryAfter, duration) + + return duration, nil } -// SetLinodeBusyRetry configures resty to retry specifically on "Linode busy." errors -// The retry wait time is configured in SetPollDelay -func linodeBusyRetryCondition(r *resty.Response, _ error) bool { - apiError, ok := r.Error().(*APIError) +// Retry conditions + +func LinodeBusyRetryCondition(resp *http.Response, _ error) bool { + if resp == nil { + return false + } + + apiError, ok := getAPIError(resp) linodeBusy := ok && apiError.Error() == "Linode busy." - retry := r.StatusCode() == http.StatusBadRequest && linodeBusy + retry := resp.StatusCode == http.StatusBadRequest && linodeBusy return retry } -func tooManyRequestsRetryCondition(r *resty.Response, _ error) bool { - return r.StatusCode() == http.StatusTooManyRequests +func TooManyRequestsRetryCondition(resp *http.Response, _ error) bool { + if resp == nil { + return false + } + + return resp.StatusCode == http.StatusTooManyRequests } -func serviceUnavailableRetryCondition(r *resty.Response, _ error) bool { - serviceUnavailable := r.StatusCode() == http.StatusServiceUnavailable +func ServiceUnavailableRetryCondition(resp *http.Response, _ error) bool { + if resp == nil { + return false + } + + serviceUnavailable := resp.StatusCode == http.StatusServiceUnavailable // During maintenance events, the API will return a 503 and add // an `X-MAINTENANCE-MODE` header. Don't retry during maintenance // events, only for legitimate 503s. - if serviceUnavailable && r.Header().Get(maintenanceModeHeaderName) != "" { + if serviceUnavailable && resp.Header.Get(MaintenanceModeHeaderName) != "" { log.Printf("[INFO] Linode API is under maintenance, request will not be retried - please see status.linode.com for more information") return false } @@ -76,33 +93,47 @@ func serviceUnavailableRetryCondition(r *resty.Response, _ error) bool { return serviceUnavailable } -func requestTimeoutRetryCondition(r *resty.Response, _ error) bool { - return r.StatusCode() == http.StatusRequestTimeout +func RequestTimeoutRetryCondition(resp *http.Response, _ error) bool { + if resp == nil { + return false + } + + return resp.StatusCode == http.StatusRequestTimeout } -func requestGOAWAYRetryCondition(_ *resty.Response, e error) bool { - return errors.As(e, &http2.GoAwayError{}) +func RequestGOAWAYRetryCondition(_ *http.Response, err error) bool { + return errors.As(err, &http2.GoAwayError{}) } -func requestNGINXRetryCondition(r *resty.Response, _ error) bool { - return r.StatusCode() == http.StatusBadRequest && - r.Header().Get("Server") == "nginx" && - r.Header().Get("Content-Type") == "text/html" +func RequestNGINXRetryCondition(resp *http.Response, _ error) bool { + if resp == nil { + return false + } + + return resp.StatusCode == http.StatusBadRequest && + resp.Header.Get("Server") == "nginx" && + resp.Header.Get("Content-Type") == "text/html" } -func respectRetryAfter(client *resty.Client, resp *resty.Response) (time.Duration, error) { - retryAfterStr := resp.Header().Get(retryAfterHeaderName) - if retryAfterStr == "" { - return 0, nil +// Helper function to extract APIError from response +func getAPIError(resp *http.Response) (*APIError, bool) { + if resp.Body == nil { + return nil, false } - retryAfter, err := strconv.Atoi(retryAfterStr) + body, err := io.ReadAll(resp.Body) if err != nil { - return 0, err + return nil, false } - duration := time.Duration(retryAfter) * time.Second - log.Printf("[INFO] Respecting Retry-After Header of %d (%s) (max %s)", retryAfter, duration, client.RetryMaxWaitTime) + resp.Body = io.NopCloser(bytes.NewReader(body)) - return duration, nil + var apiError APIError + + err = json.Unmarshal(body, &apiError) + if err != nil { + return nil, false + } + + return &apiError, true } diff --git a/retries_http.go b/retries_http.go deleted file mode 100644 index 46b986e8d..000000000 --- a/retries_http.go +++ /dev/null @@ -1,132 +0,0 @@ -package linodego - -import ( - "encoding/json" - "errors" - "log" - "net/http" - "strconv" - "time" - - "golang.org/x/net/http2" -) - -const ( - // nolint:unused - httpRetryAfterHeaderName = "Retry-After" - // nolint:unused - httpMaintenanceModeHeaderName = "X-Maintenance-Mode" - - // nolint:unused - httpDefaultRetryCount = 1000 -) - -// RetryConditional is a type alias for a function that determines if a request should be retried based on the response and error. -// nolint:unused -type httpRetryConditional func(*http.Response, error) bool - -// RetryAfter is a type alias for a function that determines the duration to wait before retrying based on the response. -// nolint:unused -type httpRetryAfter func(*http.Response) (time.Duration, error) - -// Configures http.Client to lock until enough time has passed to retry the request as determined by the Retry-After response header. -// If the Retry-After header is not set, we fall back to the value of SetPollDelay. -// nolint:unused -func httpConfigureRetries(c *httpClient) { - c.retryConditionals = append(c.retryConditionals, httpcheckRetryConditionals(c)) - c.retryAfter = httpRespectRetryAfter -} - -// nolint:unused -func httpcheckRetryConditionals(c *httpClient) httpRetryConditional { - return func(resp *http.Response, err error) bool { - for _, retryConditional := range c.retryConditionals { - retry := retryConditional(resp, err) - if retry { - log.Printf("[INFO] Received error %v - Retrying", err) - return true - } - } - - return false - } -} - -// nolint:unused -func httpRespectRetryAfter(resp *http.Response) (time.Duration, error) { - retryAfterStr := resp.Header.Get(retryAfterHeaderName) - if retryAfterStr == "" { - return 0, nil - } - - retryAfter, err := strconv.Atoi(retryAfterStr) - if err != nil { - return 0, err - } - - duration := time.Duration(retryAfter) * time.Second - log.Printf("[INFO] Respecting Retry-After Header of %d (%s)", retryAfter, duration) - - return duration, nil -} - -// Retry conditions - -// nolint:unused -func httpLinodeBusyRetryCondition(resp *http.Response, _ error) bool { - apiError, ok := getAPIError(resp) - linodeBusy := ok && apiError.Error() == "Linode busy." - retry := resp.StatusCode == http.StatusBadRequest && linodeBusy - - return retry -} - -// nolint:unused -func httpTooManyRequestsRetryCondition(resp *http.Response, _ error) bool { - return resp.StatusCode == http.StatusTooManyRequests -} - -// nolint:unused -func httpServiceUnavailableRetryCondition(resp *http.Response, _ error) bool { - serviceUnavailable := resp.StatusCode == http.StatusServiceUnavailable - - // During maintenance events, the API will return a 503 and add - // an `X-MAINTENANCE-MODE` header. Don't retry during maintenance - // events, only for legitimate 503s. - if serviceUnavailable && resp.Header.Get(maintenanceModeHeaderName) != "" { - log.Printf("[INFO] Linode API is under maintenance, request will not be retried - please see status.linode.com for more information") - return false - } - - return serviceUnavailable -} - -// nolint:unused -func httpRequestTimeoutRetryCondition(resp *http.Response, _ error) bool { - return resp.StatusCode == http.StatusRequestTimeout -} - -// nolint:unused -func httpRequestGOAWAYRetryCondition(_ *http.Response, err error) bool { - return errors.As(err, &http2.GoAwayError{}) -} - -// nolint:unused -func httpRequestNGINXRetryCondition(resp *http.Response, _ error) bool { - return resp.StatusCode == http.StatusBadRequest && - resp.Header.Get("Server") == "nginx" && - resp.Header.Get("Content-Type") == "text/html" -} - -// Helper function to extract APIError from response -// nolint:unused -func getAPIError(resp *http.Response) (*APIError, bool) { - var apiError APIError - - err := json.NewDecoder(resp.Body).Decode(&apiError) - if err != nil { - return nil, false - } - - return &apiError, true -} diff --git a/retries_http_test.go b/retries_http_test.go deleted file mode 100644 index 35eea5fc9..000000000 --- a/retries_http_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package linodego - -import ( - "bytes" - "encoding/json" - "io" - "net/http" - "testing" - "time" -) - -func TestHTTPLinodeBusyRetryCondition(t *testing.T) { - var retry bool - - // Initialize response body - rawResponse := &http.Response{ - StatusCode: http.StatusBadRequest, - Body: io.NopCloser(bytes.NewBuffer(nil)), - } - - retry = httpLinodeBusyRetryCondition(rawResponse, nil) - - if retry { - t.Errorf("Should not have retried") - } - - apiError := APIError{ - Errors: []APIErrorReason{ - {Reason: "Linode busy."}, - }, - } - rawResponse.Body = createResponseBody(apiError) - - retry = httpLinodeBusyRetryCondition(rawResponse, nil) - - if !retry { - t.Errorf("Should have retried") - } -} - -func TestHTTPServiceUnavailableRetryCondition(t *testing.T) { - rawResponse := &http.Response{ - StatusCode: http.StatusServiceUnavailable, - Header: http.Header{httpRetryAfterHeaderName: []string{"20"}}, - Body: io.NopCloser(bytes.NewBuffer(nil)), // Initialize response body - } - - if retry := httpServiceUnavailableRetryCondition(rawResponse, nil); !retry { - t.Error("expected request to be retried") - } - - if retryAfter, err := httpRespectRetryAfter(rawResponse); err != nil { - t.Errorf("expected error to be nil but got %s", err) - } else if retryAfter != time.Second*20 { - t.Errorf("expected retryAfter to be 20 but got %d", retryAfter) - } -} - -func TestHTTPServiceMaintenanceModeRetryCondition(t *testing.T) { - rawResponse := &http.Response{ - StatusCode: http.StatusServiceUnavailable, - Header: http.Header{ - httpRetryAfterHeaderName: []string{"20"}, - httpMaintenanceModeHeaderName: []string{"Currently in maintenance mode."}, - }, - Body: io.NopCloser(bytes.NewBuffer(nil)), // Initialize response body - } - - if retry := httpServiceUnavailableRetryCondition(rawResponse, nil); retry { - t.Error("expected retry to be skipped due to maintenance mode header") - } -} - -// Helper function to create a response body from an object -func createResponseBody(obj interface{}) io.ReadCloser { - body, err := json.Marshal(obj) - if err != nil { - panic(err) - } - return io.NopCloser(bytes.NewBuffer(body)) -} diff --git a/retries_test.go b/retries_test.go index 4f0029388..45b5fc4d3 100644 --- a/retries_test.go +++ b/retries_test.go @@ -1,24 +1,24 @@ package linodego import ( + "bytes" + "encoding/json" + "io" "net/http" "testing" "time" - - "github.com/go-resty/resty/v2" ) func TestLinodeBusyRetryCondition(t *testing.T) { var retry bool - request := resty.Request{} - rawResponse := http.Response{StatusCode: http.StatusBadRequest} - response := resty.Response{ - Request: &request, - RawResponse: &rawResponse, + // Initialize response body + rawResponse := &http.Response{ + StatusCode: http.StatusBadRequest, + Body: io.NopCloser(bytes.NewBuffer(nil)), } - retry = linodeBusyRetryCondition(&response, nil) + retry = LinodeBusyRetryCondition(rawResponse, nil) if retry { t.Errorf("Should not have retried") @@ -29,48 +29,53 @@ func TestLinodeBusyRetryCondition(t *testing.T) { {Reason: "Linode busy."}, }, } - request.SetError(&apiError) + rawResponse.Body = createResponseBody(apiError) - retry = linodeBusyRetryCondition(&response, nil) + retry = LinodeBusyRetryCondition(rawResponse, nil) if !retry { t.Errorf("Should have retried") } } -func TestLinodeServiceUnavailableRetryCondition(t *testing.T) { - request := resty.Request{} - rawResponse := http.Response{StatusCode: http.StatusServiceUnavailable, Header: http.Header{ - retryAfterHeaderName: []string{"20"}, - }} - response := resty.Response{ - Request: &request, - RawResponse: &rawResponse, +func TestServiceUnavailableRetryCondition(t *testing.T) { + rawResponse := &http.Response{ + StatusCode: http.StatusServiceUnavailable, + Header: http.Header{RetryAfterHeaderName: []string{"20"}}, + Body: io.NopCloser(bytes.NewBuffer(nil)), // Initialize response body } - if retry := serviceUnavailableRetryCondition(&response, nil); !retry { + if retry := ServiceUnavailableRetryCondition(rawResponse, nil); !retry { t.Error("expected request to be retried") } - if retryAfter, err := respectRetryAfter(NewClient(nil).resty, &response); err != nil { + if retryAfter, err := RespectRetryAfter(rawResponse); err != nil { t.Errorf("expected error to be nil but got %s", err) } else if retryAfter != time.Second*20 { t.Errorf("expected retryAfter to be 20 but got %d", retryAfter) } } -func TestLinodeServiceMaintenanceModeRetryCondition(t *testing.T) { - request := resty.Request{} - rawResponse := http.Response{StatusCode: http.StatusServiceUnavailable, Header: http.Header{ - retryAfterHeaderName: []string{"20"}, - maintenanceModeHeaderName: []string{"Currently in maintenance mode."}, - }} - response := resty.Response{ - Request: &request, - RawResponse: &rawResponse, +func TestServiceMaintenanceModeRetryCondition(t *testing.T) { + rawResponse := &http.Response{ + StatusCode: http.StatusServiceUnavailable, + Header: http.Header{ + RetryAfterHeaderName: []string{"20"}, + MaintenanceModeHeaderName: []string{"Currently in maintenance mode."}, + }, + Body: io.NopCloser(bytes.NewBuffer(nil)), // Initialize response body } - if retry := serviceUnavailableRetryCondition(&response, nil); retry { + if retry := ServiceUnavailableRetryCondition(rawResponse, nil); retry { t.Error("expected retry to be skipped due to maintenance mode header") } } + +// Helper function to create a response body from an object +func createResponseBody(obj interface{}) io.ReadCloser { + body, err := json.Marshal(obj) + if err != nil { + panic(err) + } + return io.NopCloser(bytes.NewBuffer(body)) +} diff --git a/test/go.mod b/test/go.mod index c1f5dd3a2..a5a9b6ec2 100644 --- a/test/go.mod +++ b/test/go.mod @@ -20,7 +20,6 @@ require ( github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-resty/resty/v2 v2.17.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect diff --git a/test/go.sum b/test/go.sum index 9689a3a72..c74c0080a 100644 --- a/test/go.sum +++ b/test/go.sum @@ -14,8 +14,6 @@ github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2Kv github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= -github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/test/integration/cache_test.go b/test/integration/cache_test.go index fd4207de2..9468e870c 100644 --- a/test/integration/cache_test.go +++ b/test/integration/cache_test.go @@ -28,8 +28,8 @@ func TestCache_RegionList(t *testing.T) { totalRequests := int64(0) client.OnBeforeRequest(func(request *linodego.Request) error { - page := request.QueryParam.Get("page") - if !strings.Contains(request.URL, "regions") || page != "1" { + page := request.URL.Query().Get("page") + if !strings.Contains(request.URL.String(), "regions") || page != "1" { return nil } @@ -91,8 +91,8 @@ func TestCache_Expiration(t *testing.T) { totalRequests := int64(0) client.OnBeforeRequest(func(request *linodego.Request) error { - page := request.QueryParam.Get("page") - if !strings.Contains(request.URL, "kernels") || page != "1" { + page := request.URL.Query().Get("page") + if !strings.Contains(request.URL.String(), "kernels") || page != "1" { return nil } diff --git a/test/integration/fixtures/TestMaintenancePolicies_List.yaml b/test/integration/fixtures/TestMaintenancePolicies_List.yaml index 54b36a96c..e700c5a77 100644 --- a/test/integration/fixtures/TestMaintenancePolicies_List.yaml +++ b/test/integration/fixtures/TestMaintenancePolicies_List.yaml @@ -11,17 +11,17 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/maintenance/policies + url: https://api.linode.com/v4beta/maintenance/policies?page=1 method: GET response: body: '{"data": [{"slug": "linode/migrate", "label": "Migrate", "description": "Migrates the Linode to a new host while it remains fully operational. Recommended for maximizing availability.", "type": "migrate", "notification_period_sec": - 300, "is_default": true}, {"slug": "linode/power_off_on", "label": "Power-off/on", - "description": "Powers off the Linode at the start of the maintenance event - and reboots it once the maintenance finishes. Recommended for maximizing performance.", - "type": "power_off_on", "notification_period_sec": 1800, "is_default": false}], - "page": 1, "pages": 1, "results": 2}' + 10800, "is_default": true}, {"slug": "linode/power_off_on", "label": "Power + Off / Power On", "description": "Powers off the Linode at the start of the maintenance + event and reboots it once the maintenance finishes. Recommended for maximizing + performance.", "type": "power_off_on", "notification_period_sec": 604800, "is_default": + false}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -33,22 +33,24 @@ interactions: - '*' Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "595" + - "607" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.18.0 + Expires: + - Tue, 21 Apr 2026 18:20:32 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter @@ -62,7 +64,7 @@ interactions: X-Oauth-Scopes: - unknown X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/maintenance_test.go b/test/integration/maintenance_test.go index 8ce207aad..b8d22650c 100644 --- a/test/integration/maintenance_test.go +++ b/test/integration/maintenance_test.go @@ -2,10 +2,8 @@ package integration import ( "context" - "encoding/json" "testing" - "github.com/linode/linodego" "github.com/stretchr/testify/require" ) @@ -13,21 +11,7 @@ func TestMaintenancePolicies_List(t *testing.T) { client, fixtureTeardown := createTestClient(t, "fixtures/TestMaintenancePolicies_List") defer fixtureTeardown() - resp, err := client.R(context.Background()).Get("maintenance/policies") - require.NoError(t, err) - - var result map[string]any - err = json.Unmarshal(resp.Body(), &result) - require.NoError(t, err) - - dataRaw, ok := result["data"] - require.True(t, ok, "Expected 'data' key in response") - - dataJSON, err := json.Marshal(dataRaw) - require.NoError(t, err) - - var policies []linodego.MaintenancePolicy - err = json.Unmarshal(dataJSON, &policies) + policies, err := client.ListMaintenancePolicies(context.Background(), nil) require.NoError(t, err) if len(policies) == 0 { diff --git a/test/unit/images_test.go b/test/unit/images_test.go index dc9aa9ba7..e89cec8ef 100644 --- a/test/unit/images_test.go +++ b/test/unit/images_test.go @@ -271,6 +271,14 @@ func TestImage_Upload(t *testing.T) { base.MockPost("images/upload", fixtureData) + // Mock the PUT request to the upload URL returned in the fixture. + // UploadImageToURL uses http.DefaultTransport, so we need to + // activate httpmock on the default transport as well. + httpmock.Activate() + defer httpmock.DeactivateAndReset() + httpmock.RegisterResponder("PUT", "https://example.com/upload-endpoint", + httpmock.NewStringResponder(200, "{}")) + image, err := base.Client.UploadImage(context.Background(), requestData) assert.NoError(t, err) From df9cb24487377c25ab25822addb82940461954dd Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 5 May 2026 14:24:43 -0400 Subject: [PATCH 02/17] TPT-4421: Remove deprecated fields and methods (#946) * Removed deprecated fields and methods and updated tests * Fix lint * Addressed copilot suggestion * Fixed lint * Removed V2 suffix from various fields and methods * Addressed CoPilot suggestions * Added separate struct for Instance IP Address update options * Address PR suggestions --- account_events.go | 18 - account_maintenance.go | 4 - domains.go | 10 - instance_ips.go | 6 +- instances.go | 36 -- kernels.go | 18 +- lke_cluster_pools.go | 53 -- monitor_alert_definitions.go | 15 +- network_ips.go | 39 +- object_storage_bucket_certs.go | 37 +- object_storage_buckets.go | 62 +- object_storage_clusters.go | 26 - object_storage_keys.go | 6 +- object_storage_object.go | 34 +- paged_response_structs.go | 174 ----- pagination.go | 6 - regions.go | 4 - .../fixtures/TestObjectStorageBucketCert.yaml | 262 ++------ .../TestObjectStorageBucket_Access_Get.yaml | 138 ++-- ...TestObjectStorageBucket_Access_Update.yaml | 75 ++- .../TestObjectStorageBucket_Create.yaml | 10 +- .../TestObjectStorageBucket_GetFound.yaml | 16 +- .../TestObjectStorageBucket_GetMissing.yaml | 21 +- .../TestObjectStorageBucket_Regional.yaml | 539 --------------- ...estObjectStorageBucketsInCluster_List.yaml | 193 ------ .../TestObjectStorageBuckets_List.yaml | 61 +- .../TestObjectStorageClusters_List.yaml | 114 ---- .../TestObjectStorageKey_GetFound.yaml | 32 +- .../TestObjectStorageKey_GetMissing.yaml | 10 +- .../fixtures/TestObjectStorageKey_List.yaml | 30 +- .../fixtures/TestObjectStorageKey_Update.yaml | 32 +- .../TestObjectStorageKeys_Limited.yaml | 14 +- .../TestObjectStorageKeys_Limited_Bucket.yaml | 10 +- ...estObjectStorageKeys_Regional_Limited.yaml | 611 ++++++++++-------- ...StorageObject_ACLConfig_Bucket_Delete.yaml | 4 +- ...ectStorageObject_ACLConfig_Bucket_Put.yaml | 4 +- .../TestObjectStorageObject_Smoke.yaml | 254 +------- .../TestObjectStorageQuotaUsage_Get.yaml | 4 +- .../fixtures/TestObjectStorageQuotas_Get.yaml | 14 +- .../TestObjectStorageQuotas_List.yaml | 547 ++++++++++------ test/integration/instances_test.go | 5 - .../monitor_alert_definitions_test.go | 1 - test/integration/network_ips_test.go | 42 +- .../object_storage_bucket_certs_test.go | 24 +- .../object_storage_buckets_test.go | 97 +-- .../object_storage_clusters_test.go | 19 - test/integration/object_storage_keys_test.go | 4 +- .../integration/object_storage_object_test.go | 55 +- test/integration/object_storage_quota_test.go | 52 +- .../fixtures/lke_cluster_pool_create.json | 6 - test/unit/fixtures/lke_cluster_pool_get.json | 7 - test/unit/fixtures/lke_cluster_pool_list.json | 19 - .../fixtures/lke_cluster_pool_update.json | 6 - .../fixtures/object_storage_cluster_get.json | 7 - .../fixtures/object_storage_cluster_list.json | 15 - test/unit/instance_ip_test.go | 4 +- test/unit/instance_test.go | 22 - test/unit/lke_cluster_pool_test.go | 105 --- test/unit/monitor_alert_definitions_test.go | 15 - test/unit/network_ips_test.go | 4 +- test/unit/object_storage_bucket_cert_test.go | 63 +- test/unit/object_storage_bucket_test.go | 36 +- test/unit/object_storage_cluster_test.go | 50 -- test/unit/object_storage_object_test.go | 8 +- 64 files changed, 1161 insertions(+), 3048 deletions(-) delete mode 100644 lke_cluster_pools.go delete mode 100644 object_storage_clusters.go delete mode 100644 paged_response_structs.go delete mode 100644 test/integration/fixtures/TestObjectStorageBucket_Regional.yaml delete mode 100644 test/integration/fixtures/TestObjectStorageBucketsInCluster_List.yaml delete mode 100644 test/integration/fixtures/TestObjectStorageClusters_List.yaml delete mode 100644 test/integration/object_storage_clusters_test.go delete mode 100644 test/unit/fixtures/lke_cluster_pool_create.json delete mode 100644 test/unit/fixtures/lke_cluster_pool_get.json delete mode 100644 test/unit/fixtures/lke_cluster_pool_list.json delete mode 100644 test/unit/fixtures/lke_cluster_pool_update.json delete mode 100644 test/unit/fixtures/object_storage_cluster_get.json delete mode 100644 test/unit/fixtures/object_storage_cluster_list.json delete mode 100644 test/unit/lke_cluster_pool_test.go delete mode 100644 test/unit/object_storage_cluster_test.go diff --git a/account_events.go b/account_events.go index 190ea221e..bf2bdd17e 100644 --- a/account_events.go +++ b/account_events.go @@ -231,14 +231,6 @@ const ( ActionVPCSubnetCreate EventAction = "subnet_create" ActionVPCSubnetDelete EventAction = "subnet_delete" ActionVPCSubnetUpdate EventAction = "subnet_update" - - // Deprecated: incorrect spelling, - // to be removed in the next major version release. - ActionVolumeDelte EventAction = "volume_delete" - - // Deprecated: incorrect spelling, - // to be removed in the next major version - ActionCreateCardUpdated = ActionCreditCardUpdated ) // EntityType constants start with Entity and include Linode API Event Entity Types @@ -343,16 +335,6 @@ func (c *Client) GetEvent(ctx context.Context, eventID int) (*Event, error) { return doGETRequest[Event](ctx, c, e) } -// MarkEventRead marks a single Event as read. -// -// Deprecated: `MarkEventRead` is a deprecated API, please consider using `MarkEventsSeen` instead. -// Please note that the `MarkEventsSeen` API functions differently and will mark all events up to and -// including the referenced event-id as "seen" rather than individual events. -func (c *Client) MarkEventRead(ctx context.Context, event *Event) error { - e := formatAPIPath("account/events/%d/read", event.ID) - return doPOSTRequestNoRequestResponseBody(ctx, c, e) -} - // MarkEventsSeen marks all Events up to and including this Event by ID as seen. func (c *Client) MarkEventsSeen(ctx context.Context, event *Event) error { e := formatAPIPath("account/events/%d/seen", event.ID) diff --git a/account_maintenance.go b/account_maintenance.go index ec7e2e479..b5917c9a9 100644 --- a/account_maintenance.go +++ b/account_maintenance.go @@ -22,9 +22,6 @@ type AccountMaintenance struct { NotBefore *time.Time `json:"-"` StartTime *time.Time `json:"-"` CompleteTime *time.Time `json:"-"` - - // Deprecated: When is a deprecated property - When *time.Time `json:"when"` } // Entity represents the entity being affected by maintenance @@ -57,7 +54,6 @@ func (accountMaintenance *AccountMaintenance) UnmarshalJSON(b []byte) error { accountMaintenance.NotBefore = (*time.Time)(p.NotBefore) accountMaintenance.StartTime = (*time.Time)(p.StartTime) accountMaintenance.CompleteTime = (*time.Time)(p.CompleteTime) - accountMaintenance.When = (*time.Time)(p.When) return nil } diff --git a/domains.go b/domains.go index 4f2f2179b..d8993c35d 100644 --- a/domains.go +++ b/domains.go @@ -15,9 +15,6 @@ type Domain struct { // If this Domain represents the authoritative source of information for the domain it describes, or if it is a read-only copy of a master (also called a slave). Type DomainType `json:"type"` // Enum:"master" "slave" - // Deprecated: The group this Domain belongs to. This is for display purposes only. - Group string `json:"group"` - // Used to control whether this Domain is currently being rendered. Status DomainStatus `json:"status"` // Enum:"disabled" "active" "edit_mode" "has_errors" @@ -64,9 +61,6 @@ type DomainCreateOptions struct { // Enum:"master" "slave" Type DomainType `json:"type"` - // Deprecated: The group this Domain belongs to. This is for display purposes only. - Group string `json:"group,omitempty"` - // Used to control whether this Domain is currently being rendered. // Enum:"disabled" "active" "edit_mode" "has_errors" Status DomainStatus `json:"status,omitempty"` @@ -109,9 +103,6 @@ type DomainUpdateOptions struct { // Enum:"master" "slave" Type DomainType `json:"type,omitempty"` - // Deprecated: The group this Domain belongs to. This is for display purposes only. - Group string `json:"group,omitempty"` - // Used to control whether this Domain is currently being rendered. // Enum:"disabled" "active" "edit_mode" "has_errors" Status DomainStatus `json:"status,omitempty"` @@ -178,7 +169,6 @@ type DomainImportOptions struct { func (d Domain) GetUpdateOptions() (du DomainUpdateOptions) { du.Domain = d.Domain du.Type = d.Type - du.Group = d.Group du.Status = d.Status du.Description = d.Description du.SOAEmail = d.SOAEmail diff --git a/instance_ips.go b/instance_ips.go index 943dbdd39..eac567782 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -35,6 +35,10 @@ type InstanceIP struct { Reserved bool `json:"reserved"` } +type InstanceIPAddressUpdateOptions struct { + RDNS **string `json:"rdns,omitempty"` +} + // VPCIP represents a private IP address in a VPC subnet with additional networking details type VPCIP struct { Address *string `json:"address"` @@ -139,7 +143,7 @@ func (c *Client) AddInstanceIPAddress(ctx context.Context, linodeID int, public } // UpdateInstanceIPAddress updates the IPAddress with the specified instance id and IP address -func (c *Client) UpdateInstanceIPAddress(ctx context.Context, linodeID int, ipAddress string, opts IPAddressUpdateOptions) (*InstanceIP, error) { +func (c *Client) UpdateInstanceIPAddress(ctx context.Context, linodeID int, ipAddress string, opts InstanceIPAddressUpdateOptions) (*InstanceIP, error) { e := formatAPIPath("linode/instances/%d/ips/%s", linodeID, ipAddress) return doPUTRequest[InstanceIP](ctx, c, e, opts) } diff --git a/instances.go b/instances.go index 5fb512e61..a391dfdff 100644 --- a/instances.go +++ b/instances.go @@ -128,22 +128,8 @@ type InstanceTransfer struct { Quota int `json:"quota"` } -// Deprecated: use MonthlyInstanceTransferStatsV2 for new implementations -// // MonthlyInstanceTransferStats pool stats for a Linode Instance network transfer statistics for a specific month type MonthlyInstanceTransferStats struct { - // The amount of inbound public network traffic received by this Linode, in bytes, for a specific year/month. - BytesIn int `json:"bytes_in"` - - // The amount of outbound public network traffic sent by this Linode, in bytes, for a specific year/month. - BytesOut int `json:"bytes_out"` - - // The total amount of public network traffic sent and received by this Linode, in bytes, for a specific year/month. - BytesTotal int `json:"bytes_total"` -} - -// MonthlyInstanceTransferStatsV2 pool stats for a Linode Instance network transfer statistics for a specific month -type MonthlyInstanceTransferStatsV2 struct { // The amount of inbound public network traffic received by this Linode, in bytes, for a specific year/month. BytesIn uint64 `json:"bytes_in"` @@ -210,9 +196,6 @@ type InstanceCreateOptions struct { SwapSize *int `json:"swap_size,omitempty"` Booted *bool `json:"booted,omitempty"` - // Deprecated: group is a deprecated property denoting a group label for the Linode. - Group string `json:"group,omitempty"` - IPv4 []string `json:"ipv4,omitempty"` MaintenancePolicy *string `json:"maintenance_policy,omitempty"` @@ -233,9 +216,6 @@ type InstanceUpdateOptions struct { WatchdogEnabled *bool `json:"watchdog_enabled,omitempty"` Tags *[]string `json:"tags,omitempty"` - // Deprecated: group is a deprecated property denoting a group label for the Linode. - Group *string `json:"group,omitempty"` - MaintenancePolicy *string `json:"maintenance_policy,omitempty"` } @@ -364,7 +344,6 @@ func (backup *InstanceBackup) UnmarshalJSON(b []byte) error { func (i *Instance) GetUpdateOptions() InstanceUpdateOptions { return InstanceUpdateOptions{ Label: i.Label, - Group: &i.Group, Backups: i.Backups, Alerts: i.Alerts, WatchdogEnabled: &i.WatchdogEnabled, @@ -387,9 +366,6 @@ type InstanceCloneOptions struct { PrivateIP bool `json:"private_ip,omitempty"` Metadata *InstanceMetadataOptions `json:"metadata,omitempty"` PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitempty"` - - // Deprecated: group is a deprecated property denoting a group label for the Linode. - Group string `json:"group,omitempty"` } // InstanceResizeOptions is an options struct used when resizing an instance @@ -433,12 +409,6 @@ func (c *Client) GetInstanceTransferMonthly(ctx context.Context, linodeID, year, return doGETRequest[MonthlyInstanceTransferStats](ctx, c, e) } -// GetInstanceTransferMonthlyV2 gets the instance's network transfer pool statistics for a specific month. -func (c *Client) GetInstanceTransferMonthlyV2(ctx context.Context, linodeID, year, month int) (*MonthlyInstanceTransferStatsV2, error) { - e := formatAPIPath("linode/instances/%d/transfer/%d/%d", linodeID, year, month) - return doGETRequest[MonthlyInstanceTransferStatsV2](ctx, c, e) -} - // CreateInstance creates a Linode instance func (c *Client) CreateInstance(ctx context.Context, opts InstanceCreateOptions) (*Instance, error) { return doPOSTRequest[Instance](ctx, c, "linode/instances", opts) @@ -547,12 +517,6 @@ func (c *Client) ShutdownInstance(ctx context.Context, id int) error { return c.simpleInstanceAction(ctx, "shutdown", id) } -// Deprecated: Please use UpgradeInstance instead. -// MutateInstance Upgrades a Linode to its next generation. -func (c *Client) MutateInstance(ctx context.Context, id int) error { - return c.simpleInstanceAction(ctx, "mutate", id) -} - // InstanceUpgradeOptions is a struct representing the options for upgrading a Linode type InstanceUpgradeOptions struct { // Automatically resize disks when resizing a Linode. diff --git a/kernels.go b/kernels.go index 11d647dba..079458b73 100644 --- a/kernels.go +++ b/kernels.go @@ -10,16 +10,14 @@ import ( // LinodeKernel represents a Linode Instance kernel object type LinodeKernel struct { - ID string `json:"id"` - Label string `json:"label"` - Version string `json:"version"` - Architecture string `json:"architecture"` - Deprecated bool `json:"deprecated"` - KVM bool `json:"kvm"` - // Deprecated: this field is no longer populated by the API, but it is included here for backward compatibility with existing implementations. - XEN bool `json:"xen"` - PVOPS bool `json:"pvops"` - Built *time.Time `json:"-"` + ID string `json:"id"` + Label string `json:"label"` + Version string `json:"version"` + Architecture string `json:"architecture"` + Deprecated bool `json:"deprecated"` + KVM bool `json:"kvm"` + PVOPS bool `json:"pvops"` + Built *time.Time `json:"-"` } // UnmarshalJSON implements the json.Unmarshaler interface diff --git a/lke_cluster_pools.go b/lke_cluster_pools.go deleted file mode 100644 index 5f5207655..000000000 --- a/lke_cluster_pools.go +++ /dev/null @@ -1,53 +0,0 @@ -package linodego - -import ( - "context" -) - -// Deprecated: LKEClusterPoolDisk represents a Node disk in an LKEClusterPool object -type LKEClusterPoolDisk = LKENodePoolDisk - -// Deprecated: LKEClusterPoolAutoscaler represents an AutoScaler configuration -type LKEClusterPoolAutoscaler = LKENodePoolAutoscaler - -// Deprecated: LKEClusterPoolLinode represents a LKEClusterPoolLinode object -type LKEClusterPoolLinode = LKENodePoolLinode - -// Deprecated: LKEClusterPool represents a LKEClusterPool object -type LKEClusterPool = LKENodePool - -// Deprecated: LKEClusterPoolCreateOptions fields are those accepted by CreateLKEClusterPool -type LKEClusterPoolCreateOptions = LKENodePoolCreateOptions - -// Deprecated: LKEClusterPoolUpdateOptions fields are those accepted by UpdateLKEClusterPool -type LKEClusterPoolUpdateOptions = LKENodePoolUpdateOptions - -// Deprecated: ListLKEClusterPools lists LKEClusterPools -func (c *Client) ListLKEClusterPools(ctx context.Context, clusterID int, opts *ListOptions) ([]LKEClusterPool, error) { - return c.ListLKENodePools(ctx, clusterID, opts) -} - -// Deprecated: GetLKEClusterPool gets the lkeClusterPool with the provided ID -func (c *Client) GetLKEClusterPool(ctx context.Context, clusterID, id int) (*LKEClusterPool, error) { - return c.GetLKENodePool(ctx, clusterID, id) -} - -// Deprecated: CreateLKEClusterPool creates a LKEClusterPool -func (c *Client) CreateLKEClusterPool(ctx context.Context, clusterID int, createOpts LKEClusterPoolCreateOptions) (*LKEClusterPool, error) { - return c.CreateLKENodePool(ctx, clusterID, createOpts) -} - -// Deprecated: UpdateLKEClusterPool updates the LKEClusterPool with the specified id -func (c *Client) UpdateLKEClusterPool(ctx context.Context, clusterID, id int, updateOpts LKEClusterPoolUpdateOptions) (*LKEClusterPool, error) { - return c.UpdateLKENodePool(ctx, clusterID, id, updateOpts) -} - -// Deprecated: DeleteLKEClusterPool deletes the LKEClusterPool with the specified id -func (c *Client) DeleteLKEClusterPool(ctx context.Context, clusterID, id int) error { - return c.DeleteLKENodePool(ctx, clusterID, id) -} - -// Deprecated: DeleteLKEClusterPoolNode deletes a given node from a cluster pool -func (c *Client) DeleteLKEClusterPoolNode(ctx context.Context, clusterID int, id string) error { - return c.DeleteLKENodePoolNode(ctx, clusterID, id) -} diff --git a/monitor_alert_definitions.go b/monitor_alert_definitions.go index 7988ab673..c11d50c2d 100644 --- a/monitor_alert_definitions.go +++ b/monitor_alert_definitions.go @@ -55,7 +55,6 @@ type AlertDefinition struct { Type string `json:"type"` ServiceType string `json:"service_type"` Status AlertDefinitionStatus `json:"status"` - HasMoreResources bool `json:"has_more_resources"` // Deprecated: use Entities.HasMoreResources. RuleCriteria RuleCriteria `json:"rule_criteria"` TriggerConditions TriggerConditions `json:"trigger_conditions"` AlertChannels []AlertChannelEnvelope `json:"alert_channels"` @@ -63,7 +62,6 @@ type AlertDefinition struct { Updated *time.Time `json:"-"` UpdatedBy string `json:"updated_by"` CreatedBy string `json:"created_by"` - EntityIDs []string `json:"entity_ids"` // Deprecated: use Entities.url to list associated entities. Description string `json:"description"` Class string `json:"class"` Scope AlertDefinitionScope `json:"scope"` @@ -71,13 +69,6 @@ type AlertDefinition struct { Entities AlertDefinitionEntities `json:"entities"` } -// Backwards-compatible alias - -// MonitorAlertDefinition represents an ACLP Alert Definition object -// -// Deprecated: AlertDefinition should be used in all new implementations. -type MonitorAlertDefinition = AlertDefinition - // TriggerConditions represents the trigger conditions for an alert. type TriggerConditions struct { CriteriaCondition string `json:"criteria_condition,omitempty"` @@ -238,7 +229,7 @@ func (c *Client) GetMonitorAlertDefinition( ctx context.Context, serviceType string, alertID int, -) (*MonitorAlertDefinition, error) { +) (*AlertDefinition, error) { e := formatAPIPath("monitor/services/%s/alert-definitions/%d", serviceType, alertID) return doGETRequest[AlertDefinition](ctx, c, e) } @@ -248,7 +239,7 @@ func (c *Client) CreateMonitorAlertDefinition( ctx context.Context, serviceType string, opts AlertDefinitionCreateOptions, -) (*MonitorAlertDefinition, error) { +) (*AlertDefinition, error) { e := formatAPIPath("monitor/services/%s/alert-definitions", serviceType) return doPOSTRequest[AlertDefinition](ctx, c, e, opts) } @@ -260,7 +251,7 @@ func (c *Client) CreateMonitorAlertDefinitionWithIdempotency( serviceType string, opts AlertDefinitionCreateOptions, idempotencyKey string, -) (*MonitorAlertDefinition, error) { +) (*AlertDefinition, error) { e := formatAPIPath("monitor/services/%s/alert-definitions", serviceType) var result AlertDefinition diff --git a/network_ips.go b/network_ips.go index d4500c4d6..27d093f4f 100644 --- a/network_ips.go +++ b/network_ips.go @@ -4,25 +4,18 @@ import ( "context" ) -// IPAddressUpdateOptionsV2 fields are those accepted by UpdateIPAddress. +// IPAddressUpdateOptions fields are those accepted by UpdateIPAddress. // NOTE: An IP's RDNS can be reset to default using the following pattern: // -// IPAddressUpdateOptionsV2{ +// IPAddressUpdateOptions{ // RDNS: linodego.Pointer[*string](nil), // } -type IPAddressUpdateOptionsV2 struct { +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"` RDNS **string `json:"rdns,omitempty"` } -// IPAddressUpdateOptions fields are those accepted by UpdateIPAddress. -// -// Deprecated: Please use IPAddressUpdateOptionsV2 for all new implementations. -type IPAddressUpdateOptions struct { - RDNS *string `json:"rdns"` -} - // LinodeIPAssignment stores an assignment between an IP address and a Linode instance. type LinodeIPAssignment struct { Address string `json:"address"` @@ -56,24 +49,16 @@ type ListIPAddressesQuery struct { SkipIPv6RDNS bool `query:"skip_ipv6_rdns"` } -// GetUpdateOptionsV2 converts a IPAddress to IPAddressUpdateOptionsV2 for use in UpdateIPAddressV2. -func (i InstanceIP) GetUpdateOptionsV2() IPAddressUpdateOptionsV2 { +// GetUpdateOptions converts a IPAddress to IPAddressUpdateOptions for use in UpdateIPAddress. +func (i InstanceIP) GetUpdateOptions() IPAddressUpdateOptions { rdns := copyString(&i.RDNS) - return IPAddressUpdateOptionsV2{ + return IPAddressUpdateOptions{ RDNS: &rdns, Reserved: copyBool(&i.Reserved), } } -// GetUpdateOptions converts a IPAddress to IPAddressUpdateOptions for use in UpdateIPAddress. -// -// Deprecated: Please use GetUpdateOptionsV2 for all new implementations. -func (i InstanceIP) GetUpdateOptions() (o IPAddressUpdateOptions) { - o.RDNS = copyString(&i.RDNS) - return o -} - // ListIPAddresses lists IPAddresses. func (c *Client) ListIPAddresses(ctx context.Context, opts *ListOptions) ([]InstanceIP, error) { return getPaginatedResults[InstanceIP](ctx, c, "networking/ips", opts) @@ -85,20 +70,12 @@ func (c *Client) GetIPAddress(ctx context.Context, id string) (*InstanceIP, erro return doGETRequest[InstanceIP](ctx, c, e) } -// UpdateIPAddressV2 updates the IP address with the specified address. -func (c *Client) UpdateIPAddressV2(ctx context.Context, address string, opts IPAddressUpdateOptionsV2) (*InstanceIP, error) { +// UpdateIPAddress updates the IP address with the specified address. +func (c *Client) UpdateIPAddress(ctx context.Context, address string, opts IPAddressUpdateOptions) (*InstanceIP, error) { e := formatAPIPath("networking/ips/%s", address) return doPUTRequest[InstanceIP](ctx, c, e, opts) } -// UpdateIPAddress updates the IP address with the specified id. -// -// Deprecated: Please use UpdateIPAddressV2 for all new implementation. -func (c *Client) UpdateIPAddress(ctx context.Context, id string, opts IPAddressUpdateOptions) (*InstanceIP, error) { - e := formatAPIPath("networking/ips/%s", id) - return doPUTRequest[InstanceIP](ctx, c, e, opts) -} - // InstancesAssignIPs assigns multiple IPv4 addresses and/or IPv6 ranges to multiple Linodes in one Region. // This allows swapping, shuffling, or otherwise reorganizing IPs to your Linodes. func (c *Client) InstancesAssignIPs(ctx context.Context, opts LinodesAssignIPsOptions) error { diff --git a/object_storage_bucket_certs.go b/object_storage_bucket_certs.go index 36fb5301f..e38abd8d6 100644 --- a/object_storage_bucket_certs.go +++ b/object_storage_bucket_certs.go @@ -4,12 +4,7 @@ import ( "context" ) -// Deprecated: Please use ObjectStorageBucketCertV2 for all new implementations. type ObjectStorageBucketCert struct { - SSL bool `json:"ssl"` -} - -type ObjectStorageBucketCertV2 struct { SSL *bool `json:"ssl"` } @@ -19,43 +14,23 @@ type ObjectStorageBucketCertUploadOptions struct { } // UploadObjectStorageBucketCert uploads a TLS/SSL Cert to be used with an Object Storage Bucket. -// -// Deprecated: Please use UploadObjectStorageBucketCertV2 for all new implementations. func (c *Client) UploadObjectStorageBucketCert( ctx context.Context, - clusterOrRegionID, bucket string, + regionID, bucket string, opts ObjectStorageBucketCertUploadOptions, ) (*ObjectStorageBucketCert, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket) + e := formatAPIPath("object-storage/buckets/%s/%s/ssl", regionID, bucket) return doPOSTRequest[ObjectStorageBucketCert](ctx, c, e, opts) } // GetObjectStorageBucketCert gets an ObjectStorageBucketCert -// -// Deprecated: Please use GetObjectStorageBucketCertV2 for all new implementations. -func (c *Client) GetObjectStorageBucketCert(ctx context.Context, clusterOrRegionID, bucket string) (*ObjectStorageBucketCert, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket) +func (c *Client) GetObjectStorageBucketCert(ctx context.Context, regionID, bucket string) (*ObjectStorageBucketCert, error) { + e := formatAPIPath("object-storage/buckets/%s/%s/ssl", regionID, bucket) return doGETRequest[ObjectStorageBucketCert](ctx, c, e) } -// UploadObjectStorageBucketCertV2 uploads a TLS/SSL Cert to be used with an Object Storage Bucket. -func (c *Client) UploadObjectStorageBucketCertV2( - ctx context.Context, - clusterOrRegionID, bucket string, - opts ObjectStorageBucketCertUploadOptions, -) (*ObjectStorageBucketCertV2, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket) - return doPOSTRequest[ObjectStorageBucketCertV2](ctx, c, e, opts) -} - -// GetObjectStorageBucketCertV2 gets an ObjectStorageBucketCert -func (c *Client) GetObjectStorageBucketCertV2(ctx context.Context, clusterOrRegionID, bucket string) (*ObjectStorageBucketCertV2, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket) - return doGETRequest[ObjectStorageBucketCertV2](ctx, c, e) -} - // DeleteObjectStorageBucketCert deletes an ObjectStorageBucketCert -func (c *Client) DeleteObjectStorageBucketCert(ctx context.Context, clusterOrRegionID, bucket string) error { - e := formatAPIPath("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket) +func (c *Client) DeleteObjectStorageBucketCert(ctx context.Context, regionID, bucket string) error { + e := formatAPIPath("object-storage/buckets/%s/%s/ssl", regionID, bucket) return doDELETERequest(ctx, c, e) } diff --git a/object_storage_buckets.go b/object_storage_buckets.go index f8eed4963..d3e991a68 100644 --- a/object_storage_buckets.go +++ b/object_storage_buckets.go @@ -14,15 +14,7 @@ import ( type ObjectStorageBucket struct { Label string `json:"label"` - // Deprecated: The 'Cluster' field has been deprecated in favor of the 'Region' field. - // For example, a Cluster value of `us-mia-1` will translate to a Region value of `us-mia`. - // - // This is necessary because there are now multiple Object Storage clusters to a region. - // - // NOTE: The 'Cluster' field will always return a value similar to `-1` (e.g., `us-mia-1`) - // for backward compatibility purposes. - Cluster string `json:"cluster"` - Region string `json:"region"` + Region string `json:"region"` S3Endpoint string `json:"s3_endpoint"` EndpointType ObjectStorageEndpointType `json:"endpoint_type"` @@ -32,13 +24,7 @@ type ObjectStorageBucket struct { Size int `json:"size"` } -// ObjectStorageBucketAccess holds Object Storage access info type ObjectStorageBucketAccess struct { - ACL ObjectStorageACL `json:"acl"` - CorsEnabled bool `json:"cors_enabled"` -} - -type ObjectStorageBucketAccessV2 struct { ACL ObjectStorageACL `json:"acl"` ACLXML string `json:"acl_xml"` CorsEnabled *bool `json:"cors_enabled"` @@ -84,13 +70,7 @@ func (i *ObjectStorageBucket) UnmarshalJSON(b []byte) error { // ObjectStorageBucketCreateOptions fields are those accepted by CreateObjectStorageBucket type ObjectStorageBucketCreateOptions struct { - // Deprecated: The 'Cluster' field has been deprecated. - // - // Going forward, the 'Region' field will be the supported way to designate where an - // Object Storage Bucket should be created. For example, a 'Cluster' value of `us-mia-1` - // will translate to a Region value of `us-mia`. - Cluster string `json:"cluster,omitempty"` - Region string `json:"region,omitempty"` + Region string `json:"region,omitempty"` Label string `json:"label"` S3Endpoint string `json:"s3_endpoint,omitempty"` @@ -130,14 +110,14 @@ func (c *Client) ListObjectStorageBuckets(ctx context.Context, opts *ListOptions return getPaginatedResults[ObjectStorageBucket](ctx, c, "object-storage/buckets", opts) } -// ListObjectStorageBucketsInCluster lists all ObjectStorageBuckets of a cluster -func (c *Client) ListObjectStorageBucketsInCluster(ctx context.Context, opts *ListOptions, clusterOrRegionID string) ([]ObjectStorageBucket, error) { - return getPaginatedResults[ObjectStorageBucket](ctx, c, formatAPIPath("object-storage/buckets/%s", clusterOrRegionID), opts) +// ListObjectStorageBucketsInRegion lists all ObjectStorageBuckets in the specified region +func (c *Client) ListObjectStorageBucketsInRegion(ctx context.Context, opts *ListOptions, regionID string) ([]ObjectStorageBucket, error) { + return getPaginatedResults[ObjectStorageBucket](ctx, c, formatAPIPath("object-storage/buckets/%s", regionID), opts) } // GetObjectStorageBucket gets the ObjectStorageBucket with the provided label -func (c *Client) GetObjectStorageBucket(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucket, error) { - e := formatAPIPath("object-storage/buckets/%s/%s", clusterOrRegionID, label) +func (c *Client) GetObjectStorageBucket(ctx context.Context, regionID, label string) (*ObjectStorageBucket, error) { + e := formatAPIPath("object-storage/buckets/%s/%s", regionID, label) return doGETRequest[ObjectStorageBucket](ctx, c, e) } @@ -146,39 +126,31 @@ func (c *Client) CreateObjectStorageBucket(ctx context.Context, opts ObjectStora return doPOSTRequest[ObjectStorageBucket](ctx, c, "object-storage/buckets", opts) } -// GetObjectStorageBucketAccess gets the current access config for a bucket -// -// Deprecated: use GetObjectStorageBucketAccessV2 for new implementations -func (c *Client) GetObjectStorageBucketAccess(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucketAccess, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/access", clusterOrRegionID, label) - return doGETRequest[ObjectStorageBucketAccess](ctx, c, e) -} - // UpdateObjectStorageBucketAccess updates the access configuration for an ObjectStorageBucket -func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, clusterOrRegionID, label string, opts ObjectStorageBucketUpdateAccessOptions) error { - e := formatAPIPath("object-storage/buckets/%s/%s/access", clusterOrRegionID, label) +func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, regionID, label string, opts ObjectStorageBucketUpdateAccessOptions) error { + e := formatAPIPath("object-storage/buckets/%s/%s/access", regionID, label) return doPOSTRequestNoResponseBody(ctx, c, e, opts) } -// GetObjectStorageBucketAccessV2 gets the current access config for a bucket -func (c *Client) GetObjectStorageBucketAccessV2(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucketAccessV2, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/access", clusterOrRegionID, label) - return doGETRequest[ObjectStorageBucketAccessV2](ctx, c, e) +// GetObjectStorageBucketAccess gets the current access config for a bucket +func (c *Client) GetObjectStorageBucketAccess(ctx context.Context, regionID, label string) (*ObjectStorageBucketAccess, error) { + e := formatAPIPath("object-storage/buckets/%s/%s/access", regionID, label) + return doGETRequest[ObjectStorageBucketAccess](ctx, c, e) } // DeleteObjectStorageBucket deletes the ObjectStorageBucket with the specified label -func (c *Client) DeleteObjectStorageBucket(ctx context.Context, clusterOrRegionID, label string) error { - e := formatAPIPath("object-storage/buckets/%s/%s", clusterOrRegionID, label) +func (c *Client) DeleteObjectStorageBucket(ctx context.Context, regionID, label string) error { + e := formatAPIPath("object-storage/buckets/%s/%s", regionID, label) return doDELETERequest(ctx, c, e) } // ListObjectStorageBucketContents lists the contents of the specified ObjectStorageBucket func (c *Client) ListObjectStorageBucketContents( ctx context.Context, - clusterOrRegionID, label string, + regionID, label string, params *ObjectStorageBucketListContentsParams, ) (*ObjectStorageBucketContent, error) { - basePath := formatAPIPath("object-storage/buckets/%s/%s/object-list", clusterOrRegionID, label) + basePath := formatAPIPath("object-storage/buckets/%s/%s/object-list", regionID, label) queryString := "" diff --git a/object_storage_clusters.go b/object_storage_clusters.go deleted file mode 100644 index e4793241c..000000000 --- a/object_storage_clusters.go +++ /dev/null @@ -1,26 +0,0 @@ -package linodego - -import ( - "context" -) - -// ObjectStorageCluster represents a linode object storage cluster object -type ObjectStorageCluster struct { - ID string `json:"id"` - Domain string `json:"domain"` - Status string `json:"status"` - Region string `json:"region"` - StaticSiteDomain string `json:"static_site_domain"` -} - -// ListObjectStorageClusters lists ObjectStorageClusters -func (c *Client) ListObjectStorageClusters(ctx context.Context, opts *ListOptions) ([]ObjectStorageCluster, error) { - return getPaginatedResults[ObjectStorageCluster](ctx, c, "object-storage/clusters", opts) -} - -// Deprecated: GetObjectStorageCluster uses a deprecated API endpoint. -// GetObjectStorageCluster gets the template with the provided ID -func (c *Client) GetObjectStorageCluster(ctx context.Context, clusterID string) (*ObjectStorageCluster, error) { - e := formatAPIPath("object-storage/clusters/%s", clusterID) - return doGETRequest[ObjectStorageCluster](ctx, c, e) -} diff --git a/object_storage_keys.go b/object_storage_keys.go index cfc2ef480..a0b28065e 100644 --- a/object_storage_keys.go +++ b/object_storage_keys.go @@ -23,11 +23,7 @@ type ObjectStorageKey struct { // ObjectStorageKeyBucketAccess represents a linode limited object storage key's bucket access type ObjectStorageKeyBucketAccess struct { - // Deprecated: Cluster field has been deprecated. - // Please consider switching to use the 'Region' field. - // If your Cluster is `us-mia-1`, then the region would be `us-mia`. - Cluster string `json:"cluster,omitempty"` - Region string `json:"region,omitempty"` + Region string `json:"region,omitempty"` BucketName string `json:"bucket_name"` Permissions string `json:"permissions"` diff --git a/object_storage_object.go b/object_storage_object.go index 2e9cf8890..224d37152 100644 --- a/object_storage_object.go +++ b/object_storage_object.go @@ -17,13 +17,7 @@ type ObjectStorageObjectURL struct { Exists bool `json:"exists"` } -// Deprecated: Please use ObjectStorageObjectACLConfigV2 for all new implementations. type ObjectStorageObjectACLConfig struct { - ACL string `json:"acl"` - ACLXML string `json:"acl_xml"` -} - -type ObjectStorageObjectACLConfigV2 struct { ACL *string `json:"acl"` ACLXML *string `json:"acl_xml"` } @@ -35,39 +29,23 @@ type ObjectStorageObjectACLConfigUpdateOptions struct { func (c *Client) CreateObjectStorageObjectURL( ctx context.Context, - objectID, label string, + regionID, label string, opts ObjectStorageObjectURLCreateOptions, ) (*ObjectStorageObjectURL, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/object-url", objectID, label) + e := formatAPIPath("object-storage/buckets/%s/%s/object-url", regionID, label) return doPOSTRequest[ObjectStorageObjectURL](ctx, c, e, opts) } -// Deprecated: use GetObjectStorageObjectACLConfigV2 for new implementations -func (c *Client) GetObjectStorageObjectACLConfig(ctx context.Context, objectID, label, object string) (*ObjectStorageObjectACLConfig, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/object-acl?name=%s", objectID, label, object) +func (c *Client) GetObjectStorageObjectACLConfig(ctx context.Context, regionID, label, object string) (*ObjectStorageObjectACLConfig, error) { + e := formatAPIPath("object-storage/buckets/%s/%s/object-acl?name=%s", regionID, label, object) return doGETRequest[ObjectStorageObjectACLConfig](ctx, c, e) } -// Deprecated: use UpdateObjectStorageObjectACLConfigV2 for new implementations func (c *Client) UpdateObjectStorageObjectACLConfig( ctx context.Context, - objectID, label string, + regionID, label string, opts ObjectStorageObjectACLConfigUpdateOptions, ) (*ObjectStorageObjectACLConfig, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/object-acl", objectID, label) + e := formatAPIPath("object-storage/buckets/%s/%s/object-acl", regionID, label) return doPUTRequest[ObjectStorageObjectACLConfig](ctx, c, e, opts) } - -func (c *Client) GetObjectStorageObjectACLConfigV2(ctx context.Context, objectID, label, object string) (*ObjectStorageObjectACLConfigV2, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/object-acl?name=%s", objectID, label, object) - return doGETRequest[ObjectStorageObjectACLConfigV2](ctx, c, e) -} - -func (c *Client) UpdateObjectStorageObjectACLConfigV2( - ctx context.Context, - objectID, label string, - opts ObjectStorageObjectACLConfigUpdateOptions, -) (*ObjectStorageObjectACLConfigV2, error) { - e := formatAPIPath("object-storage/buckets/%s/%s/object-acl", objectID, label) - return doPUTRequest[ObjectStorageObjectACLConfigV2](ctx, c, e, opts) -} diff --git a/paged_response_structs.go b/paged_response_structs.go deleted file mode 100644 index 50af24c64..000000000 --- a/paged_response_structs.go +++ /dev/null @@ -1,174 +0,0 @@ -package linodego - -// Deprecated: AccountAvailabilityPagedResponse exists for historical compatibility and should not be used. -type AccountAvailabilityPagedResponse legacyPagedResponse[AccountAvailability] - -// Deprecated: AccountBetasPagedResponse exists for historical compatibility and should not be used. -type AccountBetasPagedResponse legacyPagedResponse[AccountBetaProgram] - -// Deprecated: BetaProgramPagedResponse exists for historical compatibility and should not be used. -type BetaProgramPagedResponse legacyPagedResponse[BetaProgram] - -// Deprecated: DatabaseEnginesPagedResponse exists for historical compatibility and should not be used. -type DatabaseEnginesPagedResponse legacyPagedResponse[DatabaseEngine] - -// Deprecated: DatabaseTypesPagedResponse exists for historical compatibility and should not be used. -type DatabaseTypesPagedResponse legacyPagedResponse[DatabaseType] - -// Deprecated: DatabasesPagedResponse exists for historical compatibility and should not be used. -type DatabasesPagedResponse legacyPagedResponse[Database] - -// Deprecated: DomainRecordsPagedResponse exists for historical compatibility and should not be used. -type DomainRecordsPagedResponse legacyPagedResponse[DomainRecord] - -// Deprecated: DomainsPagedResponse exists for historical compatibility and should not be used. -type DomainsPagedResponse legacyPagedResponse[Domain] - -// Deprecated: EventsPagedResponse exists for historical compatibility and should not be used. -type EventsPagedResponse legacyPagedResponse[Event] - -// Deprecated: FirewallDevicesPagedResponse exists for historical compatibility and should not be used. -type FirewallDevicesPagedResponse legacyPagedResponse[FirewallDevice] - -// Deprecated: FirewallsPagedResponse exists for historical compatibility and should not be used. -type FirewallsPagedResponse legacyPagedResponse[Firewall] - -// Deprecated: ImagesPagedResponse exists for historical compatibility and should not be used. -type ImagesPagedResponse legacyPagedResponse[Image] - -// Deprecated: InstanceConfigsPagedResponse exists for historical compatibility and should not be used. -type InstanceConfigsPagedResponse legacyPagedResponse[InstanceConfig] - -// Deprecated: InstanceDisksPagedResponse exists for historical compatibility and should not be used. -type InstanceDisksPagedResponse legacyPagedResponse[InstanceDisk] - -// Deprecated: InstanceFirewallsPagedResponse exists for historical compatibility and should not be used. -type InstanceFirewallsPagedResponse legacyPagedResponse[Firewall] - -// Deprecated: InstanceVolumesPagedResponse exists for historical compatibility and should not be used. -type InstanceVolumesPagedResponse legacyPagedResponse[Volume] - -// Deprecated: InstancesPagedResponse exists for historical compatibility and should not be used. -type InstancesPagedResponse legacyPagedResponse[Instance] - -// Deprecated: InvoiceItemsPagedResponse exists for historical compatibility and should not be used. -type InvoiceItemsPagedResponse legacyPagedResponse[InvoiceItem] - -// Deprecated: InvoicesPagedResponse exists for historical compatibility and should not be used. -type InvoicesPagedResponse legacyPagedResponse[Invoice] - -// Deprecated: LKEClusterPoolsPagedResponse exists for historical compatibility and should not be used. -// LKEClusterPoolsPagedResponse represents a paginated LKEClusterPool API response. -type LKEClusterPoolsPagedResponse LKENodePoolsPagedResponse - -// Deprecated: LKEVersionsPagedResponse exists for historical compatibility and should not be used. -type LKEVersionsPagedResponse legacyPagedResponse[LKEVersion] - -// Deprecated: LKEClusterAPIEndpointsPagedResponse exists for historical compatibility and should not be used. -type LKEClusterAPIEndpointsPagedResponse legacyPagedResponse[LKEClusterAPIEndpoint] - -// Deprecated: LKEClustersPagedResponse exists for historical compatibility and should not be used. -type LKEClustersPagedResponse legacyPagedResponse[LKECluster] - -// Deprecated: LKENodePoolsPagedResponse exists for historical compatibility and should not be used. -type LKENodePoolsPagedResponse legacyPagedResponse[LKENodePool] - -// Deprecated: IPAddressesPagedResponse exists for historical compatibility and should not be used. -type IPAddressesPagedResponse legacyPagedResponse[InstanceIP] - -// Deprecated: IPv6PoolsPagedResponse exists for historical compatibility and should not be used. -type IPv6PoolsPagedResponse legacyPagedResponse[IPv6Range] - -// Deprecated: IPv6RangesPagedResponse exists for historical compatibility and should not be used. -type IPv6RangesPagedResponse legacyPagedResponse[IPv6Range] - -// Deprecated: LinodeKernelsPagedResponse exists for historical compatibility and should not be used. -type LinodeKernelsPagedResponse legacyPagedResponse[LinodeKernel] - -// Deprecated: LinodeTypesPagedResponse exists for historical compatibility and should not be used. -type LinodeTypesPagedResponse legacyPagedResponse[LinodeType] - -// Deprecated: LoginsPagedResponse exists for historical compatibility and should not be used. -type LoginsPagedResponse legacyPagedResponse[Login] - -// Deprecated: LongviewClientsPagedResponse exists for historical compatibility and should not be used. -type LongviewClientsPagedResponse legacyPagedResponse[LongviewClient] - -// Deprecated: LongviewSubscriptionsPagedResponse exists for historical compatibility and should not be used. -type LongviewSubscriptionsPagedResponse legacyPagedResponse[LongviewSubscription] - -// Deprecated: MySQLDatabasesPagedResponse exists for historical compatibility and should not be used. -type MySQLDatabasesPagedResponse legacyPagedResponse[MySQLDatabase] - -// Deprecated: NodeBalancersPagedResponse exists for historical compatibility and should not be used. -type NodeBalancersPagedResponse legacyPagedResponse[NodeBalancer] - -// Deprecated: NodeBalancerConfigsPagedResponse exists for historical compatibility and should not be used. -type NodeBalancerConfigsPagedResponse legacyPagedResponse[NodeBalancerConfig] - -// Deprecated: NodeBalancerNodesPagedResponse exists for historical compatibility and should not be used. -type NodeBalancerNodesPagedResponse legacyPagedResponse[NodeBalancerNode] - -// Deprecated: NodeBalancerFirewallsPagedResponse exists for historical compatibility and should not be used. -type NodeBalancerFirewallsPagedResponse legacyPagedResponse[Firewall] - -// Deprecated: NotificationsPagedResponse exists for historical compatibility and should not be used. -type NotificationsPagedResponse legacyPagedResponse[Notification] - -// Deprecated: OAuthClientsPagedResponse exists for historical compatibility and should not be used. -type OAuthClientsPagedResponse legacyPagedResponse[OAuthClient] - -// Deprecated: ObjectStorageKeysPagedResponse exists for historical compatibility and should not be used. -type ObjectStorageKeysPagedResponse legacyPagedResponse[ObjectStorageKey] - -// Deprecated: ObjectStorageBucketsPagedResponse exists for historical compatibility and should not be used. -type ObjectStorageBucketsPagedResponse legacyPagedResponse[ObjectStorageBucket] - -// Deprecated: ObjectStorageClustersPagedResponse exists for historical compatibility and should not be used. -type ObjectStorageClustersPagedResponse legacyPagedResponse[ObjectStorageCluster] - -// Deprecated: PaymentsPagedResponse exists for historical compatibility and should not be used. -type PaymentsPagedResponse legacyPagedResponse[Payment] - -// Deprecated: RegionsPagedResponse exists for historical compatibility and should not be used. -type RegionsPagedResponse legacyPagedResponse[Region] - -// Deprecated: SSHKeysPagedResponse exists for historical compatibility and should not be used. -type SSHKeysPagedResponse legacyPagedResponse[SSHKey] - -// Deprecated: TokensPagedResponse exists for historical compatibility and should not be used. -type ( - TokensPagedResponse legacyPagedResponse[Token] - // Deprecated: RegionsAvailabilityPagedResponse exists for historical compatibility and should not be used. - RegionsAvailabilityPagedResponse legacyPagedResponse[RegionAvailability] -) - -// Deprecated: StackscriptsPagedResponse exists for historical compatibility and should not be used. -type StackscriptsPagedResponse legacyPagedResponse[Stackscript] - -// Deprecated: TagsPagedResponse exists for historical compatibility and should not be used. -type TagsPagedResponse legacyPagedResponse[Tag] - -// Deprecated: TaggedObjectsPagedResponse exists for historical compatibility and should not be used. -type TaggedObjectsPagedResponse legacyPagedResponse[TaggedObject] - -// Deprecated: TicketsPagedResponse exists for historical compatibility and should not be used. -type TicketsPagedResponse legacyPagedResponse[Ticket] - -// Deprecated: PostgresDatabasesPagedResponse exists for historical compatibility and should not be used. -type PostgresDatabasesPagedResponse legacyPagedResponse[PostgresDatabase] - -// Deprecated: ProfileLoginsPagedResponse exists for historical compatibility and should not be used. -type ProfileLoginsPagedResponse legacyPagedResponse[ProfileLogin] - -// Deprecated: UsersPagedResponse exists for historical compatibility and should not be used. -type UsersPagedResponse legacyPagedResponse[User] - -// Deprecated: VolumesPagedResponse exists for historical compatibility and should not be used. -type VolumesPagedResponse legacyPagedResponse[Volume] - -// Deprecated: VPCsPagedResponse exists for historical compatibility and should not be used. -type VPCsPagedResponse legacyPagedResponse[VPC] - -// Deprecated: VPCSubnetsPagedResponse exists for historical compatibility and should not be used. -type VPCSubnetsPagedResponse legacyPagedResponse[VPCSubnet] diff --git a/pagination.go b/pagination.go index b0fec7040..7addc7c01 100644 --- a/pagination.go +++ b/pagination.go @@ -174,9 +174,3 @@ func queryFieldToString(value reflect.Value) (string, error) { return "", fmt.Errorf("unsupported query param type: %s", value.Type().Name()) } } - -type legacyPagedResponse[T any] struct { - *PageOptions - - Data []T `json:"data"` -} diff --git a/regions.go b/regions.go index 935d9aba4..ad0a0a2ba 100644 --- a/regions.go +++ b/regions.go @@ -58,10 +58,6 @@ const ( CapabilityVPCIPv6LargePrefixes string = "VPC IPv6 Large Prefixes" CapabilityVPCIPv6Stack string = "VPC IPv6 Stack" CapabilityVPCsExtra string = "VPCs Extra" - - // Deprecated: CapabilityObjectStorageRegions constant has been - // renamed to `CapabilityObjectStorageAccessKeyRegions`. - CapabilityObjectStorageRegions string = CapabilityObjectStorageAccessKeyRegions ) // Region-related endpoints have a custom expiry time as the diff --git a/test/integration/fixtures/TestObjectStorageBucketCert.yaml b/test/integration/fixtures/TestObjectStorageBucketCert.yaml index 4f2026682..961169eb8 100644 --- a/test/integration/fixtures/TestObjectStorageBucketCert.yaml +++ b/test/integration/fixtures/TestObjectStorageBucketCert.yaml @@ -14,25 +14,33 @@ interactions: url: https://api.linode.com/v4beta/object-storage/endpoints?page=1 method: GET response: - body: '{"pages": 1, "page": 1, "results": 18, "data": [{"region": "fr-par", "endpoint_type": - "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, {"region": "ap-south", "endpoint_type": - "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, {"region": "us-sea", "endpoint_type": - "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, {"region": "us-east", "endpoint_type": - "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, {"region": "us-southeast", + body: '{"data": [{"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": + "ap-south-1.linodeobjects.com"}, {"region": "us-iad", "endpoint_type": "E1", + "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"region": "fr-par", "endpoint_type": + "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, {"region": - "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, - {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, - {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, - {"region": "us-iad", "endpoint_type": "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, - {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, - {"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, + "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, + {"region": "au-mel", "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com"}, + {"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, + {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, + {"region": "de-fra-2", "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com"}, + {"region": "us-lax", "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com"}, {"region": "us-lax", "endpoint_type": "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, - {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, + {"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, {"region": "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, + {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, + {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, - {"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, + {"region": "gb-lon", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com"}, + {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, - {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}]}' + {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, + {"region": "us-east", "endpoint_type": "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, + {"region": "sg-sin-2", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com"}, + {"region": "jp-tyo-3", "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com"}], + "page": 1, "pages": 1, "results": 25}' headers: Access-Control-Allow-Credentials: - "true" @@ -55,7 +63,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:13:19 GMT + - Thu, 30 Apr 2026 20:17:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -74,14 +82,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"fr-par","label":"linode-obj-bucket-cert-test.xyz","endpoint_type":"E1"}' + body: '{"region":"us-iad","label":"linode-obj-bucket-cert-test.xyz","endpoint_type":"E1"}' form: {} headers: Accept: @@ -93,10 +101,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets method: POST response: - body: '{"hostname": "linode-obj-bucket-cert-test.xyz.fr-par-1.linodeobjects.com", + body: '{"hostname": "linode-obj-bucket-cert-test.xyz.us-iad-1.linodeobjects.com", "label": "linode-obj-bucket-cert-test.xyz", "created": "2018-01-02T03:04:05", - "region": "fr-par", "cluster": "fr-par-1", "size": 0, "objects": 0, "endpoint_type": - "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}' + "region": "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": + "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}' headers: Access-Control-Allow-Credentials: - "true" @@ -121,7 +129,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:13:22 GMT + - Thu, 30 Apr 2026 20:17:50 GMT Pragma: - no-cache Strict-Transport-Security: @@ -138,7 +146,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -156,7 +164,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz/ssl + url: https://api.linode.com/v4beta/object-storage/buckets/us-iad/linode-obj-bucket-cert-test.xyz/ssl method: POST response: body: '{"ssl": true}' @@ -184,68 +192,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:13:24 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz/ssl - 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, 08 Jan 2025 07:13:26 GMT + - Thu, 30 Apr 2026 20:17:51 GMT Pragma: - no-cache Strict-Transport-Security: @@ -262,132 +209,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"certificate":"-----BEGIN CERTIFICATE-----\nMIIF3DCCA8QCCQC0dUFu1HvjazANBgkqhkiG9w0BAQsFADCBrzELMAkGA1UEBhMC\nVVMxCzAJBgNVBAgMAlBBMRUwEwYDVQQHDAxQaGlsYWRlbHBoaWExDzANBgNVBAoM\nBkxpbm9kZTELMAkGA1UECwwCRFgxKDAmBgNVBAMMH2xpbm9kZS1vYmotYnVja2V0\nLWNlcnQtdGVzdC54eXoxNDAyBgkqhkiG9w0BCQEWJWFkbWluQGxpbm9kZS1vYmot\nYnVja2V0LWNlcnQtdGVzdC54eXowHhcNMjAxMDA1MTg0MDUyWhcNMjExMDA1MTg0\nMDUyWjCBrzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlBBMRUwEwYDVQQHDAxQaGls\nYWRlbHBoaWExDzANBgNVBAoMBkxpbm9kZTELMAkGA1UECwwCRFgxKDAmBgNVBAMM\nH2xpbm9kZS1vYmotYnVja2V0LWNlcnQtdGVzdC54eXoxNDAyBgkqhkiG9w0BCQEW\nJWFkbWluQGxpbm9kZS1vYmotYnVja2V0LWNlcnQtdGVzdC54eXowggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCy4LqfRYXE314e6YkpR1BbKPH8ohO4lcMt\n+YzMUNlOC1KUktGjX8pWk4wAXYar7Mxccmbbh68pgE8iSio8V97CdQb8O64OQmre\n/y33z7Yts37/6mH5mBnfeiilVHOenQmh+4400tvF1jljU8MZSg6sLM4ZEBhfcT0V\n3yqxAwwzV8vk0t7uLRCMuDI5B4h4ZCsheCkA2roF4RGUG6KwGzf+dLSKzBcjy5ho\nh4huzp5jDYer7S86dV6/9Gwzh8CPhVaixbymHGoMbJM8lUtc/hFI+J8WVh/qLTKQ\nCcqvoZ96QU0LX2ib+ElvCMGl/UrznpHZUrGkLPfnnoxK/vKBNycJsENtWno9KgtN\nfsdmYy/blxNRW/qpi+l92f3zbjjpRqJ/oyA+hsSMn19O/v3O4wz+YS55xnVeEPIf\nfOq6VJ9BfVdXPPRp33sllM8EVWuS4ry3oJKI1CFTlhV7eU1RpJmbc5X8GhytiD2M\ngIrVlYzJTftSHw7J3v0orRD6SxI9enXI4o4pS1MMxRNb+ZQDvwx3ZujxjFXe3+qI\nkme3ih+Vl9W9rDeKAd95ciII9CxBqOvsso8zqDAEV25fn3tutk/7hQNMqv0APAah\nLo/eY1NK9i9YVJknVSzWBkE2MUyvpfFhiw6TPYh88qH+wN3CznWaCtXiAjH3kbOk\n6y2OmI8+4QIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCP2UawP8GDWxyMOsHDPqKp\nPtedCxPpEPsQm8KMnt5KJ55NFqTcpARz1miHXT1aBedu9IoqxvTP4g8BQ4QFjP2s\nddNu2WKqnwyzkCtnB2zOrOKlvUtRAZ4x2iyhKNqls6D7I4tw22HMbTzW2TVeuGVa\noiRtawFcUsjSAcarRw6swLTln+BK54dWa9E5hiulBoHLosMWCEyUDrUnaiB+2+7C\nbsExYZTXRlii7YPSr46zPmte2iKa1+b0g5DXkzSazWp+R/dlGYp84uLWk71e4b/9\nSo1pIitPasCJHgO/ii9nIcmDXarkaGT5CEUP8WPp6mLY5W9NxgF2czdz6AMJa3P9\n2jNd4J1VFl8k+LDZ4GnwHGhyL3h3lFUmmoQV/0YVoXmA59SxE2JPvc2d1V6xh2gz\nyg2M+xcKliSXxshhAopsSSoEp5g3II2mCvzeSxwsXa4Ob5c5TJNdXslm1pugRCbB\ntjFNh70wZmCq+jY8C+vGsDwkf/5UeAd+c+14s3bwsBfWqZBGokVxyf/UWHtsWlVn\np3USWBwLxEWyQIioMmj4O6wROZeyePDlFDVky4hzTCrTS6EFIqkGBs5RneCHhTN0\ngNHFG8Ixql6mybJAwopvWGEL+7E4pbNdbhmgVvf2YEQuMZBCM7fGdBsRNkTs6jIA\n/8soO6buQgQoCq3GFbodZA==\n-----END - CERTIFICATE-----\n","private_key":"-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCy4LqfRYXE314e\n6YkpR1BbKPH8ohO4lcMt+YzMUNlOC1KUktGjX8pWk4wAXYar7Mxccmbbh68pgE8i\nSio8V97CdQb8O64OQmre/y33z7Yts37/6mH5mBnfeiilVHOenQmh+4400tvF1jlj\nU8MZSg6sLM4ZEBhfcT0V3yqxAwwzV8vk0t7uLRCMuDI5B4h4ZCsheCkA2roF4RGU\nG6KwGzf+dLSKzBcjy5hoh4huzp5jDYer7S86dV6/9Gwzh8CPhVaixbymHGoMbJM8\nlUtc/hFI+J8WVh/qLTKQCcqvoZ96QU0LX2ib+ElvCMGl/UrznpHZUrGkLPfnnoxK\n/vKBNycJsENtWno9KgtNfsdmYy/blxNRW/qpi+l92f3zbjjpRqJ/oyA+hsSMn19O\n/v3O4wz+YS55xnVeEPIffOq6VJ9BfVdXPPRp33sllM8EVWuS4ry3oJKI1CFTlhV7\neU1RpJmbc5X8GhytiD2MgIrVlYzJTftSHw7J3v0orRD6SxI9enXI4o4pS1MMxRNb\n+ZQDvwx3ZujxjFXe3+qIkme3ih+Vl9W9rDeKAd95ciII9CxBqOvsso8zqDAEV25f\nn3tutk/7hQNMqv0APAahLo/eY1NK9i9YVJknVSzWBkE2MUyvpfFhiw6TPYh88qH+\nwN3CznWaCtXiAjH3kbOk6y2OmI8+4QIDAQABAoICAElFboxhMPtEt8wXwzxqXssI\niZ7/UO6yQeHqL7ddgrXKQ4hiX4b5bOtrwtQ/ezOfatKPdfyEpsZsLX4RPR28rJ2g\nzDyzwYdLw3UWt+Cjb69msCXp/zn7CNYWtuGKJ1YYY2K7pTOUD7wJFTbPj8IjKMF0\nFPQFOMaXnvr/kAA0DGJXm0he7DxJr1bE+KWNpWQTO+uYycr0zXAtEkNF0q0qaRRM\n/8s+8FeURRjEM6mX7x8J4sIVBNyASVB9sXimKcVgS+2e67hrOTFfpCwTx2wPEkt+\ns8O1gZst6mE/8Ythu+6bIxD+gt4opQPbZV810ubZ1Epd6jAiz2VL95Gcvv8Y9V7+\nEGfqeeiHqQkIkhSNO6Aqui/QBHEIuXlDvh6/Q23ln/AeniHFktYASK2WtbtzXON5\n3yL0d8S5ndCLYMch1uv1V+JQ67Y5JJYTAh+fev7uyZy7qLGnAjUoRnwRofwgig6a\nlKOf9aMlLJnIJSHlyzqni5wnVdO1y/RGMsE/BdJ15+F9LGYm/sy56VPsjU9rELIa\n9UGLAWNiEZQDQLgApZl8rawXVlANwW/iesxgAh4eZlaFXvaGtK72KcETBfn+jt8m\n2/LUbh4BL2O4F2OJ2F8+DET6JGDrNDBkcsSxYmtgtRpJjrV76MvjSli8uRAlaEd7\nR3n3ztdOEX25VeFExsdFAoIBAQDhFInwMNTY+phF57o/R6FNyLHQGkNz2w4pYXkR\nA6C4wgBDfwk/S/Sub16w4H6sr0C7MDw7t2cpmMhe+BG4V4a5sX+AjSSdMFBS/pgI\nuFgeJGBG1evyvp+8SycH7oojf106UH6gERpHmW0WMDf1r8Nueriw9DOKKqL1sJtx\nw/Diq2/8z2m5ESxL6SrEzagHmjliaNwBpwUlh5P2EMQzNTljE1fnEKl2E6LW35o0\nx4zoi3y57HtKcLNtD/GsvRYU8zjHDkDq2tUXwzxCVWmiTs3+NQVTEscJAgAahvbu\nJZ7hEXzmCR6sjoQIWCHc9Wusf/zt2XNiXYIKUJAQxv9sOgabAoIBAQDLc2Cxlz36\n3KcOGkfpWl9cGmS0t8FCOvOVV++7eNiWv0kKVdbwqqJYExmX4jmv2E1LfQ4G1vAh\nGtG7YN0rEzwLWiqd/frNLgMya7lYuCpWzxCNDoHIAtBvjPhyHRFFhLayxSsxRZLT\nPnKo2u9NjhPpm7RD+4b9uy++61jkDXK//ezI47oJWxCOxfyzaeejV8Iu9jHwKJ1o\nNpebAdPnlXU3itxaXvJIZiguHtNioTs1E6Ik433AC3Tb57Xy57lGXnOORm5Ximel\naJsB9dsh9rKsNScp+9VSD0ef7Cr8oZH0gOI+pmNnnXt+cOxH9Du4lvBql59QR9FY\nMbbigpvtJ6ozAoIBAG588ZV5sxJsOVGfhhrII9OWIEtCiTgXISWJFrAWctAfU5fO\nhZCPzaXPP9Fd8nD8eq8o53h8+GQ//qQ37CLsvFLtYeSN5JpQ/C0xkxo8u+zX+Hbt\nTizUDH+W+Kr5GtCAFhipKO+UVa0uEJGiy+WMCUhzb7RVu/MoKOSodDXtdJMgixG0\nE3boijEdXYRMXB6XQ3IefVlGTs10d1qEMnvctbX/6degoz82Nmp6Sy17g50n0+tE\nveT12+4+tGkSTQOtvYJhadaf45kNmsgJO5iUTKRsDJgSEKhIVhqvhAm1Z/+d4Qzf\nDzKvpvqdoMnho6CDF3r+kpiHxG0hzQafWQUcmt8CggEARD1461hNY71rEyHhiPXV\nEnGP4cXYvrxDQ45xTLJmA3o5p4vPQn4ZYe1WIkmxC7hDhNR3RfgGJzR1sKH2zSHw\ne+ZMcR3lZ7jNPbZAPu/W07M0W/vHsCyxeRkRpET3rBetqBzWNfqeGtjRYK2+oobL\nSwn81uihCK4mf6U09ZlFKfyj1WX82nJ/BUSHVC5rkbA348SUT3dwBKp7A3UDfKP2\n4yBidLVwErShOYcBZA2sbEsfkbv0S9wL4E7CCq2KyX2YyNn63MYBqcuCYo/yZlv2\n5igV8NEVZibV4WA3svEGoboxKM5qfTCnYWvC9QeImIuYLEibGTRdlXVnYGZqoosx\nXQKCAQEAmEbm8o37QaSMWYu/hixusHWprPRpEcz8qMmpenCTUeE7xgKeJupSx/2u\ns5WSGJy7U6jlmocMOsZ3/nPWNG219uWMUWz2REKi99KOHU7dT8N0OPigNzDBJFKe\nuJpHU2wWkg9CJtkDlQt+4/JP3gzskwpooRvUaEbsQkM0G/A1SMVSyYPuzBui3+E7\nHMuBpZsWkNKLh0hjC5i7YBZYtXGYPG2JCEE4mpiV8ClxTvmijsr8sYUOtnmIBXfG\n0fcsLA4W7xYCUqr74LA1dMQd6f8T00mZycR5eh0wXJ68i5QEotBTGS8ibTilUJbx\n7aJXvW2Q3oCt1sF576QNr9rLxhHl8A==\n-----END - PRIVATE KEY-----\n"}' - form: {} - headers: - Accept: - - application/json - Content-Type: - - application/json - User-Agent: - - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz/ssl - method: POST - response: - body: '{"ssl": 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: - - "13" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Wed, 08 Jan 2025 07:13:29 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz/ssl - method: GET - response: - body: '{"ssl": 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: - - "13" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Wed, 08 Jan 2025 07:13:31 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -403,7 +225,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz/ssl + url: https://api.linode.com/v4beta/object-storage/buckets/us-iad/linode-obj-bucket-cert-test.xyz/ssl method: GET response: body: '{"ssl": true}' @@ -431,7 +253,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:13:33 GMT + - Thu, 30 Apr 2026 20:17:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -449,7 +271,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -465,7 +287,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz/ssl + url: https://api.linode.com/v4beta/object-storage/buckets/us-iad/linode-obj-bucket-cert-test.xyz/ssl method: DELETE response: body: '{}' @@ -493,7 +315,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:13:34 GMT + - Thu, 30 Apr 2026 20:17:53 GMT Pragma: - no-cache Strict-Transport-Security: @@ -510,7 +332,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -526,7 +348,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/fr-par/linode-obj-bucket-cert-test.xyz + url: https://api.linode.com/v4beta/object-storage/buckets/us-iad/linode-obj-bucket-cert-test.xyz method: DELETE response: body: '{}' @@ -554,7 +376,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:13:38 GMT + - Thu, 30 Apr 2026 20:17:56 GMT Pragma: - no-cache Strict-Transport-Security: @@ -571,7 +393,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageBucket_Access_Get.yaml b/test/integration/fixtures/TestObjectStorageBucket_Access_Get.yaml index 074365933..01278ccfe 100644 --- a/test/integration/fixtures/TestObjectStorageBucket_Access_Get.yaml +++ b/test/integration/fixtures/TestObjectStorageBucket_Access_Get.yaml @@ -14,25 +14,32 @@ interactions: url: https://api.linode.com/v4beta/object-storage/endpoints?page=1 method: GET response: - body: '{"pages": 1, "page": 1, "results": 18, "data": [{"region": "us-iad", "endpoint_type": - "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"region": "in-maa", "endpoint_type": - "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, {"region": "us-east", "endpoint_type": - "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, {"region": "eu-central", - "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, {"region": - "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, - {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, - {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, - {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, - {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, - {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, - {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, - {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, - {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, + body: '{"data": [{"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, + {"region": "sg-sin-2", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com"}, + {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, + {"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, + {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, + {"region": "us-iad", "endpoint_type": "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, + {"region": "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, + {"region": "jp-tyo-3", "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com"}, + {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, + {"region": "us-lax", "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com"}, {"region": "us-lax", "endpoint_type": "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, - {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, + {"region": "au-mel", "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com"}, + {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, + {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, + {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, + {"region": "de-fra-2", "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com"}, + {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, + {"region": "us-east", "endpoint_type": "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, + {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, {"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, - {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}]}' + {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, + {"region": "gb-lon", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com"}], + "page": 1, "pages": 1, "results": 25}' headers: Access-Control-Allow-Credentials: - "true" @@ -55,7 +62,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:40:53 GMT + - Thu, 30 Apr 2026 20:18:26 GMT Pragma: - no-cache Strict-Transport-Security: @@ -74,14 +81,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"us-iad","label":"go-bucket-test-def","endpoint_type":"E1","acl":"authenticated-read","cors_enabled":false}' + body: '{"region":"se-sto","label":"go-bucket-test-def","endpoint_type":"E1","acl":"authenticated-read","cors_enabled":false}' form: {} headers: Accept: @@ -93,10 +100,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets method: POST response: - body: '{"hostname": "go-bucket-test-def.us-iad-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-iad", - "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com"}' + body: '{"hostname": "go-bucket-test-def.se-sto-1.linodeobjects.com", "label": + "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "se-sto", + "cluster": "se-sto-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": + "se-sto-1.linodeobjects.com"}' headers: Access-Control-Allow-Credentials: - "true" @@ -121,7 +128,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:40:55 GMT + - Thu, 30 Apr 2026 20:18:30 GMT Pragma: - no-cache Strict-Transport-Security: @@ -138,72 +145,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-iad/go-bucket-test-def/access - method: GET - response: - body: '{"acl": "authenticated-read", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936http://acs.amazonaws.com/groups/global/AuthenticatedUsersREADc9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL", - "cors_enabled": false, "cors_xml": 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: - - "808" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Wed, 08 Jan 2025 07:40:57 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -219,12 +161,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-iad/go-bucket-test-def/access + url: https://api.linode.com/v4beta/object-storage/buckets/se-sto/go-bucket-test-def/access method: GET response: - body: '{"acl": "authenticated-read", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89ehttp://acs.amazonaws.com/groups/global/AuthenticatedUsersREADc9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL", + xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\">640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89eFULL_CONTROL", "cors_enabled": false, "cors_xml": null}' headers: Access-Control-Allow-Credentials: @@ -250,7 +192,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:40:58 GMT + - Thu, 30 Apr 2026 20:18:34 GMT Pragma: - no-cache Strict-Transport-Security: @@ -268,7 +210,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -284,7 +226,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-iad-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/se-sto/go-bucket-test-def method: DELETE response: body: '{}' @@ -312,7 +254,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:41:08 GMT + - Thu, 30 Apr 2026 20:18:38 GMT Pragma: - no-cache Strict-Transport-Security: @@ -329,7 +271,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml b/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml index f16513000..d6af6dbf9 100644 --- a/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml +++ b/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml @@ -14,25 +14,32 @@ interactions: url: https://api.linode.com/v4beta/object-storage/endpoints?page=1 method: GET response: - body: '{"pages": 1, "page": 1, "results": 18, "data": [{"region": "us-lax", "endpoint_type": - "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, {"region": "us-southeast", - "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, {"region": - "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, - {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, + body: '{"data": [{"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, - {"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, - {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, - {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, - {"region": "us-iad", "endpoint_type": "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, - {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, + {"region": "de-fra-2", "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com"}, + {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, + {"region": "sg-sin-2", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com"}, + {"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, + {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, + {"region": "jp-tyo-3", "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com"}, + {"region": "us-lax", "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com"}, + {"region": "us-lax", "endpoint_type": "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, - {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, - {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, + {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, {"region": "us-east", "endpoint_type": "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, + {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, + {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, + {"region": "gb-lon", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com"}, + {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, + {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, + {"region": "au-mel", "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com"}, {"region": "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, - {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, - {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}]}' + {"region": "us-iad", "endpoint_type": "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, + {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}], + "page": 1, "pages": 1, "results": 25}' headers: Access-Control-Allow-Credentials: - "true" @@ -55,7 +62,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:41 GMT + - Thu, 30 Apr 2026 20:18:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -74,14 +81,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"us-lax","label":"go-bucket-test-def","endpoint_type":"E1"}' + body: '{"region":"it-mil","label":"go-bucket-test-def","endpoint_type":"E1"}' form: {} headers: Accept: @@ -93,10 +100,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets method: POST response: - body: '{"hostname": "go-bucket-test-def.us-lax-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-lax", - "cluster": "us-lax-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": - "us-lax-1.linodeobjects.com"}' + body: '{"hostname": "go-bucket-test-def.it-mil-1.linodeobjects.com", "label": + "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "it-mil", + "cluster": "it-mil-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": + "it-mil-1.linodeobjects.com"}' headers: Access-Control-Allow-Credentials: - "true" @@ -121,7 +128,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:42 GMT + - Thu, 30 Apr 2026 20:18:46 GMT Pragma: - no-cache Strict-Transport-Security: @@ -138,7 +145,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -154,7 +161,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-lax/go-bucket-test-def/access + url: https://api.linode.com/v4beta/object-storage/buckets/it-mil/go-bucket-test-def/access method: POST response: body: '{}' @@ -182,7 +189,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:43 GMT + - Thu, 30 Apr 2026 20:18:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -199,7 +206,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -215,11 +222,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-lax/go-bucket-test-def/access + url: https://api.linode.com/v4beta/object-storage/buckets/it-mil/go-bucket-test-def/access method: GET response: - body: '{"acl": "private", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL", + body: '{"acl": "private", "acl_xml": "640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89eFULL_CONTROL", "cors_enabled": false, "cors_xml": null}' headers: Access-Control-Allow-Credentials: @@ -245,7 +252,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:45 GMT + - Thu, 30 Apr 2026 20:18:51 GMT Pragma: - no-cache Strict-Transport-Security: @@ -263,7 +270,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -279,7 +286,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-lax-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/it-mil/go-bucket-test-def method: DELETE response: body: '{}' @@ -307,7 +314,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:48 GMT + - Thu, 30 Apr 2026 20:18:54 GMT Pragma: - no-cache Strict-Transport-Security: @@ -324,7 +331,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageBucket_Create.yaml b/test/integration/fixtures/TestObjectStorageBucket_Create.yaml index 2a4753831..02d29e4b8 100644 --- a/test/integration/fixtures/TestObjectStorageBucket_Create.yaml +++ b/test/integration/fixtures/TestObjectStorageBucket_Create.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:02:49 GMT + - Thu, 30 Apr 2026 20:17:59 GMT Pragma: - no-cache Strict-Transport-Security: @@ -59,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -75,7 +75,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: DELETE response: body: '{}' @@ -103,7 +103,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:02:53 GMT + - Thu, 30 Apr 2026 20:18:02 GMT Pragma: - no-cache Strict-Transport-Security: @@ -120,7 +120,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageBucket_GetFound.yaml b/test/integration/fixtures/TestObjectStorageBucket_GetFound.yaml index eb8fb4b5c..3aab50b2f 100644 --- a/test/integration/fixtures/TestObjectStorageBucket_GetFound.yaml +++ b/test/integration/fixtures/TestObjectStorageBucket_GetFound.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:13 GMT + - Thu, 30 Apr 2026 20:18:11 GMT Pragma: - no-cache Strict-Transport-Security: @@ -59,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -75,7 +75,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: GET response: body: '{"hostname": "go-bucket-test-def.us-east-1.linodeobjects.com", "label": @@ -106,7 +106,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:14 GMT + - Thu, 30 Apr 2026 20:18:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -124,7 +124,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -140,7 +140,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: DELETE response: body: '{}' @@ -168,7 +168,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:17 GMT + - Thu, 30 Apr 2026 20:18:15 GMT Pragma: - no-cache Strict-Transport-Security: @@ -185,7 +185,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageBucket_GetMissing.yaml b/test/integration/fixtures/TestObjectStorageBucket_GetMissing.yaml index b5864d11b..adeabb5a6 100644 --- a/test/integration/fixtures/TestObjectStorageBucket_GetMissing.yaml +++ b/test/integration/fixtures/TestObjectStorageBucket_GetMissing.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:07 GMT + - Thu, 30 Apr 2026 20:18:04 GMT Pragma: - no-cache Strict-Transport-Security: @@ -59,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -78,7 +78,8 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets/us-west-1/go-bucket-test-def method: GET response: - body: '{"errors": [{"reason": "Not found"}]}' + body: '{"errors": [{"reason": "The specified region was not found or does not + support Object Storage."}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -93,13 +94,15 @@ interactions: Connection: - keep-alive Content-Length: - - "37" + - "98" Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:07 GMT + - Thu, 30 Apr 2026 20:18:04 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -109,7 +112,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" status: 404 Not Found code: 404 duration: "" @@ -123,7 +126,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: DELETE response: body: '{}' @@ -151,7 +154,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:11 GMT + - Thu, 30 Apr 2026 20:18:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -168,7 +171,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageBucket_Regional.yaml b/test/integration/fixtures/TestObjectStorageBucket_Regional.yaml deleted file mode 100644 index 55aaf10c0..000000000 --- a/test/integration/fixtures/TestObjectStorageBucket_Regional.yaml +++ /dev/null @@ -1,539 +0,0 @@ ---- -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", "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": "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", "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": "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", "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": "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", "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": "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-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": "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": "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": "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-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", "Managed Databases", "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": "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", "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": - "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", "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": - "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": 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", "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": "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": "es-mad", "label": "Madrid, ES", "country": - "es", "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": - "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": 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", "StackScripts", "NETINT Quadra T1U"], "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", "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.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", "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": - "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", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U"], "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", "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": - "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", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U"], "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": "nz-akl-1", "label": "Auckland, NZ", "country": - "nz", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", "Distributed - Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "us-den-1", - "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", "Cloud Firewall", - "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", - "country": "de", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", - "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "fr-mrs-1", - "label": "Marseille, FR", "country": "fr", "capabilities": ["Linodes", "Cloud - Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, - ZA", "country": "za", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", - "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "my-kul-1", - "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", "Cloud - Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", - "country": "co", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", - "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "mx-qro-1", - "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": ["Linodes", - "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", - "country": "us", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", - "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "cl-scl-1", - "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", "Cloud - Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": - "gb", "capabilities": ["Linodes", "Block Storage Encryption", "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": "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": "au-mel", "label": "Melbourne, AU", "country": - "au", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement - Group", "StackScripts", "NETINT Quadra T1U"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans", "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": "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": "de-fra-2", "label": "Frankfurt 2, DE", "country": - "de", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U"], "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": "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": "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", "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": "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-tyo-3", "label": "Tokyo 3, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "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": "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-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", "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": "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-west", "label": "Fremont, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed 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": "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-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", "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": "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-east", "label": "Newark, NJ", "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", "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": "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": "eu-west", - "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Disk Encryption", - "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": "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-south", "label": "Singapore, SG", "country": - "sg", "capabilities": ["Linodes", "Disk Encryption", "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": "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": "eu-central", "label": "Frankfurt, DE", "country": - "de", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block 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": "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 2, JP", "country": - "jp", "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": "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": 41}' - 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, 08 Jan 2025 06:02:53 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: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"region":"us-iad","label":"go-bucket-test-def"}' - form: {} - headers: - Accept: - - application/json - Content-Type: - - application/json - User-Agent: - - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets - method: POST - response: - body: '{"hostname": "go-bucket-test-def.us-iad-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-iad", - "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com"}' - 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: - - Wed, 08 Jan 2025 06:02:55 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-iad/go-bucket-test-def - method: GET - response: - body: '{"hostname": "go-bucket-test-def.us-iad-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-iad", - "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com"}' - 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: - - Wed, 08 Jan 2025 06:02:56 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-iad-1/go-bucket-test-def - 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, 08 Jan 2025 06:03:05 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" diff --git a/test/integration/fixtures/TestObjectStorageBucketsInCluster_List.yaml b/test/integration/fixtures/TestObjectStorageBucketsInCluster_List.yaml deleted file mode 100644 index 9e0cc3b02..000000000 --- a/test/integration/fixtures/TestObjectStorageBucketsInCluster_List.yaml +++ /dev/null @@ -1,193 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"region":"us-east","label":"go-bucket-test-def"}' - form: {} - headers: - Accept: - - application/json - Content-Type: - - application/json - User-Agent: - - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets - method: POST - response: - body: '{"hostname": "go-bucket-test-def.us-east-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-east", - "cluster": "us-east-1", "size": 0, "objects": 0, "endpoint_type": "E0", "s3_endpoint": - "us-east-1.linodeobjects.com"}' - 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: - - Wed, 08 Jan 2025 06:03:28 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-east-1?page=1 - method: GET - response: - body: '{"data": [{"hostname": "go-bucket-test-def.us-east-1.linodeobjects.com", - "label": "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-east", - "cluster": "us-east-1", "size": 0, "objects": 0, "endpoint_type": "E0", "s3_endpoint": - "us-east-1.linodeobjects.com"}], "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: - - "315" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Wed, 08 Jan 2025 06:03:29 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-east-1/go-bucket-test-def - 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, 08 Jan 2025 06:03:33 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" diff --git a/test/integration/fixtures/TestObjectStorageBuckets_List.yaml b/test/integration/fixtures/TestObjectStorageBuckets_List.yaml index 139f14f75..861804cd5 100644 --- a/test/integration/fixtures/TestObjectStorageBuckets_List.yaml +++ b/test/integration/fixtures/TestObjectStorageBuckets_List.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Jan 2025 19:34:04 GMT + - Thu, 30 Apr 2026 20:18:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -59,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -78,50 +78,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets?page=1 method: GET response: - body: '{"data": [{"hostname": "bucket-1736798274052633022.gb-lon-1.linodeobjects.com", - "label": "bucket-1736798274052633022", "created": "2018-01-02T03:04:05", "region": - "gb-lon", "cluster": "", "size": 0, "objects": 0, "endpoint_type": "E3", "s3_endpoint": - "gb-lon-1.linodeobjects.com"}, {"hostname": "bucket-1738000793614673680.gb-lon-1.linodeobjects.com", - "label": "bucket-1738000793614673680", "created": "2018-01-02T03:04:05", "region": - "gb-lon", "cluster": "", "size": 0, "objects": 0, "endpoint_type": "E3", "s3_endpoint": - "gb-lon-1.linodeobjects.com"}, {"hostname": "go-bucket-test-def.us-east-1.linodeobjects.com", + body: '{"data": [{"hostname": "go-bucket-test-def.us-east-1.linodeobjects.com", "label": "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-east", "cluster": "us-east-1", "size": 0, "objects": 0, "endpoint_type": "E0", "s3_endpoint": - "us-east-1.linodeobjects.com"}, {"hostname": "tf-test-1543819153442410267.sg-sin-1.linodeobjects.com", - "label": "tf-test-1543819153442410267", "created": "2018-01-02T03:04:05", "region": - "sg-sin-2", "cluster": "", "size": 0, "objects": 0, "endpoint_type": "E2", "s3_endpoint": - "sg-sin-1.linodeobjects.com"}, {"hostname": "tf-test-2484676038142344857.it-mil-1.linodeobjects.com", - "label": "tf-test-2484676038142344857", "created": "2018-01-02T03:04:05", "region": - "it-mil", "cluster": "it-mil-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "it-mil-1.linodeobjects.com"}, {"hostname": "tf-test-3502349996573909406.us-iad-1.linodeobjects.com", - "label": "tf-test-3502349996573909406", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"hostname": "tf-test-3632911602253826896.gb-lon-1.linodeobjects.com", - "label": "tf-test-3632911602253826896", "created": "2018-01-02T03:04:05", "region": - "gb-lon", "cluster": "", "size": 0, "objects": 0, "endpoint_type": "E3", "s3_endpoint": - "gb-lon-1.linodeobjects.com"}, {"hostname": "tf-test-3691810287020261631.us-iad-1.linodeobjects.com", - "label": "tf-test-3691810287020261631", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"hostname": "tf-test-3847259615974034792.us-iad-1.linodeobjects.com", - "label": "tf-test-3847259615974034792", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"hostname": "tf-test-5629732048996817677.us-iad-1.linodeobjects.com", - "label": "tf-test-5629732048996817677", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"hostname": "tf-test-6566002079784759866.us-iad-1.linodeobjects.com", - "label": "tf-test-6566002079784759866", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"hostname": "tf-test-6680232593917341773.us-iad-1.linodeobjects.com", - "label": "tf-test-6680232593917341773", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}, {"hostname": "tf-test-6921913936824551527.id-cgk-1.linodeobjects.com", - "label": "tf-test-6921913936824551527", "created": "2018-01-02T03:04:05", "region": - "id-cgk", "cluster": "id-cgk-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "id-cgk-1.linodeobjects.com"}, {"hostname": "tf-test-8637208670123446138.us-iad-1.linodeobjects.com", - "label": "tf-test-8637208670123446138", "created": "2018-01-02T03:04:05", "region": - "us-iad", "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", - "s3_endpoint": "us-iad-1.linodeobjects.com"}], "page": 1, "pages": 1, "results": - 14}' + "us-east-1.linodeobjects.com"}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -139,12 +99,14 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive + Content-Length: + - "315" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 30 Jan 2025 19:34:09 GMT + - Thu, 30 Apr 2026 20:18:19 GMT Pragma: - no-cache Strict-Transport-Security: @@ -152,7 +114,6 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter - - Accept-Encoding X-Accepted-Oauth-Scopes: - object_storage:read_only X-Content-Type-Options: @@ -163,7 +124,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -179,7 +140,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: DELETE response: body: '{}' @@ -207,7 +168,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Jan 2025 19:34:13 GMT + - Thu, 30 Apr 2026 20:18:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -224,7 +185,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageClusters_List.yaml b/test/integration/fixtures/TestObjectStorageClusters_List.yaml deleted file mode 100644 index c6df53d93..000000000 --- a/test/integration/fixtures/TestObjectStorageClusters_List.yaml +++ /dev/null @@ -1,114 +0,0 @@ ---- -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/object-storage/clusters?page=1 - method: GET - response: - body: '{"data": [{"id": "us-east-1", "region": "us-east", "status": "available", - "domain": "us-east-1.linodeobjects.com", "static_site_domain": "website-us-east-1.linodeobjects.com"}, - {"id": "eu-central-1", "region": "eu-central", "status": "available", "domain": - "eu-central-1.linodeobjects.com", "static_site_domain": "website-eu-central-1.linodeobjects.com"}, - {"id": "ap-south-1", "region": "ap-south", "status": "available", "domain": - "ap-south-1.linodeobjects.com", "static_site_domain": "website-ap-south-1.linodeobjects.com"}, - {"id": "us-southeast-1", "region": "us-southeast", "status": "available", "domain": - "us-southeast-1.linodeobjects.com", "static_site_domain": "website-us-southeast-1.linodeobjects.com"}, - {"id": "us-iad-1", "region": "us-iad", "status": "available", "domain": "us-iad-1.linodeobjects.com", - "static_site_domain": "website-us-iad-1.linodeobjects.com"}, {"id": "fr-par-1", - "region": "fr-par", "status": "available", "domain": "fr-par-1.linodeobjects.com", - "static_site_domain": "website-fr-par-1.linodeobjects.com"}, {"id": "us-ord-1", - "region": "us-ord", "status": "available", "domain": "us-ord-1.linodeobjects.com", - "static_site_domain": "website-us-ord-1.linodeobjects.com"}, {"id": "in-maa-1", - "region": "in-maa", "status": "available", "domain": "in-maa-1.linodeobjects.com", - "static_site_domain": "website-in-maa-1.linodeobjects.com"}, {"id": "se-sto-1", - "region": "se-sto", "status": "available", "domain": "se-sto-1.linodeobjects.com", - "static_site_domain": "website-se-sto-1.linodeobjects.com"}, {"id": "it-mil-1", - "region": "it-mil", "status": "available", "domain": "it-mil-1.linodeobjects.com", - "static_site_domain": "website-it-mil-1.linodeobjects.com"}, {"id": "us-sea-1", - "region": "us-sea", "status": "available", "domain": "us-sea-1.linodeobjects.com", - "static_site_domain": "website-us-sea-1.linodeobjects.com"}, {"id": "id-cgk-1", - "region": "id-cgk", "status": "available", "domain": "id-cgk-1.linodeobjects.com", - "static_site_domain": "website-id-cgk-1.linodeobjects.com"}, {"id": "jp-osa-1", - "region": "jp-osa", "status": "available", "domain": "jp-osa-1.linodeobjects.com", - "static_site_domain": "website-jp-osa-1.linodeobjects.com"}, {"id": "br-gru-1", - "region": "br-gru", "status": "available", "domain": "br-gru-1.linodeobjects.com", - "static_site_domain": "website-br-gru-1.linodeobjects.com"}, {"id": "us-lax-1", - "region": "us-lax", "status": "available", "domain": "us-lax-1.linodeobjects.com", - "static_site_domain": "website-us-lax-1.linodeobjects.com"}, {"id": "nl-ams-1", - "region": "nl-ams", "status": "available", "domain": "nl-ams-1.linodeobjects.com", - "static_site_domain": "website-nl-ams-1.linodeobjects.com"}, {"id": "us-mia-1", - "region": "us-mia", "status": "available", "domain": "us-mia-1.linodeobjects.com", - "static_site_domain": "website-us-mia-1.linodeobjects.com"}, {"id": "es-mad-1", - "region": "es-mad", "status": "available", "domain": "es-mad-1.linodeobjects.com", - "static_site_domain": "website-es-mad-1.linodeobjects.com"}, {"id": "us-iad-10", - "region": "us-iad", "status": "available", "domain": "us-iad-10.linodeobjects.com", - "static_site_domain": "website-us-iad-10.linodeobjects.com"}, {"id": "us-sea-9", - "region": "us-sea", "status": "hidden", "domain": "us-sea-9.linodeobjects.com", - "static_site_domain": "website-us-sea-9.linodeobjects.com"}, {"id": "au-mel-1", - "region": "au-mel", "status": "hidden", "domain": "au-mel-1.linodeobjects.com", - "static_site_domain": "website-au-mel-1.linodeobjects.com"}, {"id": "gb-lon-1", - "region": "gb-lon", "status": "hidden", "domain": "gb-lon-1.linodeobjects.com", - "static_site_domain": "website-gb-lon-1.linodeobjects.com"}, {"id": "in-bom-1", - "region": "in-bom-2", "status": "hidden", "domain": "in-bom-1.linodeobjects.com", - "static_site_domain": "website-in-bom-1.linodeobjects.com"}, {"id": "de-fra-1", - "region": "de-fra-2", "status": "hidden", "domain": "de-fra-1.linodeobjects.com", - "static_site_domain": "website-de-fra-1.linodeobjects.com"}, {"id": "sg-sin-1", - "region": "sg-sin-2", "status": "hidden", "domain": "sg-sin-1.linodeobjects.com", - "static_site_domain": "website-sg-sin-1.linodeobjects.com"}], "page": 1, "pages": - 1, "results": 25}' - 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, 08 Jan 2025 06:03:49 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" diff --git a/test/integration/fixtures/TestObjectStorageKey_GetFound.yaml b/test/integration/fixtures/TestObjectStorageKey_GetFound.yaml index eded32ffc..df3671b78 100644 --- a/test/integration/fixtures/TestObjectStorageKey_GetFound.yaml +++ b/test/integration/fixtures/TestObjectStorageKey_GetFound.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 1654583, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3498033, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, @@ -30,9 +30,11 @@ interactions: "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-4.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}' headers: @@ -57,7 +59,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:51 GMT + - Thu, 30 Apr 2026 20:18:59 GMT Pragma: - no-cache Strict-Transport-Security: @@ -75,7 +77,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -91,10 +93,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654583 + url: https://api.linode.com/v4beta/object-storage/keys/3498033 method: GET response: - body: '{"id": 1654583, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3498033, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[REDACTED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, @@ -110,9 +112,11 @@ interactions: "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-4.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}' headers: @@ -137,7 +141,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:52 GMT + - Thu, 30 Apr 2026 20:19:00 GMT Pragma: - no-cache Strict-Transport-Security: @@ -156,7 +160,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -172,7 +176,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654583 + url: https://api.linode.com/v4beta/object-storage/keys/3498033 method: DELETE response: body: '{}' @@ -200,7 +204,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:53 GMT + - Thu, 30 Apr 2026 20:19:01 GMT Pragma: - no-cache Strict-Transport-Security: @@ -217,7 +221,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageKey_GetMissing.yaml b/test/integration/fixtures/TestObjectStorageKey_GetMissing.yaml index 3ed97bae6..65eabaefb 100644 --- a/test/integration/fixtures/TestObjectStorageKey_GetMissing.yaml +++ b/test/integration/fixtures/TestObjectStorageKey_GetMissing.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys/123 method: GET response: - body: '{"errors": [{"reason": "Not found"}]}' + body: '{"errors": [{"reason": "The specified access key was not found."}]}' headers: Access-Control-Allow-Headers: - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter @@ -29,13 +29,15 @@ interactions: Connection: - keep-alive Content-Length: - - "37" + - "67" Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:49 GMT + - Thu, 30 Apr 2026 20:18:55 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -45,7 +47,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" status: 404 Not Found code: 404 duration: "" diff --git a/test/integration/fixtures/TestObjectStorageKey_List.yaml b/test/integration/fixtures/TestObjectStorageKey_List.yaml index 8d76c9713..7d1eb9587 100644 --- a/test/integration/fixtures/TestObjectStorageKey_List.yaml +++ b/test/integration/fixtures/TestObjectStorageKey_List.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 1654585, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3498036, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, @@ -30,9 +30,11 @@ interactions: "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-4.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}' headers: @@ -57,7 +59,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:59 GMT + - Thu, 30 Apr 2026 20:19:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -75,7 +77,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -94,7 +96,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys?page=1 method: GET response: - body: '{"pages": 1, "page": 1, "results": 1, "data": [{"id": 1654585, "label": + body: '{"pages": 1, "page": 1, "results": 1, "data": [{"id": 3498036, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[REDACTED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": @@ -110,9 +112,11 @@ interactions: "se-sto-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": - "us-lax-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-mia", "s3_endpoint": + "us-lax-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": + "us-lax-4.linodeobjects.com", "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": - "us-ord-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-sea", "s3_endpoint": + "us-ord-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": + "us-ord-10.linodeobjects.com", "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}]}' headers: @@ -137,7 +141,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:00 GMT + - Thu, 30 Apr 2026 20:19:13 GMT Pragma: - no-cache Strict-Transport-Security: @@ -156,7 +160,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -172,7 +176,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654585 + url: https://api.linode.com/v4beta/object-storage/keys/3498036 method: DELETE response: body: '{}' @@ -200,7 +204,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:01 GMT + - Thu, 30 Apr 2026 20:19:15 GMT Pragma: - no-cache Strict-Transport-Security: @@ -217,7 +221,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageKey_Update.yaml b/test/integration/fixtures/TestObjectStorageKey_Update.yaml index f9804cc6b..738b51c19 100644 --- a/test/integration/fixtures/TestObjectStorageKey_Update.yaml +++ b/test/integration/fixtures/TestObjectStorageKey_Update.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 1654584, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3498035, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, @@ -30,9 +30,11 @@ interactions: "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-4.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}' headers: @@ -57,7 +59,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:55 GMT + - Thu, 30 Apr 2026 20:19:06 GMT Pragma: - no-cache Strict-Transport-Security: @@ -75,7 +77,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -91,10 +93,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654584 + url: https://api.linode.com/v4beta/object-storage/keys/3498035 method: PUT response: - body: '{"id": 1654584, "label": "go-test-def_r", "access_key": "[SANITIZED]", + body: '{"id": 3498035, "label": "go-test-def_r", "access_key": "[SANITIZED]", "secret_key": "[REDACTED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": @@ -110,9 +112,11 @@ interactions: "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-4.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-1.linodeobjects.com", - "endpoint_type": "E1"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}' headers: @@ -137,7 +141,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:56 GMT + - Thu, 30 Apr 2026 20:19:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -155,7 +159,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -171,7 +175,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654584 + url: https://api.linode.com/v4beta/object-storage/keys/3498035 method: DELETE response: body: '{}' @@ -199,7 +203,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:03:57 GMT + - Thu, 30 Apr 2026 20:19:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -216,7 +220,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml b/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml index 1b0984136..bc2b65b14 100644 --- a/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml +++ b/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"label":"go-test-def","bucket_access":[{"cluster":"us-east-1","region":"us-east","bucket_name":"go-bucket-test-def","permissions":"read_only"},{"cluster":"us-east-1","region":"us-east","bucket_name":"go-bucket-test-def","permissions":"read_write"}]}' + body: '{"label":"go-test-def","bucket_access":[{"region":"us-east","bucket_name":"go-bucket-test-def","permissions":"read_only"},{"region":"us-east","bucket_name":"go-bucket-test-def","permissions":"read_write"}]}' form: {} headers: Accept: @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 1654586, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3498038, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": true, "bucket_access": [{"cluster": "us-east-1", "bucket_name": "go-bucket-test-def", "permissions": "read_only", "region": "us-east"}, {"cluster": "us-east-1", "bucket_name": "go-bucket-test-def", "permissions": "read_write", @@ -44,7 +44,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:05 GMT + - Thu, 30 Apr 2026 20:19:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -61,7 +61,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -77,7 +77,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654586 + url: https://api.linode.com/v4beta/object-storage/keys/3498038 method: DELETE response: body: '{}' @@ -105,7 +105,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:07 GMT + - Thu, 30 Apr 2026 20:19:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -122,7 +122,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml b/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml index 1c01b5723..59b573519 100644 --- a/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml +++ b/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:03 GMT + - Thu, 30 Apr 2026 20:19:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -59,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -75,7 +75,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: DELETE response: body: '{}' @@ -103,7 +103,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:10 GMT + - Thu, 30 Apr 2026 20:19:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -120,7 +120,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml b/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml index b43393d9d..eec661585 100644 --- a/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml +++ b/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml @@ -14,292 +14,377 @@ interactions: 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", "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", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed + Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": 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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": 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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-mia", + "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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", "Managed Databases", "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "br-gru", "label": "Sao Paulo, BR", "country": - "br", "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": - "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "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", "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "gb-lon", + "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": 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", "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": - "es", "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": - "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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": "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", "StackScripts", "NETINT Quadra T1U"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "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", "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.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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": "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", "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": - "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": "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", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "no-osl-1", + "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage + Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC + Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", "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", "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": - "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC + Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", "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", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U"], "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": "nz-akl-1", "label": "Auckland, NZ", "country": - "nz", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", "Distributed - Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "us-den-1", - "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", "Cloud Firewall", - "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", - "country": "de", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", - "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "fr-mrs-1", - "label": "Marseille, FR", "country": "fr", "capabilities": ["Linodes", "Cloud - Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, - ZA", "country": "za", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", - "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "my-kul-1", - "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", "Cloud - Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", - "country": "co", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", - "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "mx-qro-1", - "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": ["Linodes", - "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", - "country": "us", "capabilities": ["Linodes", "Cloud Firewall", "Vlans", "Metadata", - "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0}, "site_type": "distributed"}, {"id": "cl-scl-1", - "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", "Cloud - Firewall", "Vlans", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": - "gb", "capabilities": ["Linodes", "Block Storage Encryption", "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": "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": "au-mel", "label": "Melbourne, AU", "country": - "au", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement - Group", "StackScripts", "NETINT Quadra T1U"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans", "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "status": "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": - "de", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": 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", "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "jp-tyo-3", "label": "Tokyo 3, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "us-central", "label": "Dallas, TX", "country": - "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts"], "status": + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", + "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 + Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", + "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed 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": "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-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", "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": "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-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block 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": "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": "eu-west", - "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts"], + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-south", "label": "Singapore, SG", "country": - "sg", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "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", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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": "eu-central", "label": "Frankfurt, DE", "country": - "de", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block 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", + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": - "jp", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "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": "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": 41}' + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 34}' headers: Access-Control-Allow-Credentials: - "true" @@ -322,7 +407,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:11 GMT + - Thu, 30 Apr 2026 20:19:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -341,14 +426,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"us-iad","label":"go-bucket-test-def"}' + body: '{"region":"au-mel","label":"go-bucket-test-defgo-test-def-regional"}' form: {} headers: Accept: @@ -360,10 +445,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets method: POST response: - body: '{"hostname": "go-bucket-test-def.us-iad-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-iad", - "cluster": "us-iad-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com"}' + body: '{"hostname": "go-bucket-test-defgo-test-def-regional.au-mel-1.linodeobjects.com", + "label": "go-bucket-test-defgo-test-def-regional", "created": "2018-01-02T03:04:05", + "region": "au-mel", "cluster": "", "size": 0, "objects": 0, "endpoint_type": + "E2", "s3_endpoint": "au-mel-1.linodeobjects.com"}' headers: Access-Control-Allow-Credentials: - "true" @@ -382,13 +467,13 @@ interactions: Connection: - keep-alive Content-Length: - - "262" + - "294" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:13 GMT + - Thu, 30 Apr 2026 20:19:31 GMT Pragma: - no-cache Strict-Transport-Security: @@ -405,14 +490,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"go-test-def","bucket_access":[{"region":"us-iad","bucket_name":"go-bucket-test-def","permissions":"read_only"}],"regions":["us-iad"]}' + body: '{"label":"go-test-def","bucket_access":[{"region":"au-mel","bucket_name":"go-bucket-test-defgo-test-def-regional","permissions":"read_only"}],"regions":["au-mel"]}' form: {} headers: Accept: @@ -424,11 +509,11 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 1654587, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": - "[SANITIZED]", "limited": true, "bucket_access": [{"cluster": "us-iad-1", "bucket_name": - "go-bucket-test-def", "permissions": "read_only", "region": "us-iad"}], "regions": - [{"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": - "E1"}]}' + body: '{"id": 3498041, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + "[SANITIZED]", "limited": true, "bucket_access": [{"cluster": "", "bucket_name": + "go-bucket-test-defgo-test-def-regional", "permissions": "read_only", "region": + "au-mel"}], "regions": [{"id": "au-mel", "s3_endpoint": "au-mel-1.linodeobjects.com", + "endpoint_type": "E2"}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -447,13 +532,13 @@ interactions: Connection: - keep-alive Content-Length: - - "380" + - "392" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:14 GMT + - Thu, 30 Apr 2026 20:19:37 GMT Pragma: - no-cache Strict-Transport-Security: @@ -470,14 +555,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"regions":["us-iad","us-mia"]}' + body: '{"regions":["au-mel","us-mia"]}' form: {} headers: Accept: @@ -486,15 +571,15 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654587 + url: https://api.linode.com/v4beta/object-storage/keys/3498041 method: PUT response: - body: '{"id": 1654587, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": - "[REDACTED]", "limited": true, "bucket_access": [{"cluster": "us-iad-1", "bucket_name": - "go-bucket-test-def", "permissions": "read_only", "region": "us-iad"}], "regions": - [{"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", "endpoint_type": - "E1"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", "endpoint_type": - "E1"}]}' + body: '{"id": 3498041, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + "[REDACTED]", "limited": true, "bucket_access": [{"cluster": "", "bucket_name": + "go-bucket-test-defgo-test-def-regional", "permissions": "read_only", "region": + "au-mel"}], "regions": [{"id": "au-mel", "s3_endpoint": "au-mel-1.linodeobjects.com", + "endpoint_type": "E2"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -513,13 +598,13 @@ interactions: Connection: - keep-alive Content-Length: - - "436" + - "448" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:15 GMT + - Thu, 30 Apr 2026 20:19:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -536,7 +621,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -552,7 +637,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/1654587 + url: https://api.linode.com/v4beta/object-storage/keys/3498041 method: DELETE response: body: '{}' @@ -580,7 +665,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:16 GMT + - Thu, 30 Apr 2026 20:19:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -597,7 +682,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -613,7 +698,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-iad-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/au-mel/go-bucket-test-defgo-test-def-regional method: DELETE response: body: '{}' @@ -641,7 +726,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 06:04:29 GMT + - Thu, 30 Apr 2026 20:19:51 GMT Pragma: - no-cache Strict-Transport-Security: @@ -658,7 +743,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Delete.yaml b/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Delete.yaml index 868fe0b01..3e0b2f5c8 100644 --- a/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Delete.yaml +++ b/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Delete.yaml @@ -5,7 +5,7 @@ interactions: body: "" form: {} headers: {} - url: https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=q40b1QCD%2FE5YyfsAW%2Fl5vZNfiRs%3D&Expires=1736322799&AWSAccessKeyID=SANITIZED + url: https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=AR8zXFhZ7YiFXg5d92BWdbftFNk%3D&Expires=1777580764&AWSAccessKeyID=SANITIZED method: DELETE response: body: "" @@ -13,7 +13,7 @@ interactions: Connection: - keep-alive X-Amz-Request-Id: - - tx000003f312b97ed86260d-00677e2d87-f1a4821b-default + - tx00000d61d93b8872788f2-0069f3b974-18c2cc906-default status: 204 No Content code: 204 duration: "" diff --git a/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Put.yaml b/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Put.yaml index 5d7ccf6ad..74d078e75 100644 --- a/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Put.yaml +++ b/test/integration/fixtures/TestObjectStorageObject_ACLConfig_Bucket_Put.yaml @@ -7,7 +7,7 @@ interactions: headers: Content-Type: - text/plain - url: https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=UZqhNnak%2FwLVHy0HB2TW87rl%2Baw%3D&Expires=1736322791&AWSAccessKeyID=SANITIZED + url: https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=uVC0ROXSh0pzdkwt%2FSF6aO8sSUE%3D&Expires=1777580757&AWSAccessKeyID=SANITIZED method: PUT response: body: "" @@ -21,7 +21,7 @@ interactions: Etag: - '"7f2ababa423061c509f4923dd04b6cf1"' X-Amz-Request-Id: - - tx000003d8b04716d761fbb-00677e2d7f-ef83577d-default + - tx00000a96d0bdfc69b8814-0069f3b96d-18c2db3f1-default status: 200 OK code: 200 duration: "" diff --git a/test/integration/fixtures/TestObjectStorageObject_Smoke.yaml b/test/integration/fixtures/TestObjectStorageObject_Smoke.yaml index 5898e1fd9..17e6e4c1e 100644 --- a/test/integration/fixtures/TestObjectStorageObject_Smoke.yaml +++ b/test/integration/fixtures/TestObjectStorageObject_Smoke.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:09 GMT + - Thu, 30 Apr 2026 20:19:55 GMT Pragma: - no-cache Strict-Transport-Security: @@ -59,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "60" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -75,10 +75,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-url + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def/object-url method: POST response: - body: '{"url": "https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=UZqhNnak%2FwLVHy0HB2TW87rl%2Baw%3D&Expires=1736322791&AWSAccessKeyID=SANITIZED", + body: '{"url": "https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=uVC0ROXSh0pzdkwt%2FSF6aO8sSUE%3D&Expires=1777580757&AWSAccessKeyID=SANITIZED", "exists": false}' headers: Access-Control-Allow-Credentials: @@ -98,13 +98,13 @@ interactions: Connection: - keep-alive Content-Length: - - "191" + - "189" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:11 GMT + - Thu, 30 Apr 2026 20:19:57 GMT Pragma: - no-cache Strict-Transport-Security: @@ -121,7 +121,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -137,11 +137,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-acl?name=test + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def/object-acl?name=test method: GET response: - body: '{"acl": "private", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL"}' + body: '{"acl": "private", "acl_xml": "640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89eFULL_CONTROL"}' headers: Access-Control-Allow-Credentials: - "true" @@ -166,7 +166,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:12 GMT + - Thu, 30 Apr 2026 20:19:58 GMT Pragma: - no-cache Strict-Transport-Security: @@ -184,7 +184,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -200,74 +200,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-acl?name=test + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def/object-list method: GET response: - body: '{"acl": "private", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL"}' - 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: - - "550" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Wed, 08 Jan 2025 07:47:13 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-east-1/go-bucket-test-def/object-list - method: GET - response: - body: '{"data": [{"name": "test", "size": 10, "last_modified": "2018-01-02T03:04:05.723Z", - "etag": "7f2ababa423061c509f4923dd04b6cf1", "owner": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936"}], + body: '{"data": [{"name": "test", "size": 10, "last_modified": "2018-01-02T03:04:05.368Z", + "etag": "7f2ababa423061c509f4923dd04b6cf1", "owner": "640757b5-ebe9-45b1-abd5-581f215ef89e"}], "next_marker": null, "is_truncated": false}' headers: Access-Control-Allow-Credentials: @@ -293,7 +230,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:14 GMT + - Thu, 30 Apr 2026 20:19:59 GMT Pragma: - no-cache Strict-Transport-Security: @@ -311,7 +248,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -327,7 +264,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-acl + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def/object-acl method: PUT response: body: '{}' @@ -355,7 +292,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:15 GMT + - Thu, 30 Apr 2026 20:20:00 GMT Pragma: - no-cache Strict-Transport-Security: @@ -372,132 +309,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"name":"test","acl":"public-read"}' - form: {} - headers: - Accept: - - application/json - Content-Type: - - application/json - User-Agent: - - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-acl - method: PUT - 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, 08 Jan 2025 07:47:16 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/object-storage/buckets/us-east-1/go-bucket-test-def/object-acl?name=test - method: GET - response: - body: '{"acl": "public-read", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936http://acs.amazonaws.com/groups/global/AllUsersREADc9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL"}' - 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: - - "750" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Wed, 08 Jan 2025 07:47:17 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - object_storage:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -513,12 +325,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-acl?name=test + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def/object-acl?name=test method: GET response: - body: '{"acl": "public-read", "acl_xml": "c9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89ehttp://acs.amazonaws.com/groups/global/AllUsersREADc9539a32-3ece-47dd-a9a4-40bbfa5a2936c9539a32-3ece-47dd-a9a4-40bbfa5a2936FULL_CONTROL"}' + xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\">640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89eFULL_CONTROL"}' headers: Access-Control-Allow-Credentials: - "true" @@ -543,7 +355,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:17 GMT + - Thu, 30 Apr 2026 20:20:02 GMT Pragma: - no-cache Strict-Transport-Security: @@ -561,7 +373,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -577,10 +389,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def/object-url + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def/object-url method: POST response: - body: '{"url": "https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=q40b1QCD%2FE5YyfsAW%2Fl5vZNfiRs%3D&Expires=1736322799&AWSAccessKeyID=SANITIZED", + body: '{"url": "https://us-east-1.linodeobjects.com:443/go-bucket-test-def/test?Signature=AR8zXFhZ7YiFXg5d92BWdbftFNk%3D&Expires=1777580764&AWSAccessKeyID=SANITIZED", "exists": true}' headers: Access-Control-Allow-Credentials: @@ -600,13 +412,13 @@ interactions: Connection: - keep-alive Content-Length: - - "190" + - "186" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:19 GMT + - Thu, 30 Apr 2026 20:20:04 GMT Pragma: - no-cache Strict-Transport-Security: @@ -623,7 +435,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -639,7 +451,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/us-east-1/go-bucket-test-def + url: https://api.linode.com/v4beta/object-storage/buckets/us-east/go-bucket-test-def method: DELETE response: body: '{}' @@ -667,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 08 Jan 2025 07:47:22 GMT + - Thu, 30 Apr 2026 20:20:06 GMT Pragma: - no-cache Strict-Transport-Security: @@ -684,7 +496,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageQuotaUsage_Get.yaml b/test/integration/fixtures/TestObjectStorageQuotaUsage_Get.yaml index 04a756093..e464dd380 100644 --- a/test/integration/fixtures/TestObjectStorageQuotaUsage_Get.yaml +++ b/test/integration/fixtures/TestObjectStorageQuotaUsage_Get.yaml @@ -39,7 +39,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 24 Apr 2025 17:38:48 GMT + - Thu, 30 Apr 2026 20:20:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -57,7 +57,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageQuotas_Get.yaml b/test/integration/fixtures/TestObjectStorageQuotas_Get.yaml index ee0134099..ec1048429 100644 --- a/test/integration/fixtures/TestObjectStorageQuotas_Get.yaml +++ b/test/integration/fixtures/TestObjectStorageQuotas_Get.yaml @@ -14,10 +14,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/quotas/obj-objects-us-ord-1.linodeobjects.com method: GET response: - body: '{"quota_id": "obj-objects-us-ord-1.linodeobjects.com", "quota_name": "max_objects", - "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com", "description": - "Maximum number of objects this customer is allowed to have on this endpoint", - "quota_limit": 100000000, "resource_metric": "object", "quota_type": "obj-objects", + body: '{"quota_id": "obj-objects-us-ord-1.linodeobjects.com", "quota_name": "Number + of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": + "us-ord-1.linodeobjects.com", "description": "Current number of objects per + account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", "has_usage": true}' headers: Access-Control-Allow-Credentials: @@ -37,13 +37,13 @@ interactions: Connection: - keep-alive Content-Length: - - "300" + - "330" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 24 Apr 2025 17:38:46 GMT + - Thu, 30 Apr 2026 20:20:06 GMT Pragma: - no-cache Strict-Transport-Security: @@ -61,7 +61,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestObjectStorageQuotas_List.yaml b/test/integration/fixtures/TestObjectStorageQuotas_List.yaml index 7941017e8..012e45f5d 100644 --- a/test/integration/fixtures/TestObjectStorageQuotas_List.yaml +++ b/test/integration/fixtures/TestObjectStorageQuotas_List.yaml @@ -14,29 +14,17 @@ interactions: url: https://api.linode.com/v4beta/object-storage/quotas?page=1 method: GET response: - body: '{"data": [{"quota_id": "obj-bytes-br-gru-1.linodeobjects.com", "quota_name": + body: '{"data": [{"quota_id": "obj-bytes-us-mia-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": - "br-gru-1.linodeobjects.com", "description": "Current total capacity per account, + "us-mia-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-br-gru-1.linodeobjects.com", "quota_name": + true}, {"quota_id": "obj-objects-us-mia-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": - "br-gru-1.linodeobjects.com", "description": "Current number of objects per + "us-mia-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-br-gru-1.linodeobjects.com", "quota_name": + "has_usage": true}, {"quota_id": "obj-buckets-us-mia-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": - "br-gru-1.linodeobjects.com", "description": "Current number of buckets per - account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-us-sea-1.linodeobjects.com", "quota_name": "Total - Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": - "us-sea-1.linodeobjects.com", "description": "Current total capacity per account, - per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-us-sea-1.linodeobjects.com", "quota_name": - "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": - "us-sea-1.linodeobjects.com", "description": "Current number of objects per - account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-us-sea-1.linodeobjects.com", "quota_name": - "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": - "us-sea-1.linodeobjects.com", "description": "Current number of buckets per + "us-mia-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": true}, {"quota_id": "obj-bytes-id-cgk-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": @@ -50,41 +38,17 @@ interactions: "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-us-iad-1.linodeobjects.com", "quota_name": "Total - Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com", "description": "Current total capacity per account, - per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-us-iad-1.linodeobjects.com", "quota_name": - "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com", "description": "Current number of objects per - account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-us-iad-1.linodeobjects.com", "quota_name": - "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": - "us-iad-1.linodeobjects.com", "description": "Current number of buckets per - account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-es-mad-1.linodeobjects.com", "quota_name": "Total + true}, {"quota_id": "obj-bytes-br-gru-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": - "es-mad-1.linodeobjects.com", "description": "Current total capacity per account, + "br-gru-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-es-mad-1.linodeobjects.com", "quota_name": + true}, {"quota_id": "obj-objects-br-gru-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": - "es-mad-1.linodeobjects.com", "description": "Current number of objects per + "br-gru-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-es-mad-1.linodeobjects.com", "quota_name": + "has_usage": true}, {"quota_id": "obj-buckets-br-gru-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": - "es-mad-1.linodeobjects.com", "description": "Current number of buckets per - account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-no-osl-1.linodeobjects.com", "quota_name": "Total - Capacity", "quota_type": "obj-bytes", "endpoint_type": "E2", "s3_endpoint": - "no-osl-1.linodeobjects.com", "description": "Current total capacity per account, - per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-no-osl-1.linodeobjects.com", "quota_name": - "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E2", "s3_endpoint": - "no-osl-1.linodeobjects.com", "description": "Current number of objects per - account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-no-osl-1.linodeobjects.com", "quota_name": - "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E2", "s3_endpoint": - "no-osl-1.linodeobjects.com", "description": "Current number of buckets per + "br-gru-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-ord-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": @@ -98,115 +62,145 @@ interactions: "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-us-lax-1.linodeobjects.com", "quota_name": "Total + true}, {"quota_id": "obj-bytes-se-sto-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": - "us-lax-1.linodeobjects.com", "description": "Current total capacity per account, + "se-sto-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-us-lax-1.linodeobjects.com", "quota_name": + true}, {"quota_id": "obj-objects-se-sto-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": - "us-lax-1.linodeobjects.com", "description": "Current number of objects per + "se-sto-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-us-lax-1.linodeobjects.com", "quota_name": + "has_usage": true}, {"quota_id": "obj-buckets-se-sto-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": - "us-lax-1.linodeobjects.com", "description": "Current number of buckets per + "se-sto-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-it-mil-1.linodeobjects.com", "quota_name": "Total + true}, {"quota_id": "obj-bytes-jp-osa-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": - "it-mil-1.linodeobjects.com", "description": "Current total capacity per account, + "jp-osa-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": - true}, {"quota_id": "obj-objects-it-mil-1.linodeobjects.com", "quota_name": + true}, {"quota_id": "obj-objects-jp-osa-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": - "it-mil-1.linodeobjects.com", "description": "Current number of objects per + "jp-osa-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", - "has_usage": true}, {"quota_id": "obj-buckets-it-mil-1.linodeobjects.com", "quota_name": + "has_usage": true}, {"quota_id": "obj-buckets-jp-osa-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": - "it-mil-1.linodeobjects.com", "description": "Current number of buckets per + "jp-osa-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": - true}, {"quota_id": "obj-bytes-us-southeast-1.linodeobjects.com", "quota_name": - "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E0", "s3_endpoint": - "us-southeast-1.linodeobjects.com", "description": "Current total capacity per - account, per endpoint", "quota_limit": 5497558138880, "resource_metric": "byte", - "has_usage": true}, {"quota_id": "obj-objects-us-southeast-1.linodeobjects.com", - "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com", "description": "Current - number of objects per account, per endpoint", "quota_limit": 50000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-us-southeast-1.linodeobjects.com", - "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com", "description": "Current - number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-ap-south-1.linodeobjects.com", - "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E0", "s3_endpoint": "ap-south-1.linodeobjects.com", "description": "Current - total capacity per account, per endpoint", "quota_limit": 5497558138880, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-ap-south-1.linodeobjects.com", - "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E0", "s3_endpoint": "ap-south-1.linodeobjects.com", "description": "Current - number of objects per account, per endpoint", "quota_limit": 50000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-ap-south-1.linodeobjects.com", - "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E0", "s3_endpoint": "ap-south-1.linodeobjects.com", "description": "Current - number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-jp-osa-1.linodeobjects.com", + true}, {"quota_id": "obj-bytes-nl-ams-1.linodeobjects.com", "quota_name": "Total + Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": + "nl-ams-1.linodeobjects.com", "description": "Current total capacity per account, + per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": + true}, {"quota_id": "obj-objects-nl-ams-1.linodeobjects.com", "quota_name": + "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": + "nl-ams-1.linodeobjects.com", "description": "Current number of objects per + account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", + "has_usage": true}, {"quota_id": "obj-buckets-nl-ams-1.linodeobjects.com", "quota_name": + "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": + "nl-ams-1.linodeobjects.com", "description": "Current number of buckets per + account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": + true}, {"quota_id": "obj-bytes-us-lax-4.linodeobjects.com", "quota_name": "Total + Capacity", "quota_type": "obj-bytes", "endpoint_type": "E3", "s3_endpoint": + "us-lax-4.linodeobjects.com", "description": "Current total capacity per account, + per endpoint", "quota_limit": 549755813888000, "resource_metric": "byte", "has_usage": + true}, {"quota_id": "obj-objects-us-lax-4.linodeobjects.com", "quota_name": + "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E3", "s3_endpoint": + "us-lax-4.linodeobjects.com", "description": "Current number of objects per + account, per endpoint", "quota_limit": 500000000, "resource_metric": "object", + "has_usage": true}, {"quota_id": "obj-buckets-us-lax-4.linodeobjects.com", "quota_name": + "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E3", "s3_endpoint": + "us-lax-4.linodeobjects.com", "description": "Current number of buckets per + account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": + true}, {"quota_id": "obj-total-ingress-throughput-us-lax-4.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-us-lax-4.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": "Current total + egress bandwidth per account, per endpoint", "quota_limit": 1250000000, "resource_metric": + "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-us-lax-4.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-us-lax-4.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": "Current egress + bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-au-mel-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com", "description": "Current total + "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-jp-osa-1.linodeobjects.com", + "byte", "has_usage": true}, {"quota_id": "obj-objects-au-mel-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com", "description": "Current number + "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-jp-osa-1.linodeobjects.com", + "object", "has_usage": true}, {"quota_id": "obj-buckets-au-mel-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com", "description": "Current number + "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-east-1.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-total-ingress-throughput-au-mel-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-au-mel-1.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current total + egress bandwidth per account, per endpoint", "quota_limit": 1250000000, "resource_metric": + "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-au-mel-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-au-mel-1.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current egress + bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-eu-central-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E0", "s3_endpoint": "us-east-1.linodeobjects.com", "description": "Current + "E0", "s3_endpoint": "eu-central-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 5497558138880, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-us-east-1.linodeobjects.com", + "byte", "has_usage": true}, {"quota_id": "obj-objects-eu-central-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E0", "s3_endpoint": "us-east-1.linodeobjects.com", "description": "Current + "E0", "s3_endpoint": "eu-central-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 50000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-us-east-1.linodeobjects.com", + "object", "has_usage": true}, {"quota_id": "obj-buckets-eu-central-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E0", "s3_endpoint": "us-east-1.linodeobjects.com", "description": "Current + "E0", "s3_endpoint": "eu-central-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-fr-par-1.linodeobjects.com", - "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E1", "s3_endpoint": "fr-par-1.linodeobjects.com", "description": "Current total - capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-fr-par-1.linodeobjects.com", - "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E1", "s3_endpoint": "fr-par-1.linodeobjects.com", "description": "Current number - of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-fr-par-1.linodeobjects.com", - "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E1", "s3_endpoint": "fr-par-1.linodeobjects.com", "description": "Current number - of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-se-sto-1.linodeobjects.com", - "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E1", "s3_endpoint": "se-sto-1.linodeobjects.com", "description": "Current total - capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-se-sto-1.linodeobjects.com", - "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E1", "s3_endpoint": "se-sto-1.linodeobjects.com", "description": "Current number - of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-se-sto-1.linodeobjects.com", - "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E1", "s3_endpoint": "se-sto-1.linodeobjects.com", "description": "Current number - of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-nl-ams-1.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-ord-10.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com", "description": "Current total - capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-nl-ams-1.linodeobjects.com", + "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current + total capacity per account, per endpoint", "quota_limit": 549755813888000, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-us-ord-10.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com", "description": "Current number - of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-nl-ams-1.linodeobjects.com", + "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current + number of objects per account, per endpoint", "quota_limit": 500000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-us-ord-10.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com", "description": "Current number - of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-gb-lon-1.linodeobjects.com", + "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current + number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "bucket", "has_usage": true}, {"quota_id": "obj-total-ingress-throughput-us-ord-10.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-us-ord-10.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current + total egress bandwidth per account, per endpoint", "quota_limit": 1250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-us-ord-10.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-us-ord-10.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current + egress bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-gb-lon-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 549755813888000, "resource_metric": @@ -218,19 +212,25 @@ interactions: "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-au-mel-1.linodeobjects.com", - "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current total - capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-au-mel-1.linodeobjects.com", - "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current number - of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-au-mel-1.linodeobjects.com", - "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E2", "s3_endpoint": "au-mel-1.linodeobjects.com", "description": "Current number - of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-in-maa-1.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-total-ingress-throughput-gb-lon-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-gb-lon-1.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com", "description": "Current total + egress bandwidth per account, per endpoint", "quota_limit": 1250000000, "resource_metric": + "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-gb-lon-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-gb-lon-1.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com", "description": "Current egress + bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-in-maa-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": @@ -242,42 +242,90 @@ interactions: "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-jp-tyo-1.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-de-fra-1.linodeobjects.com", + "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": + "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": "Current total + capacity per account, per endpoint", "quota_limit": 549755813888000, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-de-fra-1.linodeobjects.com", + "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": + "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": "Current number + of objects per account, per endpoint", "quota_limit": 500000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-de-fra-1.linodeobjects.com", + "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": + "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": "Current number + of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "bucket", "has_usage": true}, {"quota_id": "obj-total-ingress-throughput-de-fra-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-de-fra-1.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": "Current total + egress bandwidth per account, per endpoint", "quota_limit": 1250000000, "resource_metric": + "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-de-fra-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-de-fra-1.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "de-fra-1.linodeobjects.com", "description": "Current egress + bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-it-mil-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E2", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current total + "E1", "s3_endpoint": "it-mil-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-jp-tyo-1.linodeobjects.com", + "byte", "has_usage": true}, {"quota_id": "obj-objects-it-mil-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E2", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current number + "E1", "s3_endpoint": "it-mil-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-jp-tyo-1.linodeobjects.com", + "object", "has_usage": true}, {"quota_id": "obj-buckets-it-mil-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E2", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current number + "E1", "s3_endpoint": "it-mil-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-lax-4.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-jp-tyo-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": "Current total + "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 549755813888000, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-us-lax-4.linodeobjects.com", + "byte", "has_usage": true}, {"quota_id": "obj-objects-jp-tyo-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": "Current number + "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 500000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-us-lax-4.linodeobjects.com", + "object", "has_usage": true}, {"quota_id": "obj-buckets-jp-tyo-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E3", "s3_endpoint": "us-lax-4.linodeobjects.com", "description": "Current number + "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-mia-1.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-total-ingress-throughput-jp-tyo-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-jp-tyo-1.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current total + egress bandwidth per account, per endpoint", "quota_limit": 1250000000, "resource_metric": + "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-jp-tyo-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-jp-tyo-1.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com", "description": "Current egress + bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-us-southeast-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E1", "s3_endpoint": "us-mia-1.linodeobjects.com", "description": "Current total - capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-us-mia-1.linodeobjects.com", + "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com", "description": "Current + total capacity per account, per endpoint", "quota_limit": 5497558138880, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-us-southeast-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E1", "s3_endpoint": "us-mia-1.linodeobjects.com", "description": "Current number - of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-us-mia-1.linodeobjects.com", + "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com", "description": "Current + number of objects per account, per endpoint", "quota_limit": 50000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-us-southeast-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E1", "s3_endpoint": "us-mia-1.linodeobjects.com", "description": "Current number - of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com", "description": "Current + number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": true}, {"quota_id": "obj-bytes-sg-sin-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com", "description": "Current total @@ -290,31 +338,170 @@ interactions: "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-eu-central-1.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-total-ingress-throughput-sg-sin-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per endpoint)", "quota_type": "obj-total-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com", "description": + "Current total ingress bandwidth per account, per endpoint", "quota_limit": + 1250000000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-total-egress-throughput-sg-sin-1.linodeobjects.com", "quota_name": "Egress + Throughput (per endpoint)", "quota_type": "obj-total-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com", "description": "Current total + egress bandwidth per account, per endpoint", "quota_limit": 1250000000, "resource_metric": + "byte_per_second", "has_usage": false}, {"quota_id": "obj-per-ip-ingress-throughput-sg-sin-1.linodeobjects.com", + "quota_name": "Ingress Throughput (per IP)", "quota_type": "obj-per-ip-ingress-throughput", + "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com", "description": + "Current ingress bandwidth per account, per destination IP address", "quota_limit": + 156250000, "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": + "obj-per-ip-egress-throughput-sg-sin-1.linodeobjects.com", "quota_name": "Egress + Throughput (per IP)", "quota_type": "obj-per-ip-egress-throughput", "endpoint_type": + "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com", "description": "Current egress + bandwidth per account, per destination IP address", "quota_limit": 250000000, + "resource_metric": "byte_per_second", "has_usage": false}, {"quota_id": "obj-bytes-ap-south-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E0", "s3_endpoint": "eu-central-1.linodeobjects.com", "description": "Current + "E0", "s3_endpoint": "ap-south-1.linodeobjects.com", "description": "Current total capacity per account, per endpoint", "quota_limit": 5497558138880, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-eu-central-1.linodeobjects.com", + "byte", "has_usage": true}, {"quota_id": "obj-objects-ap-south-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E0", "s3_endpoint": "eu-central-1.linodeobjects.com", "description": "Current + "E0", "s3_endpoint": "ap-south-1.linodeobjects.com", "description": "Current number of objects per account, per endpoint", "quota_limit": 50000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-eu-central-1.linodeobjects.com", + "object", "has_usage": true}, {"quota_id": "obj-buckets-ap-south-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E0", "s3_endpoint": "eu-central-1.linodeobjects.com", "description": "Current + "E0", "s3_endpoint": "ap-south-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-ord-10.linodeobjects.com", + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-fr-par-1.linodeobjects.com", "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": - "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current - total capacity per account, per endpoint", "quota_limit": 549755813888000, "resource_metric": - "byte", "has_usage": true}, {"quota_id": "obj-objects-us-ord-10.linodeobjects.com", + "E1", "s3_endpoint": "fr-par-1.linodeobjects.com", "description": "Current total + capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-fr-par-1.linodeobjects.com", "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": - "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current - number of objects per account, per endpoint", "quota_limit": 500000000, "resource_metric": - "object", "has_usage": true}, {"quota_id": "obj-buckets-us-ord-10.linodeobjects.com", + "E1", "s3_endpoint": "fr-par-1.linodeobjects.com", "description": "Current number + of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-fr-par-1.linodeobjects.com", "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": - "E3", "s3_endpoint": "us-ord-10.linodeobjects.com", "description": "Current + "E1", "s3_endpoint": "fr-par-1.linodeobjects.com", "description": "Current number + of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-iad-1.linodeobjects.com", + "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": + "E1", "s3_endpoint": "us-iad-1.linodeobjects.com", "description": "Current total + capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-us-iad-1.linodeobjects.com", + "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": + "E1", "s3_endpoint": "us-iad-1.linodeobjects.com", "description": "Current number + of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-us-iad-1.linodeobjects.com", + "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": + "E1", "s3_endpoint": "us-iad-1.linodeobjects.com", "description": "Current number + of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-east-1.linodeobjects.com", + "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": + "E0", "s3_endpoint": "us-east-1.linodeobjects.com", "description": "Current + total capacity per account, per endpoint", "quota_limit": 5497558138880, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-us-east-1.linodeobjects.com", + "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": + "E0", "s3_endpoint": "us-east-1.linodeobjects.com", "description": "Current + number of objects per account, per endpoint", "quota_limit": 50000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-us-east-1.linodeobjects.com", + "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": + "E0", "s3_endpoint": "us-east-1.linodeobjects.com", "description": "Current number of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": - "bucket", "has_usage": true}], "page": 1, "pages": 1, "results": 75}' + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-lax-1.linodeobjects.com", + "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": + "E1", "s3_endpoint": "us-lax-1.linodeobjects.com", "description": "Current total + capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-us-lax-1.linodeobjects.com", + "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": + "E1", "s3_endpoint": "us-lax-1.linodeobjects.com", "description": "Current number + of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-us-lax-1.linodeobjects.com", + "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": + "E1", "s3_endpoint": "us-lax-1.linodeobjects.com", "description": "Current number + of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "bucket", "has_usage": true}, {"quota_id": "obj-bytes-us-sea-1.linodeobjects.com", + "quota_name": "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": + "E1", "s3_endpoint": "us-sea-1.linodeobjects.com", "description": "Current total + capacity per account, per endpoint", "quota_limit": 109951162777600, "resource_metric": + "byte", "has_usage": true}, {"quota_id": "obj-objects-us-sea-1.linodeobjects.com", + "quota_name": "Number of Objects", "quota_type": "obj-objects", "endpoint_type": + "E1", "s3_endpoint": "us-sea-1.linodeobjects.com", "description": "Current number + of objects per account, per endpoint", "quota_limit": 100000000, "resource_metric": + "object", "has_usage": true}, {"quota_id": "obj-buckets-us-sea-1.linodeobjects.com", + "quota_name": "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": + "E1", "s3_endpoint": "us-sea-1.linodeobjects.com", "description": "Current number + of buckets per account, per endpoint", "quota_limit": 1000, "resource_metric": + "bucket", "has_usage": true}], "page": 1, "pages": 2, "results": 103}' + 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, 30 Apr 2026 20:20:07 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - object_storage:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/object-storage/quotas?page=2 + method: GET + response: + body: '{"data": [{"quota_id": "obj-bytes-us-ord-1.linodeobjects.com", "quota_name": + "Total Capacity", "quota_type": "obj-bytes", "endpoint_type": "E1", "s3_endpoint": + "us-ord-1.linodeobjects.com", "description": "Current total capacity per account, + per endpoint", "quota_limit": 109951162777600, "resource_metric": "byte", "has_usage": + true}, {"quota_id": "obj-objects-us-ord-1.linodeobjects.com", "quota_name": + "Number of Objects", "quota_type": "obj-objects", "endpoint_type": "E1", "s3_endpoint": + "us-ord-1.linodeobjects.com", "description": "Current number of objects per + account, per endpoint", "quota_limit": 100000000, "resource_metric": "object", + "has_usage": true}, {"quota_id": "obj-buckets-us-ord-1.linodeobjects.com", "quota_name": + "Number of Buckets", "quota_type": "obj-buckets", "endpoint_type": "E1", "s3_endpoint": + "us-ord-1.linodeobjects.com", "description": "Current number of buckets per + account, per endpoint", "quota_limit": 1000, "resource_metric": "bucket", "has_usage": + true}], "page": 2, "pages": 2, "results": 103}' headers: Access-Control-Allow-Credentials: - "true" @@ -337,7 +524,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 23 Feb 2026 20:13:34 GMT + - Thu, 30 Apr 2026 20:20:07 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index e925a71fd..8a1d09b0f 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -120,11 +120,6 @@ func TestInstance_GetMonthlyTransfer(t *testing.T) { if err != nil { t.Errorf("Error getting monthly instance transfer, expected struct, got error %v", err) } - - _, err = client.GetInstanceTransferMonthlyV2(context.Background(), instance.ID, testYear, testMonth) - if err != nil { - t.Errorf("Error getting monthly instance transfer, expected struct, got error %v", err) - } } func TestInstance_ResetPassword(t *testing.T) { diff --git a/test/integration/monitor_alert_definitions_test.go b/test/integration/monitor_alert_definitions_test.go index 566fc4f6f..f8f243658 100644 --- a/test/integration/monitor_alert_definitions_test.go +++ b/test/integration/monitor_alert_definitions_test.go @@ -113,7 +113,6 @@ func TestMonitorAlertDefinition_smoke(t *testing.T) { assert.Equal(t, createOpts.Label, createdAlert.Label) assert.Equal(t, createOpts.Severity, createdAlert.Severity) assert.Equal(t, *createOpts.Description, createdAlert.Description) - assert.ElementsMatch(t, createOpts.EntityIDs, createdAlert.EntityIDs) // assert.Equal(t, fetchedChannel.Label, createdAlert.AlertChannels[0].Label) // More thorough assertions on the created alert's nested fields diff --git a/test/integration/network_ips_test.go b/test/integration/network_ips_test.go index fef3d2f4b..b96308d09 100644 --- a/test/integration/network_ips_test.go +++ b/test/integration/network_ips_test.go @@ -97,7 +97,7 @@ func TestIPAddresses_List_smoke(t *testing.T) { } rdns := fmt.Sprintf("%s.nip.io", ip.Address) - _, err = client.UpdateIPAddressV2(context.Background(), ip.Address, IPAddressUpdateOptionsV2{ + _, err = client.UpdateIPAddress(context.Background(), ip.Address, IPAddressUpdateOptions{ RDNS: linodego.Pointer(linodego.Pointer(rdns)), }) if err != nil { @@ -191,18 +191,18 @@ func TestIPAddress_Update(t *testing.T) { originalRDNS := i.IPv4.Public[0].RDNS // Update RDNS to nip.io - updateOpts := IPAddressUpdateOptionsV2{ + updateOpts := IPAddressUpdateOptions{ RDNS: linodego.Pointer(linodego.Pointer(fmt.Sprintf("%s.nip.io", i.IPv4.Public[0].Address))), } - ip, err := client.UpdateIPAddressV2(context.Background(), address, updateOpts) + ip, err := client.UpdateIPAddress(context.Background(), address, updateOpts) require.NoError(t, err) // Update RDNS to default - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ RDNS: linodego.Pointer[*string](nil), } - ip, err = client.UpdateIPAddressV2(context.Background(), ip.Address, updateOpts) + ip, err = client.UpdateIPAddress(context.Background(), ip.Address, updateOpts) require.NoError(t, err) require.NotNil(t, ip) @@ -219,10 +219,10 @@ func TestIPAddress_Update(t *testing.T) { // Scenario 1: Convert ephemeral IP to reserved IP ephemeralIP := instance.IPv4[0].String() - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedTrue, } - updatedIP, err := client.UpdateIPAddressV2(context.Background(), ephemeralIP, updateOpts) + updatedIP, err := client.UpdateIPAddress(context.Background(), ephemeralIP, updateOpts) if err != nil { t.Fatalf("Failed to convert ephemeral IP to reserved: %v", err) } @@ -238,10 +238,10 @@ func TestIPAddress_Update(t *testing.T) { } defer client.DeleteReservedIPAddress(context.Background(), reservedIP) - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedTrue, } - updatedIP, err = client.UpdateIPAddressV2(context.Background(), reservedIP, updateOpts) + updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { t.Fatalf("Failed to update reserved IP: %v", err) } @@ -252,10 +252,10 @@ func TestIPAddress_Update(t *testing.T) { // Scenario 3: Convert reserved to ephemeral ephemeralIP = instance.IPv4[0].String() - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedFalse, } - updatedIP, err = client.UpdateIPAddressV2(context.Background(), ephemeralIP, updateOpts) + updatedIP, err = client.UpdateIPAddress(context.Background(), ephemeralIP, updateOpts) if err != nil { t.Fatalf("Failed to update ephemeral IP: %v", err) } @@ -285,10 +285,10 @@ func TestIPAddress_Update(t *testing.T) { t.Fatalf("Failed to assign reserved IP: %v", err) } - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedFalse, } - updatedIP, err = client.UpdateIPAddressV2(context.Background(), reservedIP, updateOpts) + updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { t.Fatalf("Failed to convert assigned reserved IP to ephemeral: %v", err) } @@ -303,11 +303,11 @@ func TestIPAddress_Update(t *testing.T) { t.Fatalf("Failed to create reserved IP: %v", unassignedResIpErr) } - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedTrue, RDNS: linodego.Pointer(linodego.Pointer("sample rdns")), } - _, err = client.UpdateIPAddressV2(context.Background(), unassignedResIP, updateOpts) + _, err = client.UpdateIPAddress(context.Background(), unassignedResIP, updateOpts) if err == nil { t.Fatalf("Expected error when setting RDNS for unassigned reserved IP, but got none") } @@ -321,10 +321,10 @@ func TestIPAddress_Update(t *testing.T) { t.Fatalf("Failed to create reserved IP: %v", err) } - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedTrue, } - updatedIP, err = client.UpdateIPAddressV2(context.Background(), reservedIP, updateOpts) + updatedIP, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { t.Fatalf("Failed to update unassigned reserved IP: %v", err) } @@ -341,10 +341,10 @@ func TestIPAddress_Update(t *testing.T) { t.Fatalf("Failed to create reserved IP: %v", err) } - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedFalse, } - _, err = client.UpdateIPAddressV2(context.Background(), reservedIP, updateOpts) + _, err = client.UpdateIPAddress(context.Background(), reservedIP, updateOpts) if err != nil { t.Fatalf("Failed to convert unassigned reserved IP to unassigned: %v", err) } @@ -359,11 +359,11 @@ func TestIPAddress_Update(t *testing.T) { invalidResIp := "123.72.121.76" - updateOpts = IPAddressUpdateOptionsV2{ + updateOpts = IPAddressUpdateOptions{ Reserved: &reservedFalse, } - updatedIP, err = client.UpdateIPAddressV2(context.Background(), invalidResIp, updateOpts) + updatedIP, err = client.UpdateIPAddress(context.Background(), invalidResIp, updateOpts) if err == nil { t.Fatalf("Expected error indicating the IP address is invalid, got nil") } diff --git a/test/integration/object_storage_bucket_certs_test.go b/test/integration/object_storage_bucket_certs_test.go index 20a0ca295..b31f968ec 100644 --- a/test/integration/object_storage_bucket_certs_test.go +++ b/test/integration/object_storage_bucket_certs_test.go @@ -133,19 +133,6 @@ func TestObjectStorageBucketCert_smoke(t *testing.T) { t.Fatalf("failed to upload bucket cert: %s", err) } - err = client.DeleteObjectStorageBucketCert(context.TODO(), bucket.Region, bucket.Label) - if err != nil { - t.Fatalf("failed to upload bucket cert: %s", err) - } - - _, err = client.UploadObjectStorageBucketCertV2(context.TODO(), bucket.Region, bucket.Label, linodego.ObjectStorageBucketCertUploadOptions{ - Certificate: testCertifcate, - PrivateKey: testPrivateKey, - }) - if err != nil { - t.Fatalf("failed to upload bucket cert: %s", err) - } - defer func() { if err := client.DeleteObjectStorageBucketCert(context.TODO(), bucket.Region, bucket.Label); err != nil { t.Errorf("failed to delete bucket cert: %s", err) @@ -157,16 +144,7 @@ func TestObjectStorageBucketCert_smoke(t *testing.T) { t.Fatalf("failed to get bucket cert: %s", err) } - if !cert.SSL { - t.Fatalf("expected cert.SSL to be true; got false") - } - - certv2, err := client.GetObjectStorageBucketCertV2(context.TODO(), bucket.Region, bucket.Label) - if err != nil { - t.Fatalf("failed to get bucket cert: %s", err) - } - - if certv2 == nil || !*certv2.SSL { + if cert == nil || !*cert.SSL { t.Fatalf("expected cert.SSL to be true; got false") } } diff --git a/test/integration/object_storage_buckets_test.go b/test/integration/object_storage_buckets_test.go index 9476cde52..efe10b707 100644 --- a/test/integration/object_storage_buckets_test.go +++ b/test/integration/object_storage_buckets_test.go @@ -12,11 +12,6 @@ import ( var objectStorageBucketTestLabel = "go-bucket-test-def" var testObjectStorageBucketCreateOpts = ObjectStorageBucketCreateOptions{ - Cluster: "us-east-1", - Label: objectStorageBucketTestLabel, -} - -var testRegionalObjectStorageBucketCreateOpts = ObjectStorageBucketCreateOptions{ Region: "us-east", Label: objectStorageBucketTestLabel, } @@ -35,53 +30,13 @@ func TestObjectStorageBucket_Create_smoke(t *testing.T) { // when comparing fixtures to random value Label will differ, compare the known prefix if bucket.Label != expected.Label || - bucket.Cluster != expected.Cluster { + bucket.Region != expected.Region { t.Errorf("Object Storage Bucket did not match CreateOptions") } assertDateSet(t, bucket.Created) } -func TestObjectStorageBucket_Regional(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestObjectStorageBucket_Regional") - regions := getRegionsWithCaps(t, client, []string{"Object Storage"}) - if len(regions) < 1 { - t.Fatal("Can't get region with Object Storage capability") - } - region := regions[0] - - client, bucket, teardown, err := setupObjectStorageBucket(t, - []objectStorageBucketModifier{ - func(opts *ObjectStorageBucketCreateOptions) { - opts.Cluster = "" - opts.Region = region - }, - }, - "fixtures/TestObjectStorageBucket_Regional", - client, teardown, nil, - ) - defer teardown() - - if err != nil { - t.Errorf("Error creating Object Storage Bucket, got error %v", err) - } - - expected := testObjectStorageBucketCreateOpts - - // when comparing fixtures to random value Label will differ, compare the known prefix - if bucket.Label != expected.Label || - bucket.Region != region { - t.Errorf("Object Storage Bucket did not match CreateOptions") - } - - assertDateSet(t, bucket.Created) - - bucket, err = client.GetObjectStorageBucket(context.Background(), region, expected.Label) - if err != nil { - t.Errorf("Error getting Object Storage Bucket, %v", err) - } -} - func TestObjectStorageBucket_GetMissing(t *testing.T) { client, bucket, teardown, err := setupObjectStorageBucket(t, nil, @@ -114,7 +69,7 @@ func TestObjectStorageBucket_GetFound(t *testing.T) { t.Error(err) } - i, err := client.GetObjectStorageBucket(context.Background(), bucket.Cluster, bucket.Label) + i, err := client.GetObjectStorageBucket(context.Background(), bucket.Region, bucket.Label) if err != nil { t.Errorf("Error getting ObjectStorageBucket, expected struct, got %v and error %v", i, err) } @@ -125,7 +80,7 @@ func TestObjectStorageBucket_GetFound(t *testing.T) { // when comparing fixtures to random value Label will differ, compare the known prefix if bucket.Label != expected.Label || - bucket.Cluster != expected.Cluster { + bucket.Region != expected.Region { t.Errorf("Object Storage Bucket did not match CreateOptions") } } @@ -157,24 +112,6 @@ func TestObjectStorageBuckets_List_smoke(t *testing.T) { } } -func TestObjectStorageBucketsInCluster_List(t *testing.T) { - client, bucket, teardown, err := setupObjectStorageBucket(t, - nil, - "fixtures/TestObjectStorageBucketsInCluster_List", nil, nil, nil) - defer teardown() - - i, err := client.ListObjectStorageBucketsInCluster(context.Background(), nil, bucket.Cluster) - if err != nil { - t.Errorf("Error listing ObjectStorageBucketsInCluster, expected struct, got error %v", err) - } - if len(i) == 0 { - t.Errorf("Expected a list of ObjectStorageBucketsInCluster, but got none %v", i) - } else if i[0].Label == "" || - i[0].Cluster == "" { - t.Errorf("Listed Object Storage Bucket in Cluster did not have attributes %v", i) - } -} - func TestObjectStorageBucket_Access_Get(t *testing.T) { corsEnabled := false @@ -200,21 +137,12 @@ func TestObjectStorageBucket_Access_Get(t *testing.T) { t.Errorf("Error getting ObjectStorageBucket access, got error %s", err) } - newBucketv2, err := client.GetObjectStorageBucketAccessV2(context.Background(), bucket.Region, bucket.Label) - if err != nil { - t.Errorf("Error getting ObjectStorageBucket access, got error %s", err) - } - - if newBucket.CorsEnabled != corsEnabled { - t.Errorf("ObjectStorageBucket access CORS does not match update, expected %t, got %t", corsEnabled, newBucket.CorsEnabled) - } - - if newBucketv2.CorsEnabled == nil { + if newBucket.CorsEnabled == nil { t.Errorf("ObjectStorageBucket access CORS does not match update, expected %t, got nil", corsEnabled) } - if newBucketv2.CorsEnabled != nil && *newBucketv2.CorsEnabled != corsEnabled { - t.Errorf("ObjectStorageBucket access CORS does not match update, expected %t, got %t", corsEnabled, *newBucketv2.CorsEnabled) + if newBucket.CorsEnabled != nil && *newBucket.CorsEnabled != corsEnabled { + t.Errorf("ObjectStorageBucket access CORS does not match update, expected %t, got %t", corsEnabled, *newBucket.CorsEnabled) } if newBucket.ACL != createOpts.ACL { @@ -222,11 +150,6 @@ func TestObjectStorageBucket_Access_Get(t *testing.T) { createOpts.ACL, newBucket.ACL) } - if newBucketv2.ACL != createOpts.ACL { - t.Errorf("ObjectStorageBucket access ACL does not match update, expected %s, got %s", - createOpts.ACL, - newBucketv2.ACL) - } } func TestObjectStorageBucket_Access_Update(t *testing.T) { @@ -255,8 +178,8 @@ func TestObjectStorageBucket_Access_Update(t *testing.T) { t.Errorf("Error getting ObjectStorageBucket access, got error %s", err) } - if newBucket.CorsEnabled != corsEnabled { - t.Errorf("ObjectStorageBucket access CORS does not match update, expected %t, got %t", corsEnabled, newBucket.CorsEnabled) + if *newBucket.CorsEnabled != corsEnabled { + t.Errorf("ObjectStorageBucket access CORS does not match update, expected %t, got %t", corsEnabled, *newBucket.CorsEnabled) } if newBucket.ACL != opts.ACL { @@ -287,7 +210,7 @@ func setupObjectStorageBucket( client, teardown = createTestClient(t, fixturesYaml) } - createOpts := testRegionalObjectStorageBucketCreateOpts + createOpts := testObjectStorageBucketCreateOpts if endpointType != nil { endpoints, err := client.ListObjectStorageEndpoints(context.Background(), nil) @@ -313,7 +236,7 @@ func setupObjectStorageBucket( } newTeardown := func() { - if err := client.DeleteObjectStorageBucket(context.Background(), bucket.Cluster, bucket.Label); err != nil { + if err := client.DeleteObjectStorageBucket(context.Background(), bucket.Region, bucket.Label); err != nil { if t != nil { t.Errorf("Error deleting test Bucket: %s", err) } diff --git a/test/integration/object_storage_clusters_test.go b/test/integration/object_storage_clusters_test.go deleted file mode 100644 index 20e8f92a7..000000000 --- a/test/integration/object_storage_clusters_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package integration - -import ( - "context" - "testing" -) - -func TestObjectStorageClusters_List(t *testing.T) { - client, teardown := createTestClient(t, "fixtures/TestObjectStorageClusters_List") - defer teardown() - - objectStorageClusters, err := client.ListObjectStorageClusters(context.Background(), nil) - if err != nil { - t.Errorf("Error listing objectStorageClusters, expected struct - error %v", err) - } - if len(objectStorageClusters) == 0 { - t.Errorf("Expected a list of objectStorageClusters - %v", objectStorageClusters) - } -} diff --git a/test/integration/object_storage_keys_test.go b/test/integration/object_storage_keys_test.go index 069272683..215353ec6 100644 --- a/test/integration/object_storage_keys_test.go +++ b/test/integration/object_storage_keys_test.go @@ -116,13 +116,11 @@ func TestObjectStorageKeys_Limited(t *testing.T) { createOpts := testBasicObjectStorageKeyCreateOpts createOpts.BucketAccess = &[]ObjectStorageKeyBucketAccess{ { - Cluster: "us-east-1", Region: "us-east", BucketName: bucket.Label, Permissions: "read_only", }, { - Cluster: "us-east-1", Region: "us-east", BucketName: bucket.Label, Permissions: "read_write", @@ -170,8 +168,8 @@ func TestObjectStorageKeys_Regional_Limited(t *testing.T) { client, bucket, teardown, err := setupObjectStorageBucket(t, []objectStorageBucketModifier{ func(createOpts *ObjectStorageBucketCreateOptions) { - createOpts.Cluster = "" createOpts.Region = region + createOpts.Label += "go-test-def-regional" }, }, "fixtures/TestObjectStorageKeys_Regional_Limited", client, teardown, nil) diff --git a/test/integration/object_storage_object_test.go b/test/integration/object_storage_object_test.go index 14166b734..60a606a93 100644 --- a/test/integration/object_storage_object_test.go +++ b/test/integration/object_storage_object_test.go @@ -14,7 +14,7 @@ var objectStorageObjectURLExpirySeconds = 360 func putObjectStorageObject(t *testing.T, client *linodego.Client, bucket *linodego.ObjectStorageBucket, name, content string) { t.Helper() - url, err := client.CreateObjectStorageObjectURL(context.TODO(), bucket.Cluster, bucket.Label, linodego.ObjectStorageObjectURLCreateOptions{ + url, err := client.CreateObjectStorageObjectURL(context.TODO(), bucket.Region, bucket.Label, linodego.ObjectStorageObjectURLCreateOptions{ Name: name, Method: http.MethodPut, ContentType: "text/plain", @@ -48,7 +48,7 @@ func putObjectStorageObject(t *testing.T, client *linodego.Client, bucket *linod func deleteObjectStorageObject(t *testing.T, client *linodego.Client, bucket *linodego.ObjectStorageBucket, name string) { t.Helper() - url, err := client.CreateObjectStorageObjectURL(context.TODO(), bucket.Cluster, bucket.Label, linodego.ObjectStorageObjectURLCreateOptions{ + url, err := client.CreateObjectStorageObjectURL(context.TODO(), bucket.Region, bucket.Label, linodego.ObjectStorageObjectURLCreateOptions{ Name: name, Method: http.MethodDelete, ExpiresIn: &objectStorageObjectURLExpirySeconds, @@ -87,33 +87,20 @@ func TestObjectStorageObject_Smoke(t *testing.T) { putObjectStorageObject(t, client, bucket, object, "testing123") defer deleteObjectStorageObject(t, client, bucket, object) - config, err := client.GetObjectStorageObjectACLConfig(context.TODO(), bucket.Cluster, bucket.Label, object) + config, err := client.GetObjectStorageObjectACLConfig(context.TODO(), bucket.Region, bucket.Label, object) if err != nil { t.Errorf("failed to get ACL config: %s", err) } - if config.ACL != "private" { - t.Errorf("expected ACL to be private; got %s", config.ACL) - } - - if config.ACLXML == "" { - t.Error("expected ACL XML to be included") - } - - configv2, err := client.GetObjectStorageObjectACLConfigV2(context.TODO(), bucket.Cluster, bucket.Label, object) - if err != nil { - t.Errorf("failed to get ACL config: %s", err) - } - - if configv2.ACL == nil { + if config.ACL == nil { t.Errorf("expected ACL to be private; got nil") } - if configv2.ACL != nil && *configv2.ACL != "private" { - t.Errorf("expected ACL to be private; got %s", *configv2.ACL) + if config.ACL != nil && *config.ACL != "private" { + t.Errorf("expected ACL to be private; got %s", *config.ACL) } - content, err := client.ListObjectStorageBucketContents(context.TODO(), bucket.Cluster, bucket.Label, nil) + content, err := client.ListObjectStorageBucketContents(context.TODO(), bucket.Region, bucket.Label, nil) if err != nil { t.Errorf("failed to get bucket contents: %s", err) } @@ -123,44 +110,28 @@ func TestObjectStorageObject_Smoke(t *testing.T) { } updateOpts := linodego.ObjectStorageObjectACLConfigUpdateOptions{ACL: "public-read", Name: object} - if _, err = client.UpdateObjectStorageObjectACLConfig(context.TODO(), bucket.Cluster, bucket.Label, updateOpts); err != nil { + if _, err = client.UpdateObjectStorageObjectACLConfig(context.TODO(), bucket.Region, bucket.Label, updateOpts); err != nil { t.Errorf("failed to update ACL config: %s", err) } - if _, err = client.UpdateObjectStorageObjectACLConfigV2(context.TODO(), bucket.Cluster, bucket.Label, updateOpts); err != nil { - t.Errorf("failed to update ACL config: %s", err) - } - - config, err = client.GetObjectStorageObjectACLConfig(context.TODO(), bucket.Cluster, bucket.Label, object) - if err != nil { - t.Errorf("failed to get updated ACL config: %s", err) - } - - if config.ACL != updateOpts.ACL { - t.Errorf("expected ACL config to be %s; got %s", updateOpts.ACL, config.ACL) - } - if config.ACLXML == "" { - t.Error("expected ACL XML to be included") - } - - configv2, err = client.GetObjectStorageObjectACLConfigV2(context.TODO(), bucket.Cluster, bucket.Label, object) + config, err = client.GetObjectStorageObjectACLConfig(context.TODO(), bucket.Region, bucket.Label, object) if err != nil { t.Errorf("failed to get ACL config: %s", err) } - if configv2.ACL == nil { + if config.ACL == nil { t.Errorf("expected ACL config to be %s; got nil", updateOpts.ACL) } - if configv2.ACL != nil && *configv2.ACL != updateOpts.ACL { + if config.ACL != nil && *config.ACL != updateOpts.ACL { t.Errorf("expected ACL config to be %s; got nil", updateOpts.ACL) } - if configv2.ACLXML == nil { + if config.ACLXML == nil { t.Error("expected ACL XML to be included") } - if configv2.ACLXML != nil && *configv2.ACLXML == "" { + if config.ACLXML != nil && *config.ACLXML == "" { t.Error("expected ACL XML to be included") } } diff --git a/test/integration/object_storage_quota_test.go b/test/integration/object_storage_quota_test.go index bd1e9d512..a8ad8c410 100644 --- a/test/integration/object_storage_quota_test.go +++ b/test/integration/object_storage_quota_test.go @@ -16,15 +16,23 @@ func TestObjectStorageQuotas_Get(t *testing.T) { quota, err := client.GetObjectStorageQuota(context.Background(), targetQuotaID) assert.NoError(t, err) - assert.Equal(t, targetQuotaID, quota.QuotaID) - assert.NotEmpty(t, quota.QuotaName) - assert.NotEmpty(t, quota.EndpointType) - assert.NotEmpty(t, quota.S3Endpoint) - assert.NotEmpty(t, quota.Description) - assert.Greater(t, quota.QuotaLimit, 0) - assert.NotEmpty(t, quota.ResourceMetric) - assert.NotEmpty(t, quota.QuotaType) - assert.True(t, quota.HasUsage) + expected := linodego.ObjectStorageQuota{ + QuotaID: "obj-objects-us-ord-1.linodeobjects.com", + QuotaName: "Number of Objects", + EndpointType: "E1", + S3Endpoint: "us-ord-1.linodeobjects.com", + Description: "Current number of objects per account, per endpoint", + QuotaLimit: 100000000, + ResourceMetric: "object", + } + + assert.Equal(t, expected.QuotaID, quota.QuotaID) + assert.Equal(t, expected.QuotaName, quota.QuotaName) + assert.Equal(t, expected.EndpointType, quota.EndpointType) + assert.Equal(t, expected.S3Endpoint, quota.S3Endpoint) + assert.Equal(t, expected.Description, quota.Description) + assert.Equal(t, expected.QuotaLimit, quota.QuotaLimit) + assert.Equal(t, expected.ResourceMetric, quota.ResourceMetric) } func TestObjectStorageQuotas_List(t *testing.T) { @@ -45,15 +53,23 @@ func TestObjectStorageQuotas_List(t *testing.T) { } if assert.NotNil(t, foundQuota, "Expected quota_id %q not found", targetQuotaID) { - assert.Equal(t, targetQuotaID, foundQuota.QuotaID) - assert.NotEmpty(t, foundQuota.QuotaName) - assert.NotEmpty(t, foundQuota.EndpointType) - assert.NotEmpty(t, foundQuota.S3Endpoint) - assert.NotEmpty(t, foundQuota.Description) - assert.Greater(t, foundQuota.QuotaLimit, 0) - assert.NotEmpty(t, foundQuota.ResourceMetric) - assert.NotEmpty(t, foundQuota.QuotaType) - assert.True(t, foundQuota.HasUsage) + expected := linodego.ObjectStorageQuota{ + QuotaID: "obj-buckets-us-mia-1.linodeobjects.com", + QuotaName: "Number of Buckets", + EndpointType: "E1", + S3Endpoint: "us-mia-1.linodeobjects.com", + Description: "Current number of buckets per account, per endpoint", + QuotaLimit: 1000, + ResourceMetric: "bucket", + } + + assert.Equal(t, expected.QuotaID, foundQuota.QuotaID) + assert.Equal(t, expected.QuotaName, foundQuota.QuotaName) + assert.Equal(t, expected.EndpointType, foundQuota.EndpointType) + assert.Equal(t, expected.S3Endpoint, foundQuota.S3Endpoint) + assert.Equal(t, expected.Description, foundQuota.Description) + assert.Equal(t, expected.QuotaLimit, foundQuota.QuotaLimit) + assert.Equal(t, expected.ResourceMetric, foundQuota.ResourceMetric) } } diff --git a/test/unit/fixtures/lke_cluster_pool_create.json b/test/unit/fixtures/lke_cluster_pool_create.json deleted file mode 100644 index 7f2f34602..000000000 --- a/test/unit/fixtures/lke_cluster_pool_create.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 3, - "type": "g6-standard-2", - "count": 3 -} - \ No newline at end of file diff --git a/test/unit/fixtures/lke_cluster_pool_get.json b/test/unit/fixtures/lke_cluster_pool_get.json deleted file mode 100644 index 55c6ead91..000000000 --- a/test/unit/fixtures/lke_cluster_pool_get.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "id": 1, - "type": "pool-1", - "count": 3, - "autoscaler": {"enabled": true, "min": 1, "max": 5} -} - \ No newline at end of file diff --git a/test/unit/fixtures/lke_cluster_pool_list.json b/test/unit/fixtures/lke_cluster_pool_list.json deleted file mode 100644 index c70ee4b6e..000000000 --- a/test/unit/fixtures/lke_cluster_pool_list.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "data": [ - { - "id": 1, - "type": "pool-1", - "count": 3, - "autoscaler": {"enabled": true, "min": 1, "max": 5} - }, - { - "id": 2, - "type": "pool-2", - "count": 2, - "autoscaler": {"enabled": false} - } - ], - "pages": 1, - "results": 2 -} - \ No newline at end of file diff --git a/test/unit/fixtures/lke_cluster_pool_update.json b/test/unit/fixtures/lke_cluster_pool_update.json deleted file mode 100644 index 235943ef0..000000000 --- a/test/unit/fixtures/lke_cluster_pool_update.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 1, - "type": "pool-1", - "count": 5 -} - \ No newline at end of file diff --git a/test/unit/fixtures/object_storage_cluster_get.json b/test/unit/fixtures/object_storage_cluster_get.json deleted file mode 100644 index 3f932e613..000000000 --- a/test/unit/fixtures/object_storage_cluster_get.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "id": "my-cluster-id", - "domain": "example.com", - "status": "active", - "region": "us-east-1", - "static_site_domain": "static.example.com" -} diff --git a/test/unit/fixtures/object_storage_cluster_list.json b/test/unit/fixtures/object_storage_cluster_list.json deleted file mode 100644 index 714737876..000000000 --- a/test/unit/fixtures/object_storage_cluster_list.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "data": [ - { - "id": "my-cluster-id", - "domain": "example.com", - "status": "active", - "region": "us-east-1", - "static_site_domain": "static.example.com" - } - ], - "page": 1, - "pages": 1, - "results": 1 -} - \ No newline at end of file diff --git a/test/unit/instance_ip_test.go b/test/unit/instance_ip_test.go index 27b046035..6e035ff7f 100644 --- a/test/unit/instance_ip_test.go +++ b/test/unit/instance_ip_test.go @@ -82,8 +82,8 @@ func TestInstanceIPAddress_Update(t *testing.T) { defer base.TearDown(t) rdns := "custom.reverse.dns" - updateOpts := linodego.IPAddressUpdateOptions{ - RDNS: &rdns, + updateOpts := linodego.InstanceIPAddressUpdateOptions{ + RDNS: linodego.DoublePointer(rdns), } base.MockPut("linode/instances/123/ips/192.0.2.1", fixtureData) diff --git a/test/unit/instance_test.go b/test/unit/instance_test.go index f10e08d6f..d72518d94 100644 --- a/test/unit/instance_test.go +++ b/test/unit/instance_test.go @@ -3,7 +3,6 @@ package unit import ( "context" "fmt" - "strconv" "testing" "github.com/jarcoal/httpmock" @@ -114,9 +113,6 @@ func TestInstance_ResetPassword(t *testing.T) { } func TestInstance_Get_MonthlyTransfer(t *testing.T) { - if strconv.IntSize < 64 { - t.Skip("V1 monthly transfer doesn't work on 32 or lower bits system") - } fixtureData, err := fixtures.GetFixture("instance_monthly_transfer_get") assert.NoError(t, err) @@ -129,24 +125,6 @@ func TestInstance_Get_MonthlyTransfer(t *testing.T) { stats, err := base.Client.GetInstanceTransferMonthly(context.Background(), 12345, 2024, 11) assert.NoError(t, err) - assert.Equal(t, 30471077120, stats.BytesIn) - assert.Equal(t, 22956600198, stats.BytesOut) - assert.Equal(t, 53427677318, stats.BytesTotal) -} - -func TestInstance_Get_MonthlyTransferV2(t *testing.T) { - fixtureData, err := fixtures.GetFixture("instance_monthly_transfer_get") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockGet("linode/instances/12345/transfer/2024/11", fixtureData) - - stats, err := base.Client.GetInstanceTransferMonthlyV2(context.Background(), 12345, 2024, 11) - assert.NoError(t, err) - assert.Equal(t, uint64(30471077120), stats.BytesIn) assert.Equal(t, uint64(22956600198), stats.BytesOut) assert.Equal(t, uint64(53427677318), stats.BytesTotal) diff --git a/test/unit/lke_cluster_pool_test.go b/test/unit/lke_cluster_pool_test.go deleted file mode 100644 index c89cb81de..000000000 --- a/test/unit/lke_cluster_pool_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package unit - -import ( - "context" - "testing" - - "github.com/linode/linodego" - "github.com/stretchr/testify/assert" -) - -func TestLKEClusterPool_List(t *testing.T) { - fixtureData, err := fixtures.GetFixture("lke_cluster_pool_list") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockGet("lke/clusters/123/pools", fixtureData) - - pools, err := base.Client.ListLKEClusterPools(context.Background(), 123, nil) - assert.NoError(t, err) - assert.Len(t, pools, 2) - - assert.Equal(t, 1, pools[0].ID) - assert.Equal(t, "pool-1", pools[0].Type) -} - -func TestLKEClusterPool_Get(t *testing.T) { - fixtureData, err := fixtures.GetFixture("lke_cluster_pool_get") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockGet("lke/clusters/123/pools/1", fixtureData) - - pool, err := base.Client.GetLKEClusterPool(context.Background(), 123, 1) - assert.NoError(t, err) - assert.Equal(t, 1, pool.ID) - assert.Equal(t, "pool-1", pool.Type) -} - -func TestLKEClusterPool_Create(t *testing.T) { - fixtureData, err := fixtures.GetFixture("lke_cluster_pool_create") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - createOptions := linodego.LKEClusterPoolCreateOptions{ - Type: "g6-standard-2", - Count: 3, - } - - base.MockPost("lke/clusters/123/pools", fixtureData) - - pool, err := base.Client.CreateLKEClusterPool(context.Background(), 123, createOptions) - assert.NoError(t, err) - assert.Equal(t, "g6-standard-2", pool.Type) - assert.Equal(t, 3, pool.Count) -} - -func TestLKEClusterPool_Update(t *testing.T) { - fixtureData, err := fixtures.GetFixture("lke_cluster_pool_update") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - updateOptions := linodego.LKEClusterPoolUpdateOptions{ - Count: 5, - } - - base.MockPut("lke/clusters/123/pools/1", fixtureData) - - pool, err := base.Client.UpdateLKEClusterPool(context.Background(), 123, 1, updateOptions) - assert.NoError(t, err) - assert.Equal(t, 5, pool.Count) -} - -func TestLKEClusterPool_Delete(t *testing.T) { - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockDelete("lke/clusters/123/pools/1", nil) - - err := base.Client.DeleteLKEClusterPool(context.Background(), 123, 1) - assert.NoError(t, err) -} - -func TestLKEClusterPool_DeleteNode(t *testing.T) { - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockDelete("lke/clusters/123/nodes/abc123", nil) - - err := base.Client.DeleteLKEClusterPoolNode(context.Background(), 123, "abc123") - assert.NoError(t, err) -} diff --git a/test/unit/monitor_alert_definitions_test.go b/test/unit/monitor_alert_definitions_test.go index c8e742db8..1d8960418 100644 --- a/test/unit/monitor_alert_definitions_test.go +++ b/test/unit/monitor_alert_definitions_test.go @@ -22,10 +22,6 @@ const ( "description": "A test alert for dbaas service", "scope": "entity", "regions": [], - "entity_ids": [ - "12345" - ], - "has_more_resources": false, "alert_channels": [ { "id": 10000, @@ -84,10 +80,6 @@ const ( "status": "enabled", "scope": "entity", "regions": [], - "entity_ids": [ - "12345" - ], - "has_more_resources": true, "alert_channels": [ { "id": 10000, @@ -253,8 +245,6 @@ func TestCreateMonitorAlertDefinition(t *testing.T) { assert.Equal(t, "/monitor/services/dbaas/alert-definitions/123/entities", alert.Entities.URL) assert.Equal(t, 0, alert.Entities.Count) assert.False(t, alert.Entities.HasMoreResources) - assert.Equal(t, []string{"12345"}, alert.EntityIDs) - assert.False(t, alert.HasMoreResources) assert.NotNil(t, alert.AlertChannels) assert.NotNil(t, alert.RuleCriteria) assert.NotNil(t, alert.RuleCriteria.Rules) @@ -311,8 +301,6 @@ func TestGetMonitorAlertDefinition(t *testing.T) { assert.Equal(t, "/monitor/services/dbaas/alert-definitions/123/entities", alert.Entities.URL) assert.Equal(t, 0, alert.Entities.Count) assert.False(t, alert.Entities.HasMoreResources) - assert.Equal(t, []string{"12345"}, alert.EntityIDs) - assert.False(t, alert.HasMoreResources) assert.NotNil(t, alert.AlertChannels) assert.NotNil(t, alert.RuleCriteria) assert.NotNil(t, alert.RuleCriteria.Rules) @@ -336,8 +324,6 @@ func TestListMonitorAlertDefinitions(t *testing.T) { assert.Equal(t, "/monitor/services/dbaas/alert-definitions/123/entities", alerts[0].Entities.URL) assert.Equal(t, 2, alerts[0].Entities.Count) assert.True(t, alerts[0].Entities.HasMoreResources) - assert.Equal(t, []string{"12345"}, alerts[0].EntityIDs) - assert.True(t, alerts[0].HasMoreResources) assert.NotNil(t, alerts[0].AlertChannels) assert.NotNil(t, alerts[0].RuleCriteria) assert.NotNil(t, alerts[0].RuleCriteria.Rules) @@ -372,7 +358,6 @@ func TestUpdateMonitorAlertDefinition(t *testing.T) { assert.Equal(t, "/monitor/services/dbaas/alert-definitions/123/entities", alert.Entities.URL) assert.Equal(t, 2, alert.Entities.Count) assert.True(t, alert.Entities.HasMoreResources) - assert.True(t, alert.HasMoreResources) } func TestUpdateMonitorAlertDefinition_LabelOnly(t *testing.T) { diff --git a/test/unit/network_ips_test.go b/test/unit/network_ips_test.go index 11042d4bd..8f5229a6e 100644 --- a/test/unit/network_ips_test.go +++ b/test/unit/network_ips_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestIPUpdateAddressV2(t *testing.T) { +func TestIPUpdateAddress(t *testing.T) { var base ClientBaseCase base.SetUp(t) defer base.TearDown(t) @@ -21,7 +21,7 @@ func TestIPUpdateAddressV2(t *testing.T) { Reserved: true, }) - updatedIP, err := base.Client.UpdateIPAddressV2(context.Background(), ip, linodego.IPAddressUpdateOptionsV2{ + updatedIP, err := base.Client.UpdateIPAddress(context.Background(), ip, linodego.IPAddressUpdateOptions{ Reserved: linodego.Pointer(true), }) assert.NoError(t, err, "Expected no error when updating IP address") diff --git a/test/unit/object_storage_bucket_cert_test.go b/test/unit/object_storage_bucket_cert_test.go index 137bed11f..83104747d 100644 --- a/test/unit/object_storage_bucket_cert_test.go +++ b/test/unit/object_storage_bucket_cert_test.go @@ -16,62 +16,19 @@ func TestObjectStorageBucketCert_Get(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketName := "my-bucket" - base.MockGet("object-storage/buckets/"+clusterID+"/"+bucketName+"/ssl", fixtureData) + base.MockGet("object-storage/buckets/"+regionID+"/"+bucketName+"/ssl", fixtureData) - cert, err := base.Client.GetObjectStorageBucketCert(context.Background(), clusterID, bucketName) - assert.NoError(t, err) - assert.NotNil(t, cert) - assert.True(t, cert.SSL) -} - -func TestObjectStorageBucketCert_Upload(t *testing.T) { - fixtureData, err := fixtures.GetFixture("object_storage_bucket_cert") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - clusterID := "us-east-1" - bucketName := "my-bucket" - - uploadOpts := linodego.ObjectStorageBucketCertUploadOptions{ - Certificate: "mock-cert", - PrivateKey: "mock-key", - } - - base.MockPost("object-storage/buckets/"+clusterID+"/"+bucketName+"/ssl", fixtureData) - - uploadedCert, err := base.Client.UploadObjectStorageBucketCert(context.Background(), clusterID, bucketName, uploadOpts) - assert.NoError(t, err) - assert.NotNil(t, uploadedCert) - assert.True(t, uploadedCert.SSL) -} - -func TestObjectStorageBucketCertV2_Get(t *testing.T) { - fixtureData, err := fixtures.GetFixture("object_storage_bucket_cert") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - clusterID := "us-east-1" - bucketName := "my-bucket" - - base.MockGet("object-storage/buckets/"+clusterID+"/"+bucketName+"/ssl", fixtureData) - - cert, err := base.Client.GetObjectStorageBucketCertV2(context.Background(), clusterID, bucketName) + cert, err := base.Client.GetObjectStorageBucketCert(context.Background(), regionID, bucketName) assert.NoError(t, err) assert.NotNil(t, cert) assert.NotNil(t, cert.SSL) assert.True(t, *cert.SSL) } -func TestObjectStorageBucketCertV2_Upload(t *testing.T) { +func TestObjectStorageBucketCert_Upload(t *testing.T) { fixtureData, err := fixtures.GetFixture("object_storage_bucket_cert") assert.NoError(t, err) @@ -79,7 +36,7 @@ func TestObjectStorageBucketCertV2_Upload(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketName := "my-bucket" uploadOpts := linodego.ObjectStorageBucketCertUploadOptions{ @@ -87,9 +44,9 @@ func TestObjectStorageBucketCertV2_Upload(t *testing.T) { PrivateKey: "mock-key", } - base.MockPost("object-storage/buckets/"+clusterID+"/"+bucketName+"/ssl", fixtureData) + base.MockPost("object-storage/buckets/"+regionID+"/"+bucketName+"/ssl", fixtureData) - uploadedCert, err := base.Client.UploadObjectStorageBucketCertV2(context.Background(), clusterID, bucketName, uploadOpts) + uploadedCert, err := base.Client.UploadObjectStorageBucketCert(context.Background(), regionID, bucketName, uploadOpts) assert.NoError(t, err) assert.NotNil(t, uploadedCert) assert.NotNil(t, uploadedCert.SSL) @@ -101,11 +58,11 @@ func TestObjectStorageBucketCert_Delete(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketName := "my-bucket" - base.MockDelete("object-storage/buckets/"+clusterID+"/"+bucketName+"/ssl", nil) + base.MockDelete("object-storage/buckets/"+regionID+"/"+bucketName+"/ssl", nil) - err := base.Client.DeleteObjectStorageBucketCert(context.Background(), clusterID, bucketName) + err := base.Client.DeleteObjectStorageBucketCert(context.Background(), regionID, bucketName) assert.NoError(t, err) } diff --git a/test/unit/object_storage_bucket_test.go b/test/unit/object_storage_bucket_test.go index 9e807d312..aa5f16cc5 100644 --- a/test/unit/object_storage_bucket_test.go +++ b/test/unit/object_storage_bucket_test.go @@ -39,10 +39,10 @@ func TestObjectStorageBucket_ListInCluster(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" - base.MockGet("object-storage/buckets/"+clusterID, fixtureData) + regionID := "us-east" + base.MockGet("object-storage/buckets/"+regionID, fixtureData) - buckets, err := base.Client.ListObjectStorageBucketsInCluster(context.Background(), nil, clusterID) + buckets, err := base.Client.ListObjectStorageBucketsInRegion(context.Background(), nil, regionID) assert.NoError(t, err) assert.NotEmpty(t, buckets) } @@ -55,12 +55,12 @@ func TestObjectStorageBucket_Get(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketLabel := "my-bucket" - base.MockGet("object-storage/buckets/"+clusterID+"/"+bucketLabel, fixtureData) + base.MockGet("object-storage/buckets/"+regionID+"/"+bucketLabel, fixtureData) - bucket, err := base.Client.GetObjectStorageBucket(context.Background(), clusterID, bucketLabel) + bucket, err := base.Client.GetObjectStorageBucket(context.Background(), regionID, bucketLabel) assert.NoError(t, err) assert.NotNil(t, bucket) assert.Equal(t, bucketLabel, bucket.Label) @@ -92,12 +92,12 @@ func TestObjectStorageBucket_Delete(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketLabel := "my-bucket" - base.MockDelete("object-storage/buckets/"+clusterID+"/"+bucketLabel, nil) + base.MockDelete("object-storage/buckets/"+regionID+"/"+bucketLabel, nil) - err := base.Client.DeleteObjectStorageBucket(context.Background(), clusterID, bucketLabel) + err := base.Client.DeleteObjectStorageBucket(context.Background(), regionID, bucketLabel) assert.NoError(t, err) } @@ -109,12 +109,12 @@ func TestObjectStorageBucket_GetAccess(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketLabel := "my-bucket" - base.MockGet("object-storage/buckets/"+clusterID+"/"+bucketLabel+"/access", fixtureData) + base.MockGet("object-storage/buckets/"+regionID+"/"+bucketLabel+"/access", fixtureData) - access, err := base.Client.GetObjectStorageBucketAccess(context.Background(), clusterID, bucketLabel) + access, err := base.Client.GetObjectStorageBucketAccess(context.Background(), regionID, bucketLabel) assert.NoError(t, err) assert.NotNil(t, access) assert.Equal(t, linodego.ACLPublicRead, access.ACL) @@ -125,16 +125,16 @@ func TestObjectStorageBucket_UpdateAccess(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketLabel := "my-bucket" updateOpts := linodego.ObjectStorageBucketUpdateAccessOptions{ ACL: linodego.ACLPrivate, } - base.MockPost("object-storage/buckets/"+clusterID+"/"+bucketLabel+"/access", nil) + base.MockPost("object-storage/buckets/"+regionID+"/"+bucketLabel+"/access", nil) - err := base.Client.UpdateObjectStorageBucketAccess(context.Background(), clusterID, bucketLabel, updateOpts) + err := base.Client.UpdateObjectStorageBucketAccess(context.Background(), regionID, bucketLabel, updateOpts) assert.NoError(t, err) } @@ -146,12 +146,12 @@ func TestObjectStorageBucket_ListContents(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - clusterID := "us-east-1" + regionID := "us-east" bucketLabel := "my-bucket" - base.MockGet("object-storage/buckets/"+clusterID+"/"+bucketLabel+"/object-list", fixtureData) + base.MockGet("object-storage/buckets/"+regionID+"/"+bucketLabel+"/object-list", fixtureData) - contents, err := base.Client.ListObjectStorageBucketContents(context.Background(), clusterID, bucketLabel, nil) + contents, err := base.Client.ListObjectStorageBucketContents(context.Background(), regionID, bucketLabel, nil) assert.NoError(t, err) assert.NotNil(t, contents) assert.True(t, contents.IsTruncated) diff --git a/test/unit/object_storage_cluster_test.go b/test/unit/object_storage_cluster_test.go deleted file mode 100644 index 25aaf549d..000000000 --- a/test/unit/object_storage_cluster_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package unit - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestObjectStorageCluster_List(t *testing.T) { - fixtureData, err := fixtures.GetFixture("object_storage_cluster_list") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockGet("object-storage/clusters", fixtureData) - - clusters, err := base.Client.ListObjectStorageClusters(context.Background(), nil) - assert.NoError(t, err) - assert.Len(t, clusters, 1) - - assert.Equal(t, "us-east-1", clusters[0].Region) - assert.Equal(t, "active", clusters[0].Status) - assert.Equal(t, "my-cluster-id", clusters[0].ID) - assert.Equal(t, "example.com", clusters[0].Domain) - assert.Equal(t, "static.example.com", clusters[0].StaticSiteDomain) -} - -func TestObjectStorageCluster_Get(t *testing.T) { - fixtureData, err := fixtures.GetFixture("object_storage_cluster_get") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockGet("object-storage/clusters/my-cluster-id", fixtureData) - - cluster, err := base.Client.GetObjectStorageCluster(context.Background(), "my-cluster-id") - assert.NoError(t, err) - assert.NotNil(t, cluster) - - assert.Equal(t, "us-east-1", cluster.Region) - assert.Equal(t, "active", cluster.Status) - assert.Equal(t, "my-cluster-id", cluster.ID) - assert.Equal(t, "example.com", cluster.Domain) - assert.Equal(t, "static.example.com", cluster.StaticSiteDomain) -} diff --git a/test/unit/object_storage_object_test.go b/test/unit/object_storage_object_test.go index 35da889ee..5c202d32b 100644 --- a/test/unit/object_storage_object_test.go +++ b/test/unit/object_storage_object_test.go @@ -31,7 +31,7 @@ func TestObjectStorageObjectURL_Create(t *testing.T) { assert.True(t, urlResponse.Exists) } -func TestObjectStorageObjectACLConfigV2_Get(t *testing.T) { +func TestObjectStorageObjectACLConfig_Get(t *testing.T) { fixtureData, err := fixtures.GetFixture("object_storage_object_acl_get") assert.NoError(t, err) @@ -41,13 +41,13 @@ func TestObjectStorageObjectACLConfigV2_Get(t *testing.T) { base.MockGet("object-storage/buckets/my-bucket/test-label/object-acl?name=test-object", fixtureData) - aclConfig, err := base.Client.GetObjectStorageObjectACLConfigV2(context.Background(), "my-bucket", "test-label", "test-object") + aclConfig, err := base.Client.GetObjectStorageObjectACLConfig(context.Background(), "my-bucket", "test-label", "test-object") assert.NoError(t, err) assert.NotNil(t, aclConfig.ACL) assert.Equal(t, "public-read", *aclConfig.ACL) } -func TestObjectStorageObjectACLConfigV2_Update(t *testing.T) { +func TestObjectStorageObjectACLConfig_Update(t *testing.T) { fixtureData, err := fixtures.GetFixture("object_storage_object_acl_update") assert.NoError(t, err) @@ -62,7 +62,7 @@ func TestObjectStorageObjectACLConfigV2_Update(t *testing.T) { base.MockPut("object-storage/buckets/my-bucket/test-label/object-acl", fixtureData) - updatedACLConfig, err := base.Client.UpdateObjectStorageObjectACLConfigV2(context.Background(), "my-bucket", "test-label", updateOptions) + updatedACLConfig, err := base.Client.UpdateObjectStorageObjectACLConfig(context.Background(), "my-bucket", "test-label", updateOptions) assert.NoError(t, err) assert.NotNil(t, updatedACLConfig.ACL) assert.Equal(t, "private", *updatedACLConfig.ACL) From cdec5532185631ce08fae606b117d125e2f1c7fc Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Tue, 5 May 2026 15:40:46 -0400 Subject: [PATCH 03/17] TPT-4414: Refactor JSON tags to use "omitzero" for optional fields across multiple files (#947) * Refactor JSON struct tags to use "omitzero" for optional fields * Remove url tags in pagination structs --- account.go | 24 ++--- account_agreements.go | 6 +- account_payments.go | 2 +- account_settings.go | 6 +- account_user_grants.go | 22 ++--- account_users.go | 6 +- databases.go | 6 +- domain_records.go | 34 +++---- domains.go | 32 +++---- firewall_rules.go | 18 ++-- firewall_rulesets.go | 10 +-- firewalls.go | 26 +++--- image_sharegroups_consumer.go | 2 +- image_sharegroups_producer.go | 16 ++-- images.go | 22 ++--- instance_config_interfaces.go | 46 +++++----- instance_configs.go | 164 +++++++++++++++++----------------- instance_disks.go | 16 ++-- instance_ips.go | 2 +- instances.go | 122 ++++++++++++------------- interfaces.go | 68 +++++++------- lke_clusters.go | 22 ++--- lke_clusters_control_plane.go | 18 ++-- lke_node_pools.go | 40 ++++----- monitor_alert_definitions.go | 48 +++++----- monitor_api_services.go | 8 +- mysql.go | 86 +++++++++--------- network_ips.go | 10 +-- network_ranges.go | 4 +- nodebalancer.go | 32 +++---- nodebalancer_config_nodes.go | 16 ++-- nodebalancer_config_vpc.go | 2 +- nodebalancer_configs.go | 64 ++++++------- object_storage_buckets.go | 14 +-- object_storage_keys.go | 10 +-- object_storage_object.go | 6 +- pagination.go | 6 +- placement_groups.go | 4 +- postgres.go | 126 +++++++++++++------------- profile.go | 18 ++-- request_helpers.go | 6 +- stackscripts.go | 6 +- tags.go | 10 +-- volumes.go | 22 ++--- vpc.go | 14 +-- vpc_subnet.go | 4 +- 46 files changed, 623 insertions(+), 623 deletions(-) diff --git a/account.go b/account.go index 9201fd62c..15b3d4073 100644 --- a/account.go +++ b/account.go @@ -34,18 +34,18 @@ type Account struct { // AccountUpdateOptions fields are those accepted by UpdateAccount type AccountUpdateOptions struct { - Address1 string `json:"address_1,omitempty"` - Address2 string `json:"address_2,omitempty"` - City string `json:"city,omitempty"` - Company string `json:"company,omitempty"` - Country string `json:"country,omitempty"` - Email string `json:"email,omitempty"` - FirstName string `json:"first_name,omitempty"` - LastName string `json:"last_name,omitempty"` - Phone string `json:"phone,omitempty"` - State string `json:"state,omitempty"` - TaxID string `json:"tax_id,omitempty"` - Zip string `json:"zip,omitempty"` + Address1 string `json:"address_1,omitzero"` + Address2 string `json:"address_2,omitzero"` + City string `json:"city,omitzero"` + Company string `json:"company,omitzero"` + Country string `json:"country,omitzero"` + Email string `json:"email,omitzero"` + FirstName string `json:"first_name,omitzero"` + LastName string `json:"last_name,omitzero"` + Phone string `json:"phone,omitzero"` + State string `json:"state,omitzero"` + TaxID string `json:"tax_id,omitzero"` + Zip string `json:"zip,omitzero"` } // GetUpdateOptions converts an Account to AccountUpdateOptions for use in UpdateAccount diff --git a/account_agreements.go b/account_agreements.go index 795244a4a..1c4272651 100644 --- a/account_agreements.go +++ b/account_agreements.go @@ -11,9 +11,9 @@ type AccountAgreements struct { // AccountAgreementsUpdateOptions fields are those accepted by UpdateAccountAgreements type AccountAgreementsUpdateOptions struct { - EUModel bool `json:"eu_model,omitempty"` - MasterServiceAgreement bool `json:"master_service_agreement,omitempty"` - PrivacyPolicy bool `json:"privacy_policy,omitempty"` + EUModel bool `json:"eu_model,omitzero"` + MasterServiceAgreement bool `json:"master_service_agreement,omitzero"` + PrivacyPolicy bool `json:"privacy_policy,omitzero"` } // GetUpdateOptions converts an AccountAgreements to AccountAgreementsUpdateOptions for use in UpdateAccountAgreements diff --git a/account_payments.go b/account_payments.go index af2488e9e..6cf3d4384 100644 --- a/account_payments.go +++ b/account_payments.go @@ -23,7 +23,7 @@ type Payment struct { // PaymentCreateOptions fields are those accepted by CreatePayment type PaymentCreateOptions struct { // CVV (Card Verification Value) of the credit card to be used for the Payment - CVV string `json:"cvv,omitempty"` + CVV string `json:"cvv,omitzero"` // The amount, in US dollars, of the Payment USD json.Number `json:"usd"` diff --git a/account_settings.go b/account_settings.go index 5b487d199..068e0847f 100644 --- a/account_settings.go +++ b/account_settings.go @@ -40,17 +40,17 @@ type AccountSettings struct { // AccountSettingsUpdateOptions are the updateable account wide flags or plans that effect new resources. type AccountSettingsUpdateOptions struct { // The default backups enrollment status for all new Linodes for all users on the account. When enabled, backups are mandatory per instance. - BackupsEnabled *bool `json:"backups_enabled,omitempty"` + BackupsEnabled *bool `json:"backups_enabled,omitzero"` // The default network helper setting for all new Linodes and Linode Configs for all users on the account. - NetworkHelper *bool `json:"network_helper,omitempty"` + NetworkHelper *bool `json:"network_helper,omitzero"` // NOTE: Interfaces for new linode setting may not currently be available to all users. // A new configuration flag defines whether new Linodes can use Linode and/or legacy config interfaces. InterfacesForNewLinodes *InterfacesForNewLinodes `json:"interfaces_for_new_linodes"` // The slug of the maintenance policy to set the account to. - MaintenancePolicy *string `json:"maintenance_policy,omitempty"` + MaintenancePolicy *string `json:"maintenance_policy,omitzero"` } // GetAccountSettings gets the account wide flags or plans that effect new resources diff --git a/account_user_grants.go b/account_user_grants.go index 5314c79b9..ea00a4110 100644 --- a/account_user_grants.go +++ b/account_user_grants.go @@ -56,17 +56,17 @@ type UserGrants struct { } type UserGrantsUpdateOptions struct { - Database []GrantedEntity `json:"database,omitempty"` - Domain []EntityUserGrant `json:"domain,omitempty"` - Firewall []EntityUserGrant `json:"firewall,omitempty"` - Image []EntityUserGrant `json:"image,omitempty"` - Linode []EntityUserGrant `json:"linode,omitempty"` - Longview []EntityUserGrant `json:"longview,omitempty"` - NodeBalancer []EntityUserGrant `json:"nodebalancer,omitempty"` - PlacementGroup []EntityUserGrant `json:"placement_group,omitempty"` - StackScript []EntityUserGrant `json:"stackscript,omitempty"` - Volume []EntityUserGrant `json:"volume,omitempty"` - VPC []EntityUserGrant `json:"vpc,omitempty"` + Database []GrantedEntity `json:"database,omitzero"` + Domain []EntityUserGrant `json:"domain,omitzero"` + Firewall []EntityUserGrant `json:"firewall,omitzero"` + Image []EntityUserGrant `json:"image,omitzero"` + Linode []EntityUserGrant `json:"linode,omitzero"` + Longview []EntityUserGrant `json:"longview,omitzero"` + NodeBalancer []EntityUserGrant `json:"nodebalancer,omitzero"` + PlacementGroup []EntityUserGrant `json:"placement_group,omitzero"` + StackScript []EntityUserGrant `json:"stackscript,omitzero"` + Volume []EntityUserGrant `json:"volume,omitzero"` + VPC []EntityUserGrant `json:"vpc,omitzero"` Global GlobalUserGrants `json:"global"` } diff --git a/account_users.go b/account_users.go index 13e71c520..73cb099e9 100644 --- a/account_users.go +++ b/account_users.go @@ -45,9 +45,9 @@ type UserCreateOptions struct { // UserUpdateOptions fields are those accepted by UpdateUser type UserUpdateOptions struct { - Username string `json:"username,omitempty"` - Restricted *bool `json:"restricted,omitempty"` - Email string `json:"email,omitempty"` + Username string `json:"username,omitzero"` + Restricted *bool `json:"restricted,omitzero"` + Email string `json:"email,omitzero"` } // UnmarshalJSON implements the json.Unmarshaler interface diff --git a/databases.go b/databases.go index ead5317eb..5d05eed98 100644 --- a/databases.go +++ b/databases.go @@ -90,7 +90,7 @@ type Database struct { Updated *time.Time `json:"-"` OldestRestoreTime *time.Time `json:"-"` - PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitempty"` + PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitzero"` } // DatabaseHost for Primary/Secondary of Database @@ -119,7 +119,7 @@ type DatabaseMaintenanceWindow struct { Frequency DatabaseMaintenanceFrequency `json:"frequency"` HourOfDay int `json:"hour_of_day"` - Pending []DatabaseMaintenanceWindowPending `json:"pending,omitempty"` + Pending []DatabaseMaintenanceWindowPending `json:"pending,omitzero"` } type DatabaseMaintenanceWindowPending struct { @@ -161,7 +161,7 @@ type ClusterPrice struct { // DatabaseFork describes the source and restore time for the fork for forked DBs type DatabaseFork struct { Source int `json:"source"` - RestoreTime *time.Time `json:"-,omitempty"` + RestoreTime *time.Time `json:"-,omitzero"` } func (d *Database) UnmarshalJSON(b []byte) error { diff --git a/domain_records.go b/domain_records.go index 2d8865e66..79bc18f0e 100644 --- a/domain_records.go +++ b/domain_records.go @@ -30,27 +30,27 @@ type DomainRecordCreateOptions struct { Type DomainRecordType `json:"type"` Name string `json:"name"` Target string `json:"target"` - Priority *int `json:"priority,omitempty"` - Weight *int `json:"weight,omitempty"` - Port *int `json:"port,omitempty"` - Service *string `json:"service,omitempty"` - Protocol *string `json:"protocol,omitempty"` - TTLSec int `json:"ttl_sec,omitempty"` // 0 is not accepted by Linode, so can be omitted - Tag *string `json:"tag,omitempty"` + Priority *int `json:"priority,omitzero"` + Weight *int `json:"weight,omitzero"` + Port *int `json:"port,omitzero"` + Service *string `json:"service,omitzero"` + Protocol *string `json:"protocol,omitzero"` + TTLSec int `json:"ttl_sec,omitzero"` // 0 is not accepted by Linode, so can be omitted + Tag *string `json:"tag,omitzero"` } // DomainRecordUpdateOptions fields are those accepted by UpdateDomainRecord type DomainRecordUpdateOptions struct { - Type DomainRecordType `json:"type,omitempty"` - Name string `json:"name,omitempty"` - Target string `json:"target,omitempty"` - Priority *int `json:"priority,omitempty"` // 0 is valid, so omit only nil values - Weight *int `json:"weight,omitempty"` // 0 is valid, so omit only nil values - Port *int `json:"port,omitempty"` // 0 is valid to spec, so omit only nil values - Service *string `json:"service,omitempty"` - Protocol *string `json:"protocol,omitempty"` - TTLSec int `json:"ttl_sec,omitempty"` // 0 is not accepted by Linode, so can be omitted - Tag *string `json:"tag,omitempty"` + Type DomainRecordType `json:"type,omitzero"` + Name string `json:"name,omitzero"` + Target string `json:"target,omitzero"` + Priority *int `json:"priority,omitzero"` // 0 is valid, so omit only nil values + Weight *int `json:"weight,omitzero"` // 0 is valid, so omit only nil values + Port *int `json:"port,omitzero"` // 0 is valid to spec, so omit only nil values + Service *string `json:"service,omitzero"` + Protocol *string `json:"protocol,omitzero"` + TTLSec int `json:"ttl_sec,omitzero"` // 0 is not accepted by Linode, so can be omitted + Tag *string `json:"tag,omitzero"` } // DomainRecordType constants start with RecordType and include Linode API Domain Record Types diff --git a/domains.go b/domains.go index d8993c35d..9ca0e1e69 100644 --- a/domains.go +++ b/domains.go @@ -63,17 +63,17 @@ type DomainCreateOptions struct { // Used to control whether this Domain is currently being rendered. // Enum:"disabled" "active" "edit_mode" "has_errors" - Status DomainStatus `json:"status,omitempty"` + Status DomainStatus `json:"status,omitzero"` // A description for this Domain. This is for display purposes only. - Description string `json:"description,omitempty"` + Description string `json:"description,omitzero"` // Start of Authority email address. This is required for master Domains. - SOAEmail string `json:"soa_email,omitempty"` + SOAEmail string `json:"soa_email,omitzero"` // The interval, in seconds, at which a failed refresh should be retried. // Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - RetrySec int `json:"retry_sec,omitempty"` + RetrySec int `json:"retry_sec,omitzero"` // The IP addresses representing the master DNS for this Domain. MasterIPs []string `json:"master_ips"` @@ -85,37 +85,37 @@ type DomainCreateOptions struct { Tags []string `json:"tags"` // The amount of time in seconds that may pass before this Domain is no longer authoritative. Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - ExpireSec int `json:"expire_sec,omitempty"` + ExpireSec int `json:"expire_sec,omitzero"` // The amount of time in seconds before this Domain should be refreshed. Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - RefreshSec int `json:"refresh_sec,omitempty"` + RefreshSec int `json:"refresh_sec,omitzero"` // "Time to Live" - the amount of time in seconds that this Domain's records may be cached by resolvers or other domain servers. Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - TTLSec int `json:"ttl_sec,omitempty"` + TTLSec int `json:"ttl_sec,omitzero"` } // DomainUpdateOptions converts a Domain to DomainUpdateOptions for use in UpdateDomain type DomainUpdateOptions struct { // The domain this Domain represents. These must be unique in our system; you cannot have two Domains representing the same domain. - Domain string `json:"domain,omitempty"` + Domain string `json:"domain,omitzero"` // If this Domain represents the authoritative source of information for the domain it describes, or if it is a read-only copy of a master (also called a slave). // Enum:"master" "slave" - Type DomainType `json:"type,omitempty"` + Type DomainType `json:"type,omitzero"` // Used to control whether this Domain is currently being rendered. // Enum:"disabled" "active" "edit_mode" "has_errors" - Status DomainStatus `json:"status,omitempty"` + Status DomainStatus `json:"status,omitzero"` // A description for this Domain. This is for display purposes only. - Description string `json:"description,omitempty"` + Description string `json:"description,omitzero"` // Start of Authority email address. This is required for master Domains. - SOAEmail string `json:"soa_email,omitempty"` + SOAEmail string `json:"soa_email,omitzero"` // The interval, in seconds, at which a failed refresh should be retried. // Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - RetrySec int `json:"retry_sec,omitempty"` + RetrySec int `json:"retry_sec,omitzero"` // The IP addresses representing the master DNS for this Domain. MasterIPs []string `json:"master_ips"` @@ -127,13 +127,13 @@ type DomainUpdateOptions struct { Tags []string `json:"tags"` // The amount of time in seconds that may pass before this Domain is no longer authoritative. Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - ExpireSec int `json:"expire_sec,omitempty"` + ExpireSec int `json:"expire_sec,omitzero"` // The amount of time in seconds before this Domain should be refreshed. Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - RefreshSec int `json:"refresh_sec,omitempty"` + RefreshSec int `json:"refresh_sec,omitzero"` // "Time to Live" - the amount of time in seconds that this Domain's records may be cached by resolvers or other domain servers. Valid values are 300, 3600, 7200, 14400, 28800, 57600, 86400, 172800, 345600, 604800, 1209600, and 2419200 - any other value will be rounded to the nearest valid value. - TTLSec int `json:"ttl_sec,omitempty"` + TTLSec int `json:"ttl_sec,omitzero"` } // DomainType constants start with DomainType and include Linode API Domain Type values diff --git a/firewall_rules.go b/firewall_rules.go index b394ed1f0..c6bde2bd1 100644 --- a/firewall_rules.go +++ b/firewall_rules.go @@ -18,8 +18,8 @@ const ( // NetworkAddresses are arrays of ipv4 and v6 addresses type NetworkAddresses struct { - IPv4 *[]string `json:"ipv4,omitempty"` - IPv6 *[]string `json:"ipv6,omitempty"` + IPv4 *[]string `json:"ipv4,omitzero"` + IPv6 *[]string `json:"ipv6,omitzero"` } // A FirewallRule is a whitelist of ports, protocols, and addresses for which traffic should be allowed. @@ -28,15 +28,15 @@ type NetworkAddresses struct { type FirewallRule struct { Action string `json:"action"` Label string `json:"label"` - Description string `json:"description,omitempty"` - Ports string `json:"ports,omitempty"` + Description string `json:"description,omitzero"` + Ports string `json:"ports,omitzero"` Protocol NetworkProtocol `json:"protocol"` Addresses NetworkAddresses `json:"addresses"` // FirewallRule references one `Rule Set` by ID. When provided, this entry // represents a reference and should be mutually exclusive with ordinary // rule fields according to the API contract. - RuleSet int `json:"ruleset,omitempty"` + RuleSet int `json:"ruleset,omitzero"` } // MarshalJSON ensures that when a rule references a Rule Set (RuleSet != 0), @@ -54,8 +54,8 @@ func (r FirewallRule) MarshalJSON() ([]byte, error) { type normal struct { Action string `json:"action"` Label string `json:"label"` - Description string `json:"description,omitempty"` - Ports string `json:"ports,omitempty"` + Description string `json:"description,omitzero"` + Ports string `json:"ports,omitzero"` Protocol NetworkProtocol `json:"protocol"` Addresses NetworkAddresses `json:"addresses"` } @@ -79,9 +79,9 @@ type FirewallRuleSet struct { // TODO: separate request and response types in linodego v2 // read-only, can't be used in creating or updating a Firewall - Version int `json:"version,omitempty"` + Version int `json:"version,omitzero"` // read-only, can't be used in creating or updating a Firewall - Fingerprint string `json:"fingerprint,omitempty"` + Fingerprint string `json:"fingerprint,omitzero"` } // GetFirewallRules gets the FirewallRuleSet for the given Firewall. diff --git a/firewall_rulesets.go b/firewall_rulesets.go index c702d3b9b..097c25c81 100644 --- a/firewall_rulesets.go +++ b/firewall_rulesets.go @@ -22,7 +22,7 @@ const ( type RuleSet struct { ID int `json:"id"` Label string `json:"label"` - Description string `json:"description,omitempty"` + Description string `json:"description,omitzero"` Type FirewallRuleSetType `json:"type"` Rules []FirewallRule `json:"rules"` IsServiceDefined bool `json:"is_service_defined"` @@ -69,7 +69,7 @@ func (r *RuleSet) UnmarshalJSON(b []byte) error { // RuleSetCreateOptions fields accepted by CreateRuleSet. type RuleSetCreateOptions struct { Label string `json:"label"` - Description string `json:"description,omitempty"` + Description string `json:"description,omitzero"` Type FirewallRuleSetType `json:"type"` Rules []FirewallRule `json:"rules"` } @@ -78,9 +78,9 @@ type RuleSetCreateOptions struct { // Omit a top-level field to leave it unchanged. If Rules is provided, it // replaces the entire ordered rules array. type RuleSetUpdateOptions struct { - Label *string `json:"label,omitempty"` - Description *string `json:"description,omitempty"` - Rules *[]FirewallRule `json:"rules,omitempty"` + Label *string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` + Rules *[]FirewallRule `json:"rules,omitzero"` } // ListFirewallRuleSets returns a paginated list of Rule Sets. diff --git a/firewalls.go b/firewalls.go index 1c698e1cc..abf503414 100644 --- a/firewalls.go +++ b/firewalls.go @@ -32,24 +32,24 @@ type Firewall struct { // DevicesCreationOptions fields are used when adding devices during the Firewall creation process. type DevicesCreationOptions struct { - Linodes []int `json:"linodes,omitempty"` - NodeBalancers []int `json:"nodebalancers,omitempty"` - LinodeInterfaces []int `json:"linode_interfaces,omitempty"` + Linodes []int `json:"linodes,omitzero"` + NodeBalancers []int `json:"nodebalancers,omitzero"` + LinodeInterfaces []int `json:"linode_interfaces,omitzero"` } // FirewallCreateOptions fields are those accepted by CreateFirewall type FirewallCreateOptions struct { - Label string `json:"label,omitempty"` + Label string `json:"label,omitzero"` Rules FirewallRuleSet `json:"rules"` - Tags []string `json:"tags,omitempty"` + Tags []string `json:"tags,omitzero"` Devices DevicesCreationOptions `json:"devices,omitzero"` } // FirewallUpdateOptions is an options struct used when Updating a Firewall type FirewallUpdateOptions struct { - Label string `json:"label,omitempty"` - Status FirewallStatus `json:"status,omitempty"` - Tags *[]string `json:"tags,omitempty"` + Label string `json:"label,omitzero"` + Status FirewallStatus `json:"status,omitzero"` + Tags *[]string `json:"tags,omitzero"` } // FirewallSettings represents the default firewalls for Linodes, @@ -67,14 +67,14 @@ type DefaultFirewallIDs struct { // FirewallSettingsUpdateOptions is an options struct used when Updating FirewallSettings type FirewallSettingsUpdateOptions struct { - DefaultFirewallIDs *DefaultFirewallIDsOptions `json:"default_firewall_ids,omitempty"` + DefaultFirewallIDs *DefaultFirewallIDsOptions `json:"default_firewall_ids,omitzero"` } type DefaultFirewallIDsOptions struct { - Linode **int `json:"linode,omitempty"` - NodeBalancer **int `json:"nodebalancer,omitempty"` - PublicInterface **int `json:"public_interface,omitempty"` - VPCInterface **int `json:"vpc_interface,omitempty"` + Linode **int `json:"linode,omitzero"` + NodeBalancer **int `json:"nodebalancer,omitzero"` + PublicInterface **int `json:"public_interface,omitzero"` + VPCInterface **int `json:"vpc_interface,omitzero"` } // GetUpdateOptions converts a Firewall to FirewallUpdateOptions for use in Client.UpdateFirewall. diff --git a/image_sharegroups_consumer.go b/image_sharegroups_consumer.go index e9150b667..4dd1faa87 100644 --- a/image_sharegroups_consumer.go +++ b/image_sharegroups_consumer.go @@ -125,7 +125,7 @@ func (t *ImageShareGroupCreateTokenResponse) UnmarshalJSON(b []byte) error { // ImageShareGroupCreateTokenOptions fields are those accepted by ImageShareGroupCreateToken type ImageShareGroupCreateTokenOptions struct { - Label *string `json:"label,omitempty"` + Label *string `json:"label,omitzero"` ValidForShareGroupUUID string `json:"valid_for_sharegroup_uuid"` } diff --git a/image_sharegroups_producer.go b/image_sharegroups_producer.go index 9d21392b2..555ecb1cb 100644 --- a/image_sharegroups_producer.go +++ b/image_sharegroups_producer.go @@ -50,14 +50,14 @@ func (isg *ProducerImageShareGroup) UnmarshalJSON(b []byte) error { // ImageShareGroupCreateOptions fields are those accepted by CreateImageShareGroup. type ImageShareGroupCreateOptions struct { Label string `json:"label"` - Description *string `json:"description,omitempty"` - Images []ImageShareGroupImage `json:"images,omitempty"` + Description *string `json:"description,omitzero"` + Images []ImageShareGroupImage `json:"images,omitzero"` } // ImageShareGroupUpdateOptions fields are those accepted by UpdateImageShareGroup. type ImageShareGroupUpdateOptions struct { - Label *string `json:"label,omitempty"` - Description *string `json:"description,omitempty"` + Label *string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` } // ImageShareGroupAddImagesOptions fields are those accepted by ImageShareGroupAddImages. @@ -67,15 +67,15 @@ type ImageShareGroupAddImagesOptions struct { // ImageShareGroupUpdateImageOptions fields are those accepted by ImageShareGroupUpdateImage. type ImageShareGroupUpdateImageOptions struct { - Label *string `json:"label,omitempty"` - Description *string `json:"description,omitempty"` + Label *string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` } // ImageShareGroupImage represents an Image to be included in a ProducerImageShareGroup. type ImageShareGroupImage struct { ID string `json:"id"` - Label *string `json:"label,omitempty"` - Description *string `json:"description,omitempty"` + Label *string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` } // ImageShareGroupMember represents a Member of an ImageShareGroup owned by the producer. diff --git a/images.go b/images.go index da2287047..57203047e 100644 --- a/images.go +++ b/images.go @@ -117,16 +117,16 @@ type ImageShareEntry struct { type ImageCreateOptions struct { DiskID int `json:"disk_id"` Label string `json:"label"` - Description string `json:"description,omitempty"` - CloudInit bool `json:"cloud_init,omitempty"` - Tags *[]string `json:"tags,omitempty"` + Description string `json:"description,omitzero"` + CloudInit bool `json:"cloud_init,omitzero"` + Tags *[]string `json:"tags,omitzero"` } // ImageUpdateOptions fields are those accepted by UpdateImage type ImageUpdateOptions struct { - Label string `json:"label,omitempty"` - Description *string `json:"description,omitempty"` - Tags *[]string `json:"tags,omitempty"` + Label string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` + Tags *[]string `json:"tags,omitzero"` } // ImageReplicateOptions represents the options accepted by the @@ -145,18 +145,18 @@ type ImageCreateUploadResponse struct { type ImageCreateUploadOptions struct { Region string `json:"region"` Label string `json:"label"` - Description string `json:"description,omitempty"` - CloudInit bool `json:"cloud_init,omitempty"` - Tags *[]string `json:"tags,omitempty"` + Description string `json:"description,omitzero"` + CloudInit bool `json:"cloud_init,omitzero"` + Tags *[]string `json:"tags,omitzero"` } // ImageUploadOptions fields are those accepted by UploadImage type ImageUploadOptions struct { Region string `json:"region"` Label string `json:"label"` - Description string `json:"description,omitempty"` + Description string `json:"description,omitzero"` CloudInit bool `json:"cloud_init"` - Tags *[]string `json:"tags,omitempty"` + Tags *[]string `json:"tags,omitzero"` Image io.Reader } diff --git a/instance_config_interfaces.go b/instance_config_interfaces.go index c1c8735f8..be218402f 100644 --- a/instance_config_interfaces.go +++ b/instance_config_interfaces.go @@ -45,31 +45,31 @@ type InstanceConfigInterfaceIPv6Range struct { } type VPCIPv4 struct { - VPC string `json:"vpc,omitempty"` - NAT1To1 *string `json:"nat_1_1,omitempty"` + VPC string `json:"vpc,omitzero"` + NAT1To1 *string `json:"nat_1_1,omitzero"` } type InstanceConfigInterfaceCreateOptions struct { - IPAMAddress string `json:"ipam_address,omitempty"` - Label string `json:"label,omitempty"` - Purpose ConfigInterfacePurpose `json:"purpose,omitempty"` - Primary bool `json:"primary,omitempty"` - SubnetID *int `json:"subnet_id,omitempty"` - IPv4 *VPCIPv4 `json:"ipv4,omitempty"` + IPAMAddress string `json:"ipam_address,omitzero"` + Label string `json:"label,omitzero"` + Purpose ConfigInterfacePurpose `json:"purpose,omitzero"` + Primary bool `json:"primary,omitzero"` + SubnetID *int `json:"subnet_id,omitzero"` + IPv4 *VPCIPv4 `json:"ipv4,omitzero"` // NOTE: IPv6 interfaces may not currently be available to all users. - IPv6 *InstanceConfigInterfaceCreateOptionsIPv6 `json:"ipv6,omitempty"` + IPv6 *InstanceConfigInterfaceCreateOptionsIPv6 `json:"ipv6,omitzero"` - IPRanges []string `json:"ip_ranges,omitempty"` + IPRanges []string `json:"ip_ranges,omitzero"` } // InstanceConfigInterfaceCreateOptionsIPv6 represents the IPv6 configuration of a Linode interface // specified during creation. // NOTE: IPv6 interfaces may not currently be available to all users. type InstanceConfigInterfaceCreateOptionsIPv6 struct { - SLAAC []InstanceConfigInterfaceCreateOptionsIPv6SLAAC `json:"slaac,omitempty"` - Ranges []InstanceConfigInterfaceCreateOptionsIPv6Range `json:"ranges,omitempty"` - IsPublic *bool `json:"is_public,omitempty"` + SLAAC []InstanceConfigInterfaceCreateOptionsIPv6SLAAC `json:"slaac,omitzero"` + Ranges []InstanceConfigInterfaceCreateOptionsIPv6Range `json:"ranges,omitzero"` + IsPublic *bool `json:"is_public,omitzero"` } // InstanceConfigInterfaceCreateOptionsIPv6SLAAC represents a single IPv6 SLAAC of a Linode interface @@ -83,40 +83,40 @@ type InstanceConfigInterfaceCreateOptionsIPv6SLAAC struct { // specified during creation. // NOTE: IPv6 interfaces may not currently be available to all users. type InstanceConfigInterfaceCreateOptionsIPv6Range struct { - Range *string `json:"range,omitempty"` + Range *string `json:"range,omitzero"` } type InstanceConfigInterfaceUpdateOptions struct { - Primary bool `json:"primary,omitempty"` - IPv4 *VPCIPv4 `json:"ipv4,omitempty"` + Primary bool `json:"primary,omitzero"` + IPv4 *VPCIPv4 `json:"ipv4,omitzero"` // NOTE: IPv6 interfaces may not currently be available to all users. - IPv6 *InstanceConfigInterfaceUpdateOptionsIPv6 `json:"ipv6,omitempty"` + IPv6 *InstanceConfigInterfaceUpdateOptionsIPv6 `json:"ipv6,omitzero"` - IPRanges *[]string `json:"ip_ranges,omitempty"` + IPRanges *[]string `json:"ip_ranges,omitzero"` } // InstanceConfigInterfaceUpdateOptionsIPv6 represents the IPv6 configuration of a Linode interface // specified during updates. // NOTE: IPv6 interfaces may not currently be available to all users. type InstanceConfigInterfaceUpdateOptionsIPv6 struct { - SLAAC *[]InstanceConfigInterfaceUpdateOptionsIPv6SLAAC `json:"slaac,omitempty"` - Ranges *[]InstanceConfigInterfaceUpdateOptionsIPv6Range `json:"ranges,omitempty"` - IsPublic *bool `json:"is_public,omitempty"` + SLAAC *[]InstanceConfigInterfaceUpdateOptionsIPv6SLAAC `json:"slaac,omitzero"` + Ranges *[]InstanceConfigInterfaceUpdateOptionsIPv6Range `json:"ranges,omitzero"` + IsPublic *bool `json:"is_public,omitzero"` } // InstanceConfigInterfaceUpdateOptionsIPv6SLAAC represents a single IPv6 SLAAC of a Linode interface // specified during updates. // NOTE: IPv6 interfaces may not currently be available to all users. type InstanceConfigInterfaceUpdateOptionsIPv6SLAAC struct { - Range *string `json:"range,omitempty"` + Range *string `json:"range,omitzero"` } // InstanceConfigInterfaceUpdateOptionsIPv6Range represents a single IPv6 ranges of a Linode interface // specified during updates. // NOTE: IPv6 interfaces may not currently be available to all users. type InstanceConfigInterfaceUpdateOptionsIPv6Range struct { - Range *string `json:"range,omitempty"` + Range *string `json:"range,omitzero"` } type InstanceConfigInterfacesReorderOptions struct { diff --git a/instance_configs.go b/instance_configs.go index 089cf882b..a59962dc2 100644 --- a/instance_configs.go +++ b/instance_configs.go @@ -28,81 +28,81 @@ type InstanceConfig struct { // InstanceConfigDevice contains either the DiskID or VolumeID assigned to a Config Device type InstanceConfigDevice struct { - DiskID int `json:"disk_id,omitempty"` - VolumeID int `json:"volume_id,omitempty"` + DiskID int `json:"disk_id,omitzero"` + VolumeID int `json:"volume_id,omitzero"` } // InstanceConfigDeviceMap contains SDA-SDH InstanceConfigDevice settings type InstanceConfigDeviceMap struct { // sda-sdz - SDA *InstanceConfigDevice `json:"sda,omitempty"` - SDB *InstanceConfigDevice `json:"sdb,omitempty"` - SDC *InstanceConfigDevice `json:"sdc,omitempty"` - SDD *InstanceConfigDevice `json:"sdd,omitempty"` - SDE *InstanceConfigDevice `json:"sde,omitempty"` - SDF *InstanceConfigDevice `json:"sdf,omitempty"` - SDG *InstanceConfigDevice `json:"sdg,omitempty"` - SDH *InstanceConfigDevice `json:"sdh,omitempty"` - SDI *InstanceConfigDevice `json:"sdi,omitempty"` - SDJ *InstanceConfigDevice `json:"sdj,omitempty"` - SDK *InstanceConfigDevice `json:"sdk,omitempty"` - SDL *InstanceConfigDevice `json:"sdl,omitempty"` - SDM *InstanceConfigDevice `json:"sdm,omitempty"` - SDN *InstanceConfigDevice `json:"sdn,omitempty"` - SDO *InstanceConfigDevice `json:"sdo,omitempty"` - SDP *InstanceConfigDevice `json:"sdp,omitempty"` - SDQ *InstanceConfigDevice `json:"sdq,omitempty"` - SDR *InstanceConfigDevice `json:"sdr,omitempty"` - SDS *InstanceConfigDevice `json:"sds,omitempty"` - SDT *InstanceConfigDevice `json:"sdt,omitempty"` - SDU *InstanceConfigDevice `json:"sdu,omitempty"` - SDV *InstanceConfigDevice `json:"sdv,omitempty"` - SDW *InstanceConfigDevice `json:"sdw,omitempty"` - SDX *InstanceConfigDevice `json:"sdx,omitempty"` - SDY *InstanceConfigDevice `json:"sdy,omitempty"` - SDZ *InstanceConfigDevice `json:"sdz,omitempty"` + SDA *InstanceConfigDevice `json:"sda,omitzero"` + SDB *InstanceConfigDevice `json:"sdb,omitzero"` + SDC *InstanceConfigDevice `json:"sdc,omitzero"` + SDD *InstanceConfigDevice `json:"sdd,omitzero"` + SDE *InstanceConfigDevice `json:"sde,omitzero"` + SDF *InstanceConfigDevice `json:"sdf,omitzero"` + SDG *InstanceConfigDevice `json:"sdg,omitzero"` + SDH *InstanceConfigDevice `json:"sdh,omitzero"` + SDI *InstanceConfigDevice `json:"sdi,omitzero"` + SDJ *InstanceConfigDevice `json:"sdj,omitzero"` + SDK *InstanceConfigDevice `json:"sdk,omitzero"` + SDL *InstanceConfigDevice `json:"sdl,omitzero"` + SDM *InstanceConfigDevice `json:"sdm,omitzero"` + SDN *InstanceConfigDevice `json:"sdn,omitzero"` + SDO *InstanceConfigDevice `json:"sdo,omitzero"` + SDP *InstanceConfigDevice `json:"sdp,omitzero"` + SDQ *InstanceConfigDevice `json:"sdq,omitzero"` + SDR *InstanceConfigDevice `json:"sdr,omitzero"` + SDS *InstanceConfigDevice `json:"sds,omitzero"` + SDT *InstanceConfigDevice `json:"sdt,omitzero"` + SDU *InstanceConfigDevice `json:"sdu,omitzero"` + SDV *InstanceConfigDevice `json:"sdv,omitzero"` + SDW *InstanceConfigDevice `json:"sdw,omitzero"` + SDX *InstanceConfigDevice `json:"sdx,omitzero"` + SDY *InstanceConfigDevice `json:"sdy,omitzero"` + SDZ *InstanceConfigDevice `json:"sdz,omitzero"` // sdaa-sdaz - SDAA *InstanceConfigDevice `json:"sdaa,omitempty"` - SDAB *InstanceConfigDevice `json:"sdab,omitempty"` - SDAC *InstanceConfigDevice `json:"sdac,omitempty"` - SDAD *InstanceConfigDevice `json:"sdad,omitempty"` - SDAE *InstanceConfigDevice `json:"sdae,omitempty"` - SDAF *InstanceConfigDevice `json:"sdaf,omitempty"` - SDAG *InstanceConfigDevice `json:"sdag,omitempty"` - SDAH *InstanceConfigDevice `json:"sdah,omitempty"` - SDAI *InstanceConfigDevice `json:"sdai,omitempty"` - SDAJ *InstanceConfigDevice `json:"sdaj,omitempty"` - SDAK *InstanceConfigDevice `json:"sdak,omitempty"` - SDAL *InstanceConfigDevice `json:"sdal,omitempty"` - SDAM *InstanceConfigDevice `json:"sdam,omitempty"` - SDAN *InstanceConfigDevice `json:"sdan,omitempty"` - SDAO *InstanceConfigDevice `json:"sdao,omitempty"` - SDAP *InstanceConfigDevice `json:"sdap,omitempty"` - SDAQ *InstanceConfigDevice `json:"sdaq,omitempty"` - SDAR *InstanceConfigDevice `json:"sdar,omitempty"` - SDAS *InstanceConfigDevice `json:"sdas,omitempty"` - SDAT *InstanceConfigDevice `json:"sdat,omitempty"` - SDAU *InstanceConfigDevice `json:"sdau,omitempty"` - SDAV *InstanceConfigDevice `json:"sdav,omitempty"` - SDAW *InstanceConfigDevice `json:"sdaw,omitempty"` - SDAX *InstanceConfigDevice `json:"sdax,omitempty"` - SDAY *InstanceConfigDevice `json:"sday,omitempty"` - SDAZ *InstanceConfigDevice `json:"sdaz,omitempty"` + SDAA *InstanceConfigDevice `json:"sdaa,omitzero"` + SDAB *InstanceConfigDevice `json:"sdab,omitzero"` + SDAC *InstanceConfigDevice `json:"sdac,omitzero"` + SDAD *InstanceConfigDevice `json:"sdad,omitzero"` + SDAE *InstanceConfigDevice `json:"sdae,omitzero"` + SDAF *InstanceConfigDevice `json:"sdaf,omitzero"` + SDAG *InstanceConfigDevice `json:"sdag,omitzero"` + SDAH *InstanceConfigDevice `json:"sdah,omitzero"` + SDAI *InstanceConfigDevice `json:"sdai,omitzero"` + SDAJ *InstanceConfigDevice `json:"sdaj,omitzero"` + SDAK *InstanceConfigDevice `json:"sdak,omitzero"` + SDAL *InstanceConfigDevice `json:"sdal,omitzero"` + SDAM *InstanceConfigDevice `json:"sdam,omitzero"` + SDAN *InstanceConfigDevice `json:"sdan,omitzero"` + SDAO *InstanceConfigDevice `json:"sdao,omitzero"` + SDAP *InstanceConfigDevice `json:"sdap,omitzero"` + SDAQ *InstanceConfigDevice `json:"sdaq,omitzero"` + SDAR *InstanceConfigDevice `json:"sdar,omitzero"` + SDAS *InstanceConfigDevice `json:"sdas,omitzero"` + SDAT *InstanceConfigDevice `json:"sdat,omitzero"` + SDAU *InstanceConfigDevice `json:"sdau,omitzero"` + SDAV *InstanceConfigDevice `json:"sdav,omitzero"` + SDAW *InstanceConfigDevice `json:"sdaw,omitzero"` + SDAX *InstanceConfigDevice `json:"sdax,omitzero"` + SDAY *InstanceConfigDevice `json:"sday,omitzero"` + SDAZ *InstanceConfigDevice `json:"sdaz,omitzero"` // sdba-sdbl - SDBA *InstanceConfigDevice `json:"sdba,omitempty"` - SDBB *InstanceConfigDevice `json:"sdbb,omitempty"` - SDBC *InstanceConfigDevice `json:"sdbc,omitempty"` - SDBD *InstanceConfigDevice `json:"sdbd,omitempty"` - SDBE *InstanceConfigDevice `json:"sdbe,omitempty"` - SDBF *InstanceConfigDevice `json:"sdbf,omitempty"` - SDBG *InstanceConfigDevice `json:"sdbg,omitempty"` - SDBH *InstanceConfigDevice `json:"sdbh,omitempty"` - SDBI *InstanceConfigDevice `json:"sdbi,omitempty"` - SDBJ *InstanceConfigDevice `json:"sdbj,omitempty"` - SDBK *InstanceConfigDevice `json:"sdbk,omitempty"` - SDBL *InstanceConfigDevice `json:"sdbl,omitempty"` + SDBA *InstanceConfigDevice `json:"sdba,omitzero"` + SDBB *InstanceConfigDevice `json:"sdbb,omitzero"` + SDBC *InstanceConfigDevice `json:"sdbc,omitzero"` + SDBD *InstanceConfigDevice `json:"sdbd,omitzero"` + SDBE *InstanceConfigDevice `json:"sdbe,omitzero"` + SDBF *InstanceConfigDevice `json:"sdbf,omitzero"` + SDBG *InstanceConfigDevice `json:"sdbg,omitzero"` + SDBH *InstanceConfigDevice `json:"sdbh,omitzero"` + SDBI *InstanceConfigDevice `json:"sdbi,omitzero"` + SDBJ *InstanceConfigDevice `json:"sdbj,omitzero"` + SDBK *InstanceConfigDevice `json:"sdbk,omitzero"` + SDBL *InstanceConfigDevice `json:"sdbl,omitzero"` } // InstanceConfigHelpers are Instance Config options that control Linux distribution specific tweaks @@ -125,34 +125,34 @@ const ( // InstanceConfigCreateOptions are InstanceConfig settings that can be used at creation type InstanceConfigCreateOptions struct { - Label string `json:"label,omitempty"` - Comments string `json:"comments,omitempty"` + Label string `json:"label,omitzero"` + Comments string `json:"comments,omitzero"` Devices InstanceConfigDeviceMap `json:"devices"` - Helpers *InstanceConfigHelpers `json:"helpers,omitempty"` + Helpers *InstanceConfigHelpers `json:"helpers,omitzero"` Interfaces []InstanceConfigInterfaceCreateOptions `json:"interfaces"` - MemoryLimit int `json:"memory_limit,omitempty"` - Kernel string `json:"kernel,omitempty"` - InitRD int `json:"init_rd,omitempty"` - RootDevice *string `json:"root_device,omitempty"` - RunLevel string `json:"run_level,omitempty"` - VirtMode string `json:"virt_mode,omitempty"` + MemoryLimit int `json:"memory_limit,omitzero"` + Kernel string `json:"kernel,omitzero"` + InitRD int `json:"init_rd,omitzero"` + RootDevice *string `json:"root_device,omitzero"` + RunLevel string `json:"run_level,omitzero"` + VirtMode string `json:"virt_mode,omitzero"` } // InstanceConfigUpdateOptions are InstanceConfig settings that can be used in updates type InstanceConfigUpdateOptions struct { - Label string `json:"label,omitempty"` + Label string `json:"label,omitzero"` Comments string `json:"comments"` - Devices *InstanceConfigDeviceMap `json:"devices,omitempty"` - Helpers *InstanceConfigHelpers `json:"helpers,omitempty"` + Devices *InstanceConfigDeviceMap `json:"devices,omitzero"` + Helpers *InstanceConfigHelpers `json:"helpers,omitzero"` Interfaces []InstanceConfigInterfaceCreateOptions `json:"interfaces"` // MemoryLimit 0 means unlimitted, this is not omitted MemoryLimit int `json:"memory_limit"` - Kernel string `json:"kernel,omitempty"` + Kernel string `json:"kernel,omitzero"` // InitRD is nullable, permit the sending of null InitRD *int `json:"init_rd"` - RootDevice string `json:"root_device,omitempty"` - RunLevel string `json:"run_level,omitempty"` - VirtMode string `json:"virt_mode,omitempty"` + RootDevice string `json:"root_device,omitzero"` + RunLevel string `json:"run_level,omitzero"` + VirtMode string `json:"virt_mode,omitzero"` } // UnmarshalJSON implements the json.Unmarshaler interface diff --git a/instance_disks.go b/instance_disks.go index de8d7bc64..375dd8ca6 100644 --- a/instance_disks.go +++ b/instance_disks.go @@ -48,14 +48,14 @@ type InstanceDiskCreateOptions struct { Size int `json:"size"` // Image is optional, but requires RootPass if provided - Image string `json:"image,omitempty"` - RootPass string `json:"root_pass,omitempty"` - - Filesystem string `json:"filesystem,omitempty"` - AuthorizedKeys []string `json:"authorized_keys,omitempty"` - AuthorizedUsers []string `json:"authorized_users,omitempty"` - StackscriptID int `json:"stackscript_id,omitempty"` - StackscriptData map[string]string `json:"stackscript_data,omitempty"` + Image string `json:"image,omitzero"` + RootPass string `json:"root_pass,omitzero"` + + Filesystem string `json:"filesystem,omitzero"` + AuthorizedKeys []string `json:"authorized_keys,omitzero"` + AuthorizedUsers []string `json:"authorized_users,omitzero"` + StackscriptID int `json:"stackscript_id,omitzero"` + StackscriptData map[string]string `json:"stackscript_data,omitzero"` } // InstanceDiskUpdateOptions are InstanceDisk settings that can be used in updates diff --git a/instance_ips.go b/instance_ips.go index eac567782..05724238b 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -36,7 +36,7 @@ type InstanceIP struct { } type InstanceIPAddressUpdateOptions struct { - RDNS **string `json:"rdns,omitempty"` + RDNS **string `json:"rdns,omitzero"` } // VPCIP represents a private IP address in a VPC subnet with additional networking details diff --git a/instances.go b/instances.go index a391dfdff..f80115d6b 100644 --- a/instances.go +++ b/instances.go @@ -100,12 +100,12 @@ type InstanceAlert struct { // InstanceBackup represents backup settings for an instance type InstanceBackup struct { - Available bool `json:"available,omitempty"` // read-only - Enabled bool `json:"enabled,omitempty"` // read-only - LastSuccessful *time.Time `json:"-"` // read-only + Available bool `json:"available,omitzero"` // read-only + Enabled bool `json:"enabled,omitzero"` // read-only + LastSuccessful *time.Time `json:"-"` // read-only Schedule struct { - Day string `json:"day,omitempty"` - Window string `json:"window,omitempty"` + Day string `json:"day,omitzero"` + Window string `json:"window,omitzero"` } `json:"schedule"` } @@ -154,7 +154,7 @@ type InstancePlacementGroup struct { // that relate to the Linode Metadata service. type InstanceMetadataOptions struct { // UserData expects a Base64-encoded string - UserData string `json:"user_data,omitempty"` + UserData string `json:"user_data,omitzero"` } // InstancePasswordResetOptions specifies the new password for the Linode @@ -166,23 +166,23 @@ type InstancePasswordResetOptions struct { type InstanceCreateOptions struct { Region string `json:"region"` Type string `json:"type"` - Label string `json:"label,omitempty"` - RootPass string `json:"root_pass,omitempty"` - AuthorizedKeys []string `json:"authorized_keys,omitempty"` - AuthorizedUsers []string `json:"authorized_users,omitempty"` - StackScriptID int `json:"stackscript_id,omitempty"` - StackScriptData map[string]string `json:"stackscript_data,omitempty"` - BackupID int `json:"backup_id,omitempty"` - Image string `json:"image,omitempty"` - BackupsEnabled bool `json:"backups_enabled,omitempty"` - PrivateIP bool `json:"private_ip,omitempty"` - NetworkHelper *bool `json:"network_helper,omitempty"` - Tags []string `json:"tags,omitempty"` - Metadata *InstanceMetadataOptions `json:"metadata,omitempty"` - FirewallID int `json:"firewall_id,omitempty"` - InterfaceGeneration InterfaceGeneration `json:"interface_generation,omitempty"` - DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitempty"` - PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitempty"` + Label string `json:"label,omitzero"` + RootPass string `json:"root_pass,omitzero"` + AuthorizedKeys []string `json:"authorized_keys,omitzero"` + AuthorizedUsers []string `json:"authorized_users,omitzero"` + StackScriptID int `json:"stackscript_id,omitzero"` + StackScriptData map[string]string `json:"stackscript_data,omitzero"` + BackupID int `json:"backup_id,omitzero"` + Image string `json:"image,omitzero"` + BackupsEnabled bool `json:"backups_enabled,omitzero"` + PrivateIP bool `json:"private_ip,omitzero"` + NetworkHelper *bool `json:"network_helper,omitzero"` + Tags []string `json:"tags,omitzero"` + Metadata *InstanceMetadataOptions `json:"metadata,omitzero"` + FirewallID int `json:"firewall_id,omitzero"` + InterfaceGeneration InterfaceGeneration `json:"interface_generation,omitzero"` + DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitzero"` + PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitzero"` // Linode Interfaces to create the new instance with. // Conflicts with Interfaces. @@ -193,30 +193,30 @@ type InstanceCreateOptions struct { Interfaces []InstanceConfigInterfaceCreateOptions `json:"-"` // Creation fields that need to be set explicitly false, "", or 0 use pointers - SwapSize *int `json:"swap_size,omitempty"` - Booted *bool `json:"booted,omitempty"` + SwapSize *int `json:"swap_size,omitzero"` + Booted *bool `json:"booted,omitzero"` - IPv4 []string `json:"ipv4,omitempty"` + IPv4 []string `json:"ipv4,omitzero"` - MaintenancePolicy *string `json:"maintenance_policy,omitempty"` + MaintenancePolicy *string `json:"maintenance_policy,omitzero"` } // InstanceCreatePlacementGroupOptions represents the placement group // to create this Linode under. type InstanceCreatePlacementGroupOptions struct { ID int `json:"id"` - CompliantOnly *bool `json:"compliant_only,omitempty"` + CompliantOnly *bool `json:"compliant_only,omitzero"` } // InstanceUpdateOptions is an options struct used when Updating an Instance type InstanceUpdateOptions struct { - Label string `json:"label,omitempty"` - Backups *InstanceBackup `json:"backups,omitempty"` - Alerts *InstanceAlert `json:"alerts,omitempty"` - WatchdogEnabled *bool `json:"watchdog_enabled,omitempty"` - Tags *[]string `json:"tags,omitempty"` + Label string `json:"label,omitzero"` + Backups *InstanceBackup `json:"backups,omitzero"` + Alerts *InstanceAlert `json:"alerts,omitzero"` + WatchdogEnabled *bool `json:"watchdog_enabled,omitzero"` + Tags *[]string `json:"tags,omitzero"` - MaintenancePolicy *string `json:"maintenance_policy,omitempty"` + MaintenancePolicy *string `json:"maintenance_policy,omitzero"` } // MarshalJSON contains logic necessary to populate the `interfaces` field of @@ -228,7 +228,7 @@ func (i InstanceCreateOptions) MarshalJSON() ([]byte, error) { resultData := struct { *Mask - Interfaces any `json:"interfaces,omitempty"` + Interfaces any `json:"interfaces,omitzero"` }{ Mask: (*Mask)(&i), Interfaces: nil, @@ -257,7 +257,7 @@ func (i *InstanceCreateOptions) UnmarshalJSON(b []byte) error { p := struct { *Mask - GenericInterfaces any `json:"interfaces,omitempty"` + GenericInterfaces any `json:"interfaces,omitzero"` }{ Mask: (*Mask)(i), } @@ -354,36 +354,36 @@ func (i *Instance) GetUpdateOptions() InstanceUpdateOptions { // InstanceCloneOptions is an options struct sent when Cloning an Instance type InstanceCloneOptions struct { - Region string `json:"region,omitempty"` - Type string `json:"type,omitempty"` + Region string `json:"region,omitzero"` + Type string `json:"type,omitzero"` // LinodeID is an optional existing instance to use as the target of the clone - LinodeID int `json:"linode_id,omitempty"` - Label string `json:"label,omitempty"` + LinodeID int `json:"linode_id,omitzero"` + Label string `json:"label,omitzero"` BackupsEnabled bool `json:"backups_enabled"` - Disks []int `json:"disks,omitempty"` - Configs []int `json:"configs,omitempty"` - PrivateIP bool `json:"private_ip,omitempty"` - Metadata *InstanceMetadataOptions `json:"metadata,omitempty"` - PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitempty"` + Disks []int `json:"disks,omitzero"` + Configs []int `json:"configs,omitzero"` + PrivateIP bool `json:"private_ip,omitzero"` + Metadata *InstanceMetadataOptions `json:"metadata,omitzero"` + PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitzero"` } // InstanceResizeOptions is an options struct used when resizing an instance type InstanceResizeOptions struct { Type string `json:"type"` - MigrationType InstanceMigrationType `json:"migration_type,omitempty"` + MigrationType InstanceMigrationType `json:"migration_type,omitzero"` // When enabled, an instance resize will also resize a data disk if the instance has no more than one data disk and one swap disk - AllowAutoDiskResize *bool `json:"allow_auto_disk_resize,omitempty"` + AllowAutoDiskResize *bool `json:"allow_auto_disk_resize,omitzero"` } // InstanceMigrateOptions is an options struct used when migrating an instance type InstanceMigrateOptions struct { - Type InstanceMigrationType `json:"type,omitempty"` - Region string `json:"region,omitempty"` - Upgrade *bool `json:"upgrade,omitempty"` + Type InstanceMigrationType `json:"type,omitzero"` + Region string `json:"region,omitzero"` + Upgrade *bool `json:"upgrade,omitzero"` - PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitempty"` + PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitzero"` } // ListInstances lists linode instances @@ -473,16 +473,16 @@ func (c *Client) RebootInstance(ctx context.Context, linodeID int, configID int) // InstanceRebuildOptions is a struct representing the options to send to the rebuild linode endpoint type InstanceRebuildOptions struct { - Image string `json:"image,omitempty"` - RootPass string `json:"root_pass,omitempty"` - AuthorizedKeys []string `json:"authorized_keys,omitempty"` - AuthorizedUsers []string `json:"authorized_users,omitempty"` - StackScriptID int `json:"stackscript_id,omitempty"` - StackScriptData map[string]string `json:"stackscript_data,omitempty"` - Booted *bool `json:"booted,omitempty"` - Metadata *InstanceMetadataOptions `json:"metadata,omitempty"` - Type string `json:"type,omitempty"` - DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitempty"` + Image string `json:"image,omitzero"` + RootPass string `json:"root_pass,omitzero"` + AuthorizedKeys []string `json:"authorized_keys,omitzero"` + AuthorizedUsers []string `json:"authorized_users,omitzero"` + StackScriptID int `json:"stackscript_id,omitzero"` + StackScriptData map[string]string `json:"stackscript_data,omitzero"` + Booted *bool `json:"booted,omitzero"` + Metadata *InstanceMetadataOptions `json:"metadata,omitzero"` + Type string `json:"type,omitzero"` + DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitzero"` } // RebuildInstance Deletes all Disks and Configs on this Linode, diff --git a/interfaces.go b/interfaces.go index b2d4e53c4..1a2b8081b 100644 --- a/interfaces.go +++ b/interfaces.go @@ -21,8 +21,8 @@ type LinodeInterface struct { } type InterfaceDefaultRoute struct { - IPv4 *bool `json:"ipv4,omitempty"` - IPv6 *bool `json:"ipv6,omitempty"` + IPv4 *bool `json:"ipv4,omitzero"` + IPv6 *bool `json:"ipv6,omitzero"` } type PublicInterface struct { @@ -108,39 +108,39 @@ type VPCInterfaceIPv6Range struct { type VLANInterface struct { VLANLabel string `json:"vlan_label"` - IPAMAddress *string `json:"ipam_address,omitempty"` + IPAMAddress *string `json:"ipam_address,omitzero"` } type LinodeInterfaceCreateOptions struct { - FirewallID *int `json:"firewall_id,omitempty"` - DefaultRoute *InterfaceDefaultRoute `json:"default_route,omitempty"` - Public *PublicInterfaceCreateOptions `json:"public,omitempty"` - VPC *VPCInterfaceCreateOptions `json:"vpc,omitempty"` - VLAN *VLANInterface `json:"vlan,omitempty"` + FirewallID *int `json:"firewall_id,omitzero"` + DefaultRoute *InterfaceDefaultRoute `json:"default_route,omitzero"` + Public *PublicInterfaceCreateOptions `json:"public,omitzero"` + VPC *VPCInterfaceCreateOptions `json:"vpc,omitzero"` + VLAN *VLANInterface `json:"vlan,omitzero"` } type LinodeInterfaceUpdateOptions struct { - DefaultRoute *InterfaceDefaultRoute `json:"default_route,omitempty"` - Public *PublicInterfaceCreateOptions `json:"public,omitempty"` - VPC *VPCInterfaceUpdateOptions `json:"vpc,omitempty"` + DefaultRoute *InterfaceDefaultRoute `json:"default_route,omitzero"` + Public *PublicInterfaceCreateOptions `json:"public,omitzero"` + VPC *VPCInterfaceUpdateOptions `json:"vpc,omitzero"` } type PublicInterfaceCreateOptions struct { - IPv4 *PublicInterfaceIPv4CreateOptions `json:"ipv4,omitempty"` - IPv6 *PublicInterfaceIPv6CreateOptions `json:"ipv6,omitempty"` + IPv4 *PublicInterfaceIPv4CreateOptions `json:"ipv4,omitzero"` + IPv6 *PublicInterfaceIPv6CreateOptions `json:"ipv6,omitzero"` } type PublicInterfaceIPv4CreateOptions struct { - Addresses *[]PublicInterfaceIPv4AddressCreateOptions `json:"addresses,omitempty"` + Addresses *[]PublicInterfaceIPv4AddressCreateOptions `json:"addresses,omitzero"` } type PublicInterfaceIPv4AddressCreateOptions struct { - Address *string `json:"address,omitempty"` - Primary *bool `json:"primary,omitempty"` + Address *string `json:"address,omitzero"` + Primary *bool `json:"primary,omitzero"` } type PublicInterfaceIPv6CreateOptions struct { - Ranges *[]PublicInterfaceIPv6RangeCreateOptions `json:"ranges,omitempty"` + Ranges *[]PublicInterfaceIPv6RangeCreateOptions `json:"ranges,omitzero"` } type PublicInterfaceIPv6RangeCreateOptions struct { @@ -149,19 +149,19 @@ type PublicInterfaceIPv6RangeCreateOptions struct { type VPCInterfaceCreateOptions struct { SubnetID int `json:"subnet_id"` - IPv4 *VPCInterfaceIPv4CreateOptions `json:"ipv4,omitempty"` - IPv6 *VPCInterfaceIPv6CreateOptions `json:"ipv6,omitempty"` + IPv4 *VPCInterfaceIPv4CreateOptions `json:"ipv4,omitzero"` + IPv6 *VPCInterfaceIPv6CreateOptions `json:"ipv6,omitzero"` } type VPCInterfaceIPv4CreateOptions struct { - Addresses *[]VPCInterfaceIPv4AddressCreateOptions `json:"addresses,omitempty"` - Ranges *[]VPCInterfaceIPv4RangeCreateOptions `json:"ranges,omitempty"` + Addresses *[]VPCInterfaceIPv4AddressCreateOptions `json:"addresses,omitzero"` + Ranges *[]VPCInterfaceIPv4RangeCreateOptions `json:"ranges,omitzero"` } type VPCInterfaceIPv4AddressCreateOptions struct { - Address *string `json:"address,omitempty"` - Primary *bool `json:"primary,omitempty"` - NAT1To1Address *string `json:"nat_1_1_address,omitempty"` + Address *string `json:"address,omitzero"` + Primary *bool `json:"primary,omitzero"` + NAT1To1Address *string `json:"nat_1_1_address,omitzero"` } type VPCInterfaceIPv4RangeCreateOptions struct { @@ -171,8 +171,8 @@ type VPCInterfaceIPv4RangeCreateOptions struct { // VPCInterfaceIPv6CreateOptions specifies IPv6 configuration parameters for VPC creation. // NOTE: IPv6 interfaces may not currently be available to all users. type VPCInterfaceIPv6CreateOptions struct { - SLAAC *[]VPCInterfaceIPv6SLAACCreateOptions `json:"slaac,omitempty"` - Ranges *[]VPCInterfaceIPv6RangeCreateOptions `json:"ranges,omitempty"` + SLAAC *[]VPCInterfaceIPv6SLAACCreateOptions `json:"slaac,omitzero"` + Ranges *[]VPCInterfaceIPv6RangeCreateOptions `json:"ranges,omitzero"` IsPublic *bool `json:"is_public"` } @@ -189,8 +189,8 @@ type VPCInterfaceIPv6RangeCreateOptions struct { } type VPCInterfaceUpdateOptions struct { - IPv4 *VPCInterfaceIPv4CreateOptions `json:"ipv4,omitempty"` - IPv6 *VPCInterfaceIPv6CreateOptions `json:"ipv6,omitempty"` + IPv4 *VPCInterfaceIPv4CreateOptions `json:"ipv4,omitzero"` + IPv6 *VPCInterfaceIPv6CreateOptions `json:"ipv6,omitzero"` } type LinodeInterfacesUpgrade struct { @@ -200,8 +200,8 @@ type LinodeInterfacesUpgrade struct { } type LinodeInterfacesUpgradeOptions struct { - ConfigID *int `json:"config_id,omitempty"` - DryRun *bool `json:"dry_run,omitempty"` + ConfigID *int `json:"config_id,omitzero"` + DryRun *bool `json:"dry_run,omitzero"` } type InterfaceSettings struct { @@ -210,13 +210,13 @@ type InterfaceSettings struct { } type InterfaceSettingsUpdateOptions struct { - NetworkHelper *bool `json:"network_helper,omitempty"` - DefaultRoute *InterfaceDefaultRouteSettingUpdateOptions `json:"default_route,omitempty"` + NetworkHelper *bool `json:"network_helper,omitzero"` + DefaultRoute *InterfaceDefaultRouteSettingUpdateOptions `json:"default_route,omitzero"` } type InterfaceDefaultRouteSettingUpdateOptions struct { - IPv4InterfaceID *int `json:"ipv4_interface_id,omitempty"` - IPv6InterfaceID *int `json:"ipv6_interface_id,omitempty"` + IPv4InterfaceID *int `json:"ipv4_interface_id,omitzero"` + IPv6InterfaceID *int `json:"ipv6_interface_id,omitzero"` } type InterfaceDefaultRouteSetting struct { diff --git a/lke_clusters.go b/lke_clusters.go index 786b6faaf..c12c08fc8 100644 --- a/lke_clusters.go +++ b/lke_clusters.go @@ -55,27 +55,27 @@ type LKEClusterCreateOptions struct { Label string `json:"label"` Region string `json:"region"` K8sVersion string `json:"k8s_version"` - Tags []string `json:"tags,omitempty"` - ControlPlane *LKEClusterControlPlaneOptions `json:"control_plane,omitempty"` + Tags []string `json:"tags,omitzero"` + ControlPlane *LKEClusterControlPlaneOptions `json:"control_plane,omitzero"` // NOTE: Tier may not currently be available to all users and can only be used with v4beta. - Tier string `json:"tier,omitempty"` + Tier string `json:"tier,omitzero"` // NOTE: APLEnabled is currently in beta and may only function with API version v4beta. - APLEnabled bool `json:"apl_enabled,omitempty"` + APLEnabled bool `json:"apl_enabled,omitzero"` // NOTE: SubnetID, VpcID, and StackType may not currently be available to all users and can only be used with v4beta. - SubnetID *int `json:"subnet_id,omitempty"` - VpcID *int `json:"vpc_id,omitempty"` - StackType *LKEClusterStackType `json:"stack_type,omitempty"` + SubnetID *int `json:"subnet_id,omitzero"` + VpcID *int `json:"vpc_id,omitzero"` + StackType *LKEClusterStackType `json:"stack_type,omitzero"` } // LKEClusterUpdateOptions fields are those accepted by UpdateLKECluster type LKEClusterUpdateOptions struct { - K8sVersion string `json:"k8s_version,omitempty"` - Label string `json:"label,omitempty"` - Tags *[]string `json:"tags,omitempty"` - ControlPlane *LKEClusterControlPlaneOptions `json:"control_plane,omitempty"` + K8sVersion string `json:"k8s_version,omitzero"` + Label string `json:"label,omitzero"` + Tags *[]string `json:"tags,omitzero"` + ControlPlane *LKEClusterControlPlaneOptions `json:"control_plane,omitzero"` } // LKEClusterAPIEndpoint fields are those returned by ListLKEClusterAPIEndpoints diff --git a/lke_clusters_control_plane.go b/lke_clusters_control_plane.go index 5a3544a25..c5080ac56 100644 --- a/lke_clusters_control_plane.go +++ b/lke_clusters_control_plane.go @@ -7,7 +7,7 @@ type LKEClusterControlPlane struct { HighAvailability bool `json:"high_availability"` // AuditLogsEnabled may not currently be available to all users and can only be used with v4beta. - AuditLogsEnabled bool `json:"audit_logs_enabled,omitempty"` + AuditLogsEnabled bool `json:"audit_logs_enabled,omitzero"` } // LKEClusterControlPlaneACLAddresses describes the @@ -28,26 +28,26 @@ type LKEClusterControlPlaneACL struct { // LKEClusterControlPlaneACLAddressesOptions are the options used to // specify the allowed IP ranges for an LKE cluster's control plane. type LKEClusterControlPlaneACLAddressesOptions struct { - IPv4 *[]string `json:"ipv4,omitempty"` - IPv6 *[]string `json:"ipv6,omitempty"` + IPv4 *[]string `json:"ipv4,omitzero"` + IPv6 *[]string `json:"ipv6,omitzero"` } // LKEClusterControlPlaneACLOptions represents the options used when // configuring an LKE cluster's control plane ACL policy. type LKEClusterControlPlaneACLOptions struct { - Enabled *bool `json:"enabled,omitempty"` - Addresses *LKEClusterControlPlaneACLAddressesOptions `json:"addresses,omitempty"` - RevisionID string `json:"revision-id,omitempty"` + Enabled *bool `json:"enabled,omitzero"` + Addresses *LKEClusterControlPlaneACLAddressesOptions `json:"addresses,omitzero"` + RevisionID string `json:"revision-id,omitzero"` } // LKEClusterControlPlaneOptions represents the options used when // configuring an LKE cluster's control plane. type LKEClusterControlPlaneOptions struct { - HighAvailability *bool `json:"high_availability,omitempty"` - ACL *LKEClusterControlPlaneACLOptions `json:"acl,omitempty"` + HighAvailability *bool `json:"high_availability,omitzero"` + ACL *LKEClusterControlPlaneACLOptions `json:"acl,omitzero"` // AuditLogsEnabled may not currently be available to all users and can only be used with v4beta. - AuditLogsEnabled *bool `json:"audit_logs_enabled,omitempty"` + AuditLogsEnabled *bool `json:"audit_logs_enabled,omitzero"` } // LKEClusterControlPlaneACLUpdateOptions represents the options diff --git a/lke_node_pools.go b/lke_node_pools.go index b50507d6d..3cba06eee 100644 --- a/lke_node_pools.go +++ b/lke_node_pools.go @@ -55,7 +55,7 @@ const ( // LKENodePoolTaint represents a corev1.Taint to add to an LKENodePool type LKENodePoolTaint struct { Key string `json:"key"` - Value string `json:"value,omitempty"` + Value string `json:"value,omitzero"` Effect LKENodePoolTaintEffect `json:"effect"` } @@ -75,14 +75,14 @@ type LKENodePool struct { Label *string `json:"label"` Autoscaler LKENodePoolAutoscaler `json:"autoscaler"` - FirewallID *int `json:"firewall_id,omitempty"` + FirewallID *int `json:"firewall_id,omitzero"` - DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitempty"` + DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitzero"` // K8sVersion and UpdateStrategy are only for LKE Enterprise to support node pool upgrades. // It may not currently be available to all users and is under v4beta. - K8sVersion *string `json:"k8s_version,omitempty"` - UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitempty"` + K8sVersion *string `json:"k8s_version,omitzero"` + UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitzero"` } // LKENodePoolCreateOptions fields are those accepted by CreateLKENodePool @@ -93,34 +93,34 @@ type LKENodePoolCreateOptions struct { Tags []string `json:"tags"` Labels LKENodePoolLabels `json:"labels"` Taints []LKENodePoolTaint `json:"taints"` - Label *string `json:"label,omitempty"` + Label *string `json:"label,omitzero"` - Autoscaler *LKENodePoolAutoscaler `json:"autoscaler,omitempty"` - FirewallID *int `json:"firewall_id,omitempty"` + Autoscaler *LKENodePoolAutoscaler `json:"autoscaler,omitzero"` + FirewallID *int `json:"firewall_id,omitzero"` // K8sVersion and UpdateStrategy only works for LKE Enterprise to support node pool upgrades. // It may not currently be available to all users and is under v4beta. - K8sVersion *string `json:"k8s_version,omitempty"` - UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitempty"` + K8sVersion *string `json:"k8s_version,omitzero"` + UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitzero"` - DiskEncryption *InstanceDiskEncryption `json:"disk_encryption,omitempty"` + DiskEncryption *InstanceDiskEncryption `json:"disk_encryption,omitzero"` } // LKENodePoolUpdateOptions fields are those accepted by UpdateLKENodePoolUpdate type LKENodePoolUpdateOptions struct { - Count int `json:"count,omitempty"` - Tags *[]string `json:"tags,omitempty"` - Labels *LKENodePoolLabels `json:"labels,omitempty"` - Taints *[]LKENodePoolTaint `json:"taints,omitempty"` - Label *string `json:"label,omitempty"` + Count int `json:"count,omitzero"` + Tags *[]string `json:"tags,omitzero"` + Labels *LKENodePoolLabels `json:"labels,omitzero"` + Taints *[]LKENodePoolTaint `json:"taints,omitzero"` + Label *string `json:"label,omitzero"` - Autoscaler *LKENodePoolAutoscaler `json:"autoscaler,omitempty"` - FirewallID *int `json:"firewall_id,omitempty"` + Autoscaler *LKENodePoolAutoscaler `json:"autoscaler,omitzero"` + FirewallID *int `json:"firewall_id,omitzero"` // K8sVersion and UpdateStrategy only works for LKE Enterprise to support node pool upgrades. // It may not currently be available to all users and is under v4beta. - K8sVersion *string `json:"k8s_version,omitempty"` - UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitempty"` + K8sVersion *string `json:"k8s_version,omitzero"` + UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitzero"` } // GetCreateOptions converts a LKENodePool to LKENodePoolCreateOptions for diff --git a/monitor_alert_definitions.go b/monitor_alert_definitions.go index c11d50c2d..dc4a4a0a0 100644 --- a/monitor_alert_definitions.go +++ b/monitor_alert_definitions.go @@ -71,15 +71,15 @@ type AlertDefinition struct { // TriggerConditions represents the trigger conditions for an alert. type TriggerConditions struct { - CriteriaCondition string `json:"criteria_condition,omitempty"` - EvaluationPeriodSeconds int `json:"evaluation_period_seconds,omitempty"` - PollingIntervalSeconds int `json:"polling_interval_seconds,omitempty"` - TriggerOccurrences int `json:"trigger_occurrences,omitempty"` + CriteriaCondition string `json:"criteria_condition,omitzero"` + EvaluationPeriodSeconds int `json:"evaluation_period_seconds,omitzero"` + PollingIntervalSeconds int `json:"polling_interval_seconds,omitzero"` + TriggerOccurrences int `json:"trigger_occurrences,omitzero"` } // RuleCriteria represents the rule criteria for an alert. type RuleCriteria struct { - Rules []Rule `json:"rules,omitempty"` + Rules []Rule `json:"rules,omitzero"` } // Rule represents a single rule for an alert. @@ -103,23 +103,23 @@ type DimensionFilter struct { // RuleCriteriaOptions represents the rule criteria options for an alert. type RuleCriteriaOptions struct { - Rules []RuleOptions `json:"rules,omitempty"` + Rules []RuleOptions `json:"rules,omitzero"` } // RuleOptions represents a single rule option for an alert. type RuleOptions struct { - AggregateFunction string `json:"aggregate_function,omitempty"` - DimensionFilters []DimensionFilterOptions `json:"dimension_filters,omitempty"` - Metric string `json:"metric,omitempty"` - Operator string `json:"operator,omitempty"` - Threshold float64 `json:"threshold,omitempty"` + AggregateFunction string `json:"aggregate_function,omitzero"` + DimensionFilters []DimensionFilterOptions `json:"dimension_filters,omitzero"` + Metric string `json:"metric,omitzero"` + Operator string `json:"operator,omitzero"` + Threshold float64 `json:"threshold,omitzero"` } // DimensionFilterOptions represents a single dimension filter option used inside a Rule. type DimensionFilterOptions struct { - DimensionLabel string `json:"dimension_label,omitempty"` - Operator string `json:"operator,omitempty"` - Value string `json:"value,omitempty"` + DimensionLabel string `json:"dimension_label,omitzero"` + Operator string `json:"operator,omitzero"` + Value string `json:"value,omitzero"` } // AlertChannelEnvelope represents a single alert channel entry returned inside alert definition @@ -161,11 +161,11 @@ type AlertDefinitionCreateOptions struct { Label string `json:"label"` Severity int `json:"severity"` ChannelIDs []int `json:"channel_ids"` - RuleCriteria *RuleCriteriaOptions `json:"rule_criteria,omitempty"` - TriggerConditions *TriggerConditions `json:"trigger_conditions,omitempty"` - EntityIDs []string `json:"entity_ids,omitempty"` - Description *string `json:"description,omitempty"` - Scope AlertDefinitionScope `json:"scope,omitempty"` + RuleCriteria *RuleCriteriaOptions `json:"rule_criteria,omitzero"` + TriggerConditions *TriggerConditions `json:"trigger_conditions,omitzero"` + EntityIDs []string `json:"entity_ids,omitzero"` + Description *string `json:"description,omitzero"` + Scope AlertDefinitionScope `json:"scope,omitzero"` Regions []string `json:"regions,omitzero"` } @@ -174,11 +174,11 @@ type AlertDefinitionUpdateOptions struct { Label string `json:"label"` Severity int `json:"severity"` ChannelIDs []int `json:"channel_ids"` - RuleCriteria *RuleCriteriaOptions `json:"rule_criteria,omitempty"` - TriggerConditions *TriggerConditions `json:"trigger_conditions,omitempty"` - EntityIDs []string `json:"entity_ids,omitempty"` - Description *string `json:"description,omitempty"` - Status *AlertDefinitionStatus `json:"status,omitempty"` + RuleCriteria *RuleCriteriaOptions `json:"rule_criteria,omitzero"` + TriggerConditions *TriggerConditions `json:"trigger_conditions,omitzero"` + EntityIDs []string `json:"entity_ids,omitzero"` + Description *string `json:"description,omitzero"` + Status *AlertDefinitionStatus `json:"status,omitzero"` Regions []string `json:"regions,omitzero"` } diff --git a/monitor_api_services.go b/monitor_api_services.go index a7ee4ca6d..d847a7e3f 100644 --- a/monitor_api_services.go +++ b/monitor_api_services.go @@ -61,11 +61,11 @@ type EntityMetricsFetchOptions struct { // EntityIDs are expected to be type "any" as different service_types have different variable type for their entity_ids. For example, Linode has "int" entity_ids whereas object storage has "string" as entity_ids. EntityIDs []any `json:"entity_ids"` - Filters []MetricFilter `json:"filters,omitempty"` + Filters []MetricFilter `json:"filters,omitzero"` Metrics []EntityMetric `json:"metrics"` - TimeGranularity []MetricTimeGranularity `json:"time_granularity,omitempty"` - RelativeTimeDuration *MetricRelativeTimeDuration `json:"relative_time_duration,omitempty"` - AbsoluteTimeDuration *MetricAbsoluteTimeDuration `json:"absolute_time_duration,omitempty"` + TimeGranularity []MetricTimeGranularity `json:"time_granularity,omitzero"` + RelativeTimeDuration *MetricRelativeTimeDuration `json:"relative_time_duration,omitzero"` + AbsoluteTimeDuration *MetricAbsoluteTimeDuration `json:"absolute_time_duration,omitzero"` } // MetricFilter describes individual objects that define dimension filters for the query. diff --git a/mysql.go b/mysql.go index 7b334f55e..78caf4fea 100644 --- a/mysql.go +++ b/mysql.go @@ -46,42 +46,42 @@ type MySQLDatabase struct { Port int `json:"port"` EngineConfig MySQLDatabaseEngineConfig `json:"engine_config"` - PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitempty"` + PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitzero"` } type MySQLDatabaseEngineConfig struct { - MySQL *MySQLDatabaseEngineConfigMySQL `json:"mysql,omitempty"` - BinlogRetentionPeriod *int `json:"binlog_retention_period,omitempty"` + MySQL *MySQLDatabaseEngineConfigMySQL `json:"mysql,omitzero"` + BinlogRetentionPeriod *int `json:"binlog_retention_period,omitzero"` } type MySQLDatabaseEngineConfigMySQL struct { - ConnectTimeout *int `json:"connect_timeout,omitempty"` - DefaultTimeZone *string `json:"default_time_zone,omitempty"` - GroupConcatMaxLen *float64 `json:"group_concat_max_len,omitempty"` - InformationSchemaStatsExpiry *int `json:"information_schema_stats_expiry,omitempty"` - InnoDBChangeBufferMaxSize *int `json:"innodb_change_buffer_max_size,omitempty"` - InnoDBFlushNeighbors *int `json:"innodb_flush_neighbors,omitempty"` - InnoDBFTMinTokenSize *int `json:"innodb_ft_min_token_size,omitempty"` - InnoDBFTServerStopwordTable **string `json:"innodb_ft_server_stopword_table,omitempty"` - InnoDBLockWaitTimeout *int `json:"innodb_lock_wait_timeout,omitempty"` - InnoDBLogBufferSize *int `json:"innodb_log_buffer_size,omitempty"` - InnoDBOnlineAlterLogMaxSize *int `json:"innodb_online_alter_log_max_size,omitempty"` - InnoDBReadIOThreads *int `json:"innodb_read_io_threads,omitempty"` - InnoDBRollbackOnTimeout *bool `json:"innodb_rollback_on_timeout,omitempty"` - InnoDBThreadConcurrency *int `json:"innodb_thread_concurrency,omitempty"` - InnoDBWriteIOThreads *int `json:"innodb_write_io_threads,omitempty"` - InteractiveTimeout *int `json:"interactive_timeout,omitempty"` - InternalTmpMemStorageEngine *string `json:"internal_tmp_mem_storage_engine,omitempty"` - MaxAllowedPacket *int `json:"max_allowed_packet,omitempty"` - MaxHeapTableSize *int `json:"max_heap_table_size,omitempty"` - NetBufferLength *int `json:"net_buffer_length,omitempty"` - NetReadTimeout *int `json:"net_read_timeout,omitempty"` - NetWriteTimeout *int `json:"net_write_timeout,omitempty"` - SortBufferSize *int `json:"sort_buffer_size,omitempty"` - SQLMode *string `json:"sql_mode,omitempty"` - SQLRequirePrimaryKey *bool `json:"sql_require_primary_key,omitempty"` - TmpTableSize *int `json:"tmp_table_size,omitempty"` - WaitTimeout *int `json:"wait_timeout,omitempty"` + ConnectTimeout *int `json:"connect_timeout,omitzero"` + DefaultTimeZone *string `json:"default_time_zone,omitzero"` + GroupConcatMaxLen *float64 `json:"group_concat_max_len,omitzero"` + InformationSchemaStatsExpiry *int `json:"information_schema_stats_expiry,omitzero"` + InnoDBChangeBufferMaxSize *int `json:"innodb_change_buffer_max_size,omitzero"` + InnoDBFlushNeighbors *int `json:"innodb_flush_neighbors,omitzero"` + InnoDBFTMinTokenSize *int `json:"innodb_ft_min_token_size,omitzero"` + InnoDBFTServerStopwordTable **string `json:"innodb_ft_server_stopword_table,omitzero"` + InnoDBLockWaitTimeout *int `json:"innodb_lock_wait_timeout,omitzero"` + InnoDBLogBufferSize *int `json:"innodb_log_buffer_size,omitzero"` + InnoDBOnlineAlterLogMaxSize *int `json:"innodb_online_alter_log_max_size,omitzero"` + InnoDBReadIOThreads *int `json:"innodb_read_io_threads,omitzero"` + InnoDBRollbackOnTimeout *bool `json:"innodb_rollback_on_timeout,omitzero"` + InnoDBThreadConcurrency *int `json:"innodb_thread_concurrency,omitzero"` + InnoDBWriteIOThreads *int `json:"innodb_write_io_threads,omitzero"` + InteractiveTimeout *int `json:"interactive_timeout,omitzero"` + InternalTmpMemStorageEngine *string `json:"internal_tmp_mem_storage_engine,omitzero"` + MaxAllowedPacket *int `json:"max_allowed_packet,omitzero"` + MaxHeapTableSize *int `json:"max_heap_table_size,omitzero"` + NetBufferLength *int `json:"net_buffer_length,omitzero"` + NetReadTimeout *int `json:"net_read_timeout,omitzero"` + NetWriteTimeout *int `json:"net_write_timeout,omitzero"` + SortBufferSize *int `json:"sort_buffer_size,omitzero"` + SQLMode *string `json:"sql_mode,omitzero"` + SQLRequirePrimaryKey *bool `json:"sql_require_primary_key,omitzero"` + TmpTableSize *int `json:"tmp_table_size,omitzero"` + WaitTimeout *int `json:"wait_timeout,omitzero"` } type MySQLDatabaseConfigInfo struct { @@ -397,24 +397,24 @@ type MySQLCreateOptions struct { Region string `json:"region"` Type string `json:"type"` Engine string `json:"engine"` - AllowList []string `json:"allow_list,omitempty"` - ClusterSize int `json:"cluster_size,omitempty"` + AllowList []string `json:"allow_list,omitzero"` + ClusterSize int `json:"cluster_size,omitzero"` - Fork *DatabaseFork `json:"fork,omitempty"` - EngineConfig *MySQLDatabaseEngineConfig `json:"engine_config,omitempty"` - PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitempty"` + Fork *DatabaseFork `json:"fork,omitzero"` + EngineConfig *MySQLDatabaseEngineConfig `json:"engine_config,omitzero"` + PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitzero"` } // MySQLUpdateOptions fields are used when altering the existing MySQL Database type MySQLUpdateOptions struct { - Label string `json:"label,omitempty"` - AllowList *[]string `json:"allow_list,omitempty"` - Updates *DatabaseMaintenanceWindow `json:"updates,omitempty"` - Type string `json:"type,omitempty"` - ClusterSize int `json:"cluster_size,omitempty"` - Version string `json:"version,omitempty"` - EngineConfig *MySQLDatabaseEngineConfig `json:"engine_config,omitempty"` - PrivateNetwork **DatabasePrivateNetwork `json:"private_network,omitempty"` + Label string `json:"label,omitzero"` + AllowList *[]string `json:"allow_list,omitzero"` + Updates *DatabaseMaintenanceWindow `json:"updates,omitzero"` + Type string `json:"type,omitzero"` + ClusterSize int `json:"cluster_size,omitzero"` + Version string `json:"version,omitzero"` + EngineConfig *MySQLDatabaseEngineConfig `json:"engine_config,omitzero"` + PrivateNetwork **DatabasePrivateNetwork `json:"private_network,omitzero"` } // MySQLDatabaseCredential is the Root Credentials to access the Linode Managed Database diff --git a/network_ips.go b/network_ips.go index 27d093f4f..d9c83ee58 100644 --- a/network_ips.go +++ b/network_ips.go @@ -12,8 +12,8 @@ import ( // } 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"` - RDNS **string `json:"rdns,omitempty"` + Reserved *bool `json:"reserved,omitzero"` + RDNS **string `json:"rdns,omitzero"` } // LinodeIPAssignment stores an assignment between an IP address and a Linode instance. @@ -25,9 +25,9 @@ type LinodeIPAssignment struct { type AllocateReserveIPOptions 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"` + Reserved bool `json:"reserved,omitzero"` + Region string `json:"region,omitzero"` + LinodeID int `json:"linode_id,omitzero"` } // LinodesAssignIPsOptions fields are those accepted by InstancesAssignIPs. diff --git a/network_ranges.go b/network_ranges.go index 00350b604..b8b7f0e15 100644 --- a/network_ranges.go +++ b/network_ranges.go @@ -6,9 +6,9 @@ import ( // IPv6RangeCreateOptions fields are those accepted by CreateIPv6Range type IPv6RangeCreateOptions struct { - LinodeID int `json:"linode_id,omitempty"` + LinodeID int `json:"linode_id,omitzero"` PrefixLength int `json:"prefix_length"` - RouteTarget string `json:"route_target,omitempty"` + RouteTarget string `json:"route_target,omitzero"` } // ListIPv6Ranges lists IPv6Ranges diff --git a/nodebalancer.go b/nodebalancer.go index 3fe80b1a5..af6c4a33d 100644 --- a/nodebalancer.go +++ b/nodebalancer.go @@ -57,38 +57,38 @@ type NodeBalancerTransfer struct { } type NodeBalancerVPCOptions struct { - IPv4Range string `json:"ipv4_range,omitempty"` - IPv6Range string `json:"ipv6_range,omitempty"` + IPv4Range string `json:"ipv4_range,omitzero"` + IPv6Range string `json:"ipv6_range,omitzero"` SubnetID int `json:"subnet_id"` - IPv4RangeAutoAssign bool `json:"ipv4_range_auto_assign,omitempty"` + IPv4RangeAutoAssign bool `json:"ipv4_range_auto_assign,omitzero"` } // NodeBalancerCreateOptions are the options permitted for CreateNodeBalancer type NodeBalancerCreateOptions struct { - Label *string `json:"label,omitempty"` - Region string `json:"region,omitempty"` - ClientConnThrottle *int `json:"client_conn_throttle,omitempty"` + Label *string `json:"label,omitzero"` + Region string `json:"region,omitzero"` + ClientConnThrottle *int `json:"client_conn_throttle,omitzero"` // NOTE: ClientUDPSessThrottle may not currently be available to all users. - ClientUDPSessThrottle *int `json:"client_udp_sess_throttle,omitempty"` + ClientUDPSessThrottle *int `json:"client_udp_sess_throttle,omitzero"` - Configs []*NodeBalancerConfigCreateOptions `json:"configs,omitempty"` + Configs []*NodeBalancerConfigCreateOptions `json:"configs,omitzero"` Tags []string `json:"tags"` - FirewallID int `json:"firewall_id,omitempty"` - Type NodeBalancerPlanType `json:"type,omitempty"` - VPCs []NodeBalancerVPCOptions `json:"vpcs,omitempty"` - IPv4 *string `json:"ipv4,omitempty"` + FirewallID int `json:"firewall_id,omitzero"` + Type NodeBalancerPlanType `json:"type,omitzero"` + VPCs []NodeBalancerVPCOptions `json:"vpcs,omitzero"` + IPv4 *string `json:"ipv4,omitzero"` } // NodeBalancerUpdateOptions are the options permitted for UpdateNodeBalancer type NodeBalancerUpdateOptions struct { - Label *string `json:"label,omitempty"` - ClientConnThrottle *int `json:"client_conn_throttle,omitempty"` + Label *string `json:"label,omitzero"` + ClientConnThrottle *int `json:"client_conn_throttle,omitzero"` // NOTE: ClientUDPSessThrottle may not currently be available to all users. - ClientUDPSessThrottle *int `json:"client_udp_sess_throttle,omitempty"` + ClientUDPSessThrottle *int `json:"client_udp_sess_throttle,omitzero"` - Tags *[]string `json:"tags,omitempty"` + Tags *[]string `json:"tags,omitzero"` } // NodeBalancerPlanType constants start with NBType and include Linode API NodeBalancer's plan types diff --git a/nodebalancer_config_nodes.go b/nodebalancer_config_nodes.go index 6516ba717..a98df52ea 100644 --- a/nodebalancer_config_nodes.go +++ b/nodebalancer_config_nodes.go @@ -38,18 +38,18 @@ var ( type NodeBalancerNodeCreateOptions struct { Address string `json:"address"` Label string `json:"label"` - Weight int `json:"weight,omitempty"` - Mode NodeMode `json:"mode,omitempty"` - SubnetID int `json:"subnet_id,omitempty"` + Weight int `json:"weight,omitzero"` + Mode NodeMode `json:"mode,omitzero"` + SubnetID int `json:"subnet_id,omitzero"` } // NodeBalancerNodeUpdateOptions fields are those accepted by UpdateNodeBalancerNode type NodeBalancerNodeUpdateOptions struct { - Address string `json:"address,omitempty"` - Label string `json:"label,omitempty"` - Weight int `json:"weight,omitempty"` - Mode NodeMode `json:"mode,omitempty"` - SubnetID int `json:"subnet_id,omitempty"` + Address string `json:"address,omitzero"` + Label string `json:"label,omitzero"` + Weight int `json:"weight,omitzero"` + Mode NodeMode `json:"mode,omitzero"` + SubnetID int `json:"subnet_id,omitzero"` } // GetCreateOptions converts a NodeBalancerNode to NodeBalancerNodeCreateOptions for use in CreateNodeBalancerNode diff --git a/nodebalancer_config_vpc.go b/nodebalancer_config_vpc.go index 122d4c9b8..3e3d8987c 100644 --- a/nodebalancer_config_vpc.go +++ b/nodebalancer_config_vpc.go @@ -10,7 +10,7 @@ import ( type NodeBalancerVPCConfig struct { ID int `json:"id"` IPv4Range string `json:"ipv4_range"` - IPv6Range string `json:"ipv6_range,omitempty"` + IPv6Range string `json:"ipv6_range,omitzero"` NodeBalancerID int `json:"nodebalancer_id"` SubnetID int `json:"subnet_id"` VPCID int `json:"vpc_id"` diff --git a/nodebalancer_configs.go b/nodebalancer_configs.go index 2c532837b..fee304fde 100644 --- a/nodebalancer_configs.go +++ b/nodebalancer_configs.go @@ -108,48 +108,48 @@ type NodeBalancerNodeStatus struct { // NodeBalancerConfigCreateOptions are permitted by CreateNodeBalancerConfig type NodeBalancerConfigCreateOptions struct { Port int `json:"port"` - Protocol ConfigProtocol `json:"protocol,omitempty"` - ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol,omitempty"` - Algorithm ConfigAlgorithm `json:"algorithm,omitempty"` - Stickiness ConfigStickiness `json:"stickiness,omitempty"` - Check ConfigCheck `json:"check,omitempty"` - CheckInterval int `json:"check_interval,omitempty"` - CheckAttempts int `json:"check_attempts,omitempty"` - CheckPath string `json:"check_path,omitempty"` - CheckBody string `json:"check_body,omitempty"` - CheckPassive *bool `json:"check_passive,omitempty"` - CheckTimeout int `json:"check_timeout,omitempty"` + Protocol ConfigProtocol `json:"protocol,omitzero"` + ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol,omitzero"` + Algorithm ConfigAlgorithm `json:"algorithm,omitzero"` + Stickiness ConfigStickiness `json:"stickiness,omitzero"` + Check ConfigCheck `json:"check,omitzero"` + CheckInterval int `json:"check_interval,omitzero"` + CheckAttempts int `json:"check_attempts,omitzero"` + CheckPath string `json:"check_path,omitzero"` + CheckBody string `json:"check_body,omitzero"` + CheckPassive *bool `json:"check_passive,omitzero"` + CheckTimeout int `json:"check_timeout,omitzero"` // NOTE: UDPCheckPort may not currently be available to all users. - UDPCheckPort *int `json:"udp_check_port,omitempty"` + UDPCheckPort *int `json:"udp_check_port,omitzero"` - CipherSuite ConfigCipher `json:"cipher_suite,omitempty"` - SSLCert string `json:"ssl_cert,omitempty"` - SSLKey string `json:"ssl_key,omitempty"` - Nodes []NodeBalancerNodeCreateOptions `json:"nodes,omitempty"` + CipherSuite ConfigCipher `json:"cipher_suite,omitzero"` + SSLCert string `json:"ssl_cert,omitzero"` + SSLKey string `json:"ssl_key,omitzero"` + Nodes []NodeBalancerNodeCreateOptions `json:"nodes,omitzero"` } // NodeBalancerConfigRebuildOptions used by RebuildNodeBalancerConfig type NodeBalancerConfigRebuildOptions struct { Port int `json:"port"` - Protocol ConfigProtocol `json:"protocol,omitempty"` - ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol,omitempty"` - Algorithm ConfigAlgorithm `json:"algorithm,omitempty"` - Stickiness ConfigStickiness `json:"stickiness,omitempty"` - Check ConfigCheck `json:"check,omitempty"` - CheckInterval int `json:"check_interval,omitempty"` - CheckAttempts int `json:"check_attempts,omitempty"` - CheckPath string `json:"check_path,omitempty"` - CheckBody string `json:"check_body,omitempty"` - CheckPassive *bool `json:"check_passive,omitempty"` - CheckTimeout int `json:"check_timeout,omitempty"` + Protocol ConfigProtocol `json:"protocol,omitzero"` + ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol,omitzero"` + Algorithm ConfigAlgorithm `json:"algorithm,omitzero"` + Stickiness ConfigStickiness `json:"stickiness,omitzero"` + Check ConfigCheck `json:"check,omitzero"` + CheckInterval int `json:"check_interval,omitzero"` + CheckAttempts int `json:"check_attempts,omitzero"` + CheckPath string `json:"check_path,omitzero"` + CheckBody string `json:"check_body,omitzero"` + CheckPassive *bool `json:"check_passive,omitzero"` + CheckTimeout int `json:"check_timeout,omitzero"` // NOTE: UDPCheckPort may not currently be available to all users. - UDPCheckPort *int `json:"udp_check_port,omitempty"` + UDPCheckPort *int `json:"udp_check_port,omitzero"` - CipherSuite ConfigCipher `json:"cipher_suite,omitempty"` - SSLCert string `json:"ssl_cert,omitempty"` - SSLKey string `json:"ssl_key,omitempty"` + CipherSuite ConfigCipher `json:"cipher_suite,omitzero"` + SSLCert string `json:"ssl_cert,omitzero"` + SSLKey string `json:"ssl_key,omitzero"` Nodes []NodeBalancerConfigRebuildNodeOptions `json:"nodes"` } @@ -158,7 +158,7 @@ type NodeBalancerConfigRebuildOptions struct { type NodeBalancerConfigRebuildNodeOptions struct { NodeBalancerNodeCreateOptions - ID int `json:"id,omitempty"` + ID int `json:"id,omitzero"` } // NodeBalancerConfigUpdateOptions are permitted by UpdateNodeBalancerConfig diff --git a/object_storage_buckets.go b/object_storage_buckets.go index d3e991a68..ba94e736a 100644 --- a/object_storage_buckets.go +++ b/object_storage_buckets.go @@ -70,20 +70,20 @@ func (i *ObjectStorageBucket) UnmarshalJSON(b []byte) error { // ObjectStorageBucketCreateOptions fields are those accepted by CreateObjectStorageBucket type ObjectStorageBucketCreateOptions struct { - Region string `json:"region,omitempty"` + Region string `json:"region,omitzero"` Label string `json:"label"` - S3Endpoint string `json:"s3_endpoint,omitempty"` - EndpointType ObjectStorageEndpointType `json:"endpoint_type,omitempty"` + S3Endpoint string `json:"s3_endpoint,omitzero"` + EndpointType ObjectStorageEndpointType `json:"endpoint_type,omitzero"` - ACL ObjectStorageACL `json:"acl,omitempty"` - CorsEnabled *bool `json:"cors_enabled,omitempty"` + ACL ObjectStorageACL `json:"acl,omitzero"` + CorsEnabled *bool `json:"cors_enabled,omitzero"` } // ObjectStorageBucketUpdateAccessOptions fields are those accepted by UpdateObjectStorageBucketAccess type ObjectStorageBucketUpdateAccessOptions struct { - ACL ObjectStorageACL `json:"acl,omitempty"` - CorsEnabled *bool `json:"cors_enabled,omitempty"` + ACL ObjectStorageACL `json:"acl,omitzero"` + CorsEnabled *bool `json:"cors_enabled,omitzero"` } // ObjectStorageBucketListContentsParams fields are the query parameters for ListObjectStorageBucketContents diff --git a/object_storage_keys.go b/object_storage_keys.go index a0b28065e..ad3f8c29e 100644 --- a/object_storage_keys.go +++ b/object_storage_keys.go @@ -23,7 +23,7 @@ type ObjectStorageKey struct { // ObjectStorageKeyBucketAccess represents a linode limited object storage key's bucket access type ObjectStorageKeyBucketAccess struct { - Region string `json:"region,omitempty"` + Region string `json:"region,omitzero"` BucketName string `json:"bucket_name"` Permissions string `json:"permissions"` @@ -32,14 +32,14 @@ type ObjectStorageKeyBucketAccess struct { // ObjectStorageKeyCreateOptions fields are those accepted by CreateObjectStorageKey type ObjectStorageKeyCreateOptions struct { Label string `json:"label"` - BucketAccess *[]ObjectStorageKeyBucketAccess `json:"bucket_access,omitempty"` - Regions []string `json:"regions,omitempty"` + BucketAccess *[]ObjectStorageKeyBucketAccess `json:"bucket_access,omitzero"` + Regions []string `json:"regions,omitzero"` } // ObjectStorageKeyUpdateOptions fields are those accepted by UpdateObjectStorageKey type ObjectStorageKeyUpdateOptions struct { - Label string `json:"label,omitempty"` - Regions []string `json:"regions,omitempty"` + Label string `json:"label,omitzero"` + Regions []string `json:"regions,omitzero"` } // ListObjectStorageKeys lists ObjectStorageKeys diff --git a/object_storage_object.go b/object_storage_object.go index 224d37152..1f2d6fbad 100644 --- a/object_storage_object.go +++ b/object_storage_object.go @@ -7,9 +7,9 @@ import ( type ObjectStorageObjectURLCreateOptions struct { Name string `json:"name"` Method string `json:"method"` - ContentType string `json:"content_type,omitempty"` - ContentDisposition string `json:"content_disposition,omitempty"` - ExpiresIn *int `json:"expires_in,omitempty"` + ContentType string `json:"content_type,omitzero"` + ContentDisposition string `json:"content_disposition,omitzero"` + ExpiresIn *int `json:"expires_in,omitzero"` } type ObjectStorageObjectURL struct { diff --git a/pagination.go b/pagination.go index 7addc7c01..57ca27ca7 100644 --- a/pagination.go +++ b/pagination.go @@ -16,9 +16,9 @@ import ( // PageOptions are the pagination parameters for List endpoints type PageOptions struct { - Page int `json:"page" url:"page,omitempty"` - Pages int `json:"pages" url:"pages,omitempty"` - Results int `json:"results" url:"results,omitempty"` + Page int `json:"page"` + Pages int `json:"pages"` + Results int `json:"results"` } // ListOptions are the pagination and filtering (TODO) parameters for endpoints diff --git a/placement_groups.go b/placement_groups.go index 189b3ace1..04effa2d9 100644 --- a/placement_groups.go +++ b/placement_groups.go @@ -61,14 +61,14 @@ type PlacementGroupCreateOptions struct { // PlacementGroupUpdateOptions represents the options to use // when updating a placement group. type PlacementGroupUpdateOptions struct { - Label string `json:"label,omitempty"` + Label string `json:"label,omitzero"` } // PlacementGroupAssignOptions represents options used when // assigning Linodes to a placement group. type PlacementGroupAssignOptions struct { Linodes []int `json:"linodes"` - CompliantOnly *bool `json:"compliant_only,omitempty"` + CompliantOnly *bool `json:"compliant_only,omitzero"` } // PlacementGroupUnAssignOptions represents options used when diff --git a/postgres.go b/postgres.go index ac4a78cf5..54f3a65c3 100644 --- a/postgres.go +++ b/postgres.go @@ -62,65 +62,65 @@ type PostgresDatabase struct { UsedDiskSizeGB int `json:"used_disk_size_gb"` TotalDiskSizeGB int `json:"total_disk_size_gb"` EngineConfig PostgresDatabaseEngineConfig `json:"engine_config"` - PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitempty"` + PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitzero"` } type PostgresDatabaseEngineConfig struct { - PG *PostgresDatabaseEngineConfigPG `json:"pg,omitempty"` - PGStatMonitorEnable *bool `json:"pg_stat_monitor_enable,omitempty"` - PGLookout *PostgresDatabaseEngineConfigPGLookout `json:"pglookout,omitempty"` - SharedBuffersPercentage *float64 `json:"shared_buffers_percentage,omitempty"` - WorkMem *int `json:"work_mem,omitempty"` + PG *PostgresDatabaseEngineConfigPG `json:"pg,omitzero"` + PGStatMonitorEnable *bool `json:"pg_stat_monitor_enable,omitzero"` + PGLookout *PostgresDatabaseEngineConfigPGLookout `json:"pglookout,omitzero"` + SharedBuffersPercentage *float64 `json:"shared_buffers_percentage,omitzero"` + WorkMem *int `json:"work_mem,omitzero"` } type PostgresDatabaseEngineConfigPG struct { - AutovacuumAnalyzeScaleFactor *float64 `json:"autovacuum_analyze_scale_factor,omitempty"` - AutovacuumAnalyzeThreshold *int32 `json:"autovacuum_analyze_threshold,omitempty"` - AutovacuumMaxWorkers *int `json:"autovacuum_max_workers,omitempty"` - AutovacuumNaptime *int `json:"autovacuum_naptime,omitempty"` - AutovacuumVacuumCostDelay *int `json:"autovacuum_vacuum_cost_delay,omitempty"` - AutovacuumVacuumCostLimit *int `json:"autovacuum_vacuum_cost_limit,omitempty"` - AutovacuumVacuumScaleFactor *float64 `json:"autovacuum_vacuum_scale_factor,omitempty"` - AutovacuumVacuumThreshold *int32 `json:"autovacuum_vacuum_threshold,omitempty"` - BGWriterDelay *int `json:"bgwriter_delay,omitempty"` - BGWriterFlushAfter *int `json:"bgwriter_flush_after,omitempty"` - BGWriterLRUMaxPages *int `json:"bgwriter_lru_maxpages,omitempty"` - BGWriterLRUMultiplier *float64 `json:"bgwriter_lru_multiplier,omitempty"` - DeadlockTimeout *int `json:"deadlock_timeout,omitempty"` - DefaultToastCompression *string `json:"default_toast_compression,omitempty"` - IdleInTransactionSessionTimeout *int `json:"idle_in_transaction_session_timeout,omitempty"` - JIT *bool `json:"jit,omitempty"` - MaxFilesPerProcess *int `json:"max_files_per_process,omitempty"` - MaxLocksPerTransaction *int `json:"max_locks_per_transaction,omitempty"` - MaxLogicalReplicationWorkers *int `json:"max_logical_replication_workers,omitempty"` - MaxParallelWorkers *int `json:"max_parallel_workers,omitempty"` - MaxParallelWorkersPerGather *int `json:"max_parallel_workers_per_gather,omitempty"` - MaxPredLocksPerTransaction *int `json:"max_pred_locks_per_transaction,omitempty"` - MaxReplicationSlots *int `json:"max_replication_slots,omitempty"` - MaxSlotWALKeepSize *int32 `json:"max_slot_wal_keep_size,omitempty"` - MaxStackDepth *int `json:"max_stack_depth,omitempty"` - MaxStandbyArchiveDelay *int `json:"max_standby_archive_delay,omitempty"` - MaxStandbyStreamingDelay *int `json:"max_standby_streaming_delay,omitempty"` - MaxWALSenders *int `json:"max_wal_senders,omitempty"` - MaxWorkerProcesses *int `json:"max_worker_processes,omitempty"` - PasswordEncryption *string `json:"password_encryption,omitempty"` - PGPartmanBGWInterval *int `json:"pg_partman_bgw.interval,omitempty"` - PGPartmanBGWRole *string `json:"pg_partman_bgw.role,omitempty"` - PGStatMonitorPGSMEnableQueryPlan *bool `json:"pg_stat_monitor.pgsm_enable_query_plan,omitempty"` - PGStatMonitorPGSMMaxBuckets *int `json:"pg_stat_monitor.pgsm_max_buckets,omitempty"` - PGStatStatementsTrack *string `json:"pg_stat_statements.track,omitempty"` - TempFileLimit *int32 `json:"temp_file_limit,omitempty"` - Timezone *string `json:"timezone,omitempty"` - TrackActivityQuerySize *int `json:"track_activity_query_size,omitempty"` - TrackCommitTimestamp *string `json:"track_commit_timestamp,omitempty"` - TrackFunctions *string `json:"track_functions,omitempty"` - TrackIOTiming *string `json:"track_io_timing,omitempty"` - WALSenderTimeout *int `json:"wal_sender_timeout,omitempty"` - WALWriterDelay *int `json:"wal_writer_delay,omitempty"` + AutovacuumAnalyzeScaleFactor *float64 `json:"autovacuum_analyze_scale_factor,omitzero"` + AutovacuumAnalyzeThreshold *int32 `json:"autovacuum_analyze_threshold,omitzero"` + AutovacuumMaxWorkers *int `json:"autovacuum_max_workers,omitzero"` + AutovacuumNaptime *int `json:"autovacuum_naptime,omitzero"` + AutovacuumVacuumCostDelay *int `json:"autovacuum_vacuum_cost_delay,omitzero"` + AutovacuumVacuumCostLimit *int `json:"autovacuum_vacuum_cost_limit,omitzero"` + AutovacuumVacuumScaleFactor *float64 `json:"autovacuum_vacuum_scale_factor,omitzero"` + AutovacuumVacuumThreshold *int32 `json:"autovacuum_vacuum_threshold,omitzero"` + BGWriterDelay *int `json:"bgwriter_delay,omitzero"` + BGWriterFlushAfter *int `json:"bgwriter_flush_after,omitzero"` + BGWriterLRUMaxPages *int `json:"bgwriter_lru_maxpages,omitzero"` + BGWriterLRUMultiplier *float64 `json:"bgwriter_lru_multiplier,omitzero"` + DeadlockTimeout *int `json:"deadlock_timeout,omitzero"` + DefaultToastCompression *string `json:"default_toast_compression,omitzero"` + IdleInTransactionSessionTimeout *int `json:"idle_in_transaction_session_timeout,omitzero"` + JIT *bool `json:"jit,omitzero"` + MaxFilesPerProcess *int `json:"max_files_per_process,omitzero"` + MaxLocksPerTransaction *int `json:"max_locks_per_transaction,omitzero"` + MaxLogicalReplicationWorkers *int `json:"max_logical_replication_workers,omitzero"` + MaxParallelWorkers *int `json:"max_parallel_workers,omitzero"` + MaxParallelWorkersPerGather *int `json:"max_parallel_workers_per_gather,omitzero"` + MaxPredLocksPerTransaction *int `json:"max_pred_locks_per_transaction,omitzero"` + MaxReplicationSlots *int `json:"max_replication_slots,omitzero"` + MaxSlotWALKeepSize *int32 `json:"max_slot_wal_keep_size,omitzero"` + MaxStackDepth *int `json:"max_stack_depth,omitzero"` + MaxStandbyArchiveDelay *int `json:"max_standby_archive_delay,omitzero"` + MaxStandbyStreamingDelay *int `json:"max_standby_streaming_delay,omitzero"` + MaxWALSenders *int `json:"max_wal_senders,omitzero"` + MaxWorkerProcesses *int `json:"max_worker_processes,omitzero"` + PasswordEncryption *string `json:"password_encryption,omitzero"` + PGPartmanBGWInterval *int `json:"pg_partman_bgw.interval,omitzero"` + PGPartmanBGWRole *string `json:"pg_partman_bgw.role,omitzero"` + PGStatMonitorPGSMEnableQueryPlan *bool `json:"pg_stat_monitor.pgsm_enable_query_plan,omitzero"` + PGStatMonitorPGSMMaxBuckets *int `json:"pg_stat_monitor.pgsm_max_buckets,omitzero"` + PGStatStatementsTrack *string `json:"pg_stat_statements.track,omitzero"` + TempFileLimit *int32 `json:"temp_file_limit,omitzero"` + Timezone *string `json:"timezone,omitzero"` + TrackActivityQuerySize *int `json:"track_activity_query_size,omitzero"` + TrackCommitTimestamp *string `json:"track_commit_timestamp,omitzero"` + TrackFunctions *string `json:"track_functions,omitzero"` + TrackIOTiming *string `json:"track_io_timing,omitzero"` + WALSenderTimeout *int `json:"wal_sender_timeout,omitzero"` + WALWriterDelay *int `json:"wal_writer_delay,omitzero"` } type PostgresDatabaseEngineConfigPGLookout struct { - MaxFailoverReplicationTimeLag *int64 `json:"max_failover_replication_time_lag,omitempty"` + MaxFailoverReplicationTimeLag *int64 `json:"max_failover_replication_time_lag,omitzero"` } type PostgresDatabaseConfigInfo struct { @@ -594,25 +594,25 @@ type PostgresCreateOptions struct { Region string `json:"region"` Type string `json:"type"` Engine string `json:"engine"` - AllowList []string `json:"allow_list,omitempty"` - ClusterSize int `json:"cluster_size,omitempty"` + AllowList []string `json:"allow_list,omitzero"` + ClusterSize int `json:"cluster_size,omitzero"` - Fork *DatabaseFork `json:"fork,omitempty"` + Fork *DatabaseFork `json:"fork,omitzero"` - EngineConfig *PostgresDatabaseEngineConfig `json:"engine_config,omitempty"` - PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitempty"` + EngineConfig *PostgresDatabaseEngineConfig `json:"engine_config,omitzero"` + PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitzero"` } // PostgresUpdateOptions fields are used when altering the existing Postgres Database type PostgresUpdateOptions struct { - Label string `json:"label,omitempty"` - AllowList *[]string `json:"allow_list,omitempty"` - Updates *DatabaseMaintenanceWindow `json:"updates,omitempty"` - Type string `json:"type,omitempty"` - ClusterSize int `json:"cluster_size,omitempty"` - Version string `json:"version,omitempty"` - EngineConfig *PostgresDatabaseEngineConfig `json:"engine_config,omitempty"` - PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitempty"` + Label string `json:"label,omitzero"` + AllowList *[]string `json:"allow_list,omitzero"` + Updates *DatabaseMaintenanceWindow `json:"updates,omitzero"` + Type string `json:"type,omitzero"` + ClusterSize int `json:"cluster_size,omitzero"` + Version string `json:"version,omitzero"` + EngineConfig *PostgresDatabaseEngineConfig `json:"engine_config,omitzero"` + PrivateNetwork *DatabasePrivateNetwork `json:"private_network,omitzero"` } // PostgresDatabaseSSL is the SSL Certificate to access the Linode Managed Postgres Database diff --git a/profile.go b/profile.go index c290d62b5..087cf6b69 100644 --- a/profile.go +++ b/profile.go @@ -38,19 +38,19 @@ type Profile struct { Referrals ProfileReferrals `json:"referrals"` AuthorizedKeys []string `json:"authorized_keys"` AuthenticationType string `json:"authentication_type"` - VerifiedPhoneNumber string `json:"verified_phone_number,omitempty"` + VerifiedPhoneNumber string `json:"verified_phone_number,omitzero"` } // ProfileUpdateOptions fields are those accepted by UpdateProfile type ProfileUpdateOptions struct { - Email string `json:"email,omitempty"` - Timezone string `json:"timezone,omitempty"` - EmailNotifications *bool `json:"email_notifications,omitempty"` - IPWhitelistEnabled *bool `json:"ip_whitelist_enabled,omitempty"` - LishAuthMethod LishAuthMethod `json:"lish_auth_method,omitempty"` - AuthorizedKeys *[]string `json:"authorized_keys,omitempty"` - TwoFactorAuth *bool `json:"two_factor_auth,omitempty"` - Restricted *bool `json:"restricted,omitempty"` + Email string `json:"email,omitzero"` + Timezone string `json:"timezone,omitzero"` + EmailNotifications *bool `json:"email_notifications,omitzero"` + IPWhitelistEnabled *bool `json:"ip_whitelist_enabled,omitzero"` + LishAuthMethod LishAuthMethod `json:"lish_auth_method,omitzero"` + AuthorizedKeys *[]string `json:"authorized_keys,omitzero"` + TwoFactorAuth *bool `json:"two_factor_auth,omitzero"` + Restricted *bool `json:"restricted,omitzero"` } // GetUpdateOptions converts a Profile to ProfileUpdateOptions for use in UpdateProfile diff --git a/request_helpers.go b/request_helpers.go index b63f56ec9..1dc46c132 100644 --- a/request_helpers.go +++ b/request_helpers.go @@ -13,9 +13,9 @@ import ( // paginatedResponse represents a single response from a paginated // endpoint. type paginatedResponse[T any] struct { - Page int `json:"page" url:"page,omitempty"` - Pages int `json:"pages" url:"pages,omitempty"` - Results int `json:"results" url:"results,omitempty"` + Page int `json:"page"` + Pages int `json:"pages"` + Results int `json:"results"` Data []T `json:"data"` } diff --git a/stackscripts.go b/stackscripts.go index 19b61ce4c..1a8f55e27 100644 --- a/stackscripts.go +++ b/stackscripts.go @@ -41,13 +41,13 @@ type StackscriptUDF struct { Example string `json:"example"` // A list of acceptable single values for the field. - OneOf string `json:"oneOf,omitempty"` + OneOf string `json:"oneOf,omitzero"` // A list of acceptable values for the field in any quantity, combination or order. - ManyOf string `json:"manyOf,omitempty"` + ManyOf string `json:"manyOf,omitzero"` // The default value. If not specified, this value will be used. - Default string `json:"default,omitempty"` + Default string `json:"default,omitzero"` } // StackscriptCreateOptions fields are those accepted by CreateStackscript diff --git a/tags.go b/tags.go index e23ba2168..bfadc0a8b 100644 --- a/tags.go +++ b/tags.go @@ -36,12 +36,12 @@ type TaggedObjectList []TaggedObject // TagCreateOptions fields are those accepted by CreateTag type TagCreateOptions struct { Label string `json:"label"` - Linodes []int `json:"linodes,omitempty"` + Linodes []int `json:"linodes,omitzero"` // @TODO is this implemented? - LKEClusters []int `json:"lke_clusters,omitempty"` - Domains []int `json:"domains,omitempty"` - Volumes []int `json:"volumes,omitempty"` - NodeBalancers []int `json:"nodebalancers,omitempty"` + LKEClusters []int `json:"lke_clusters,omitzero"` + Domains []int `json:"domains,omitzero"` + Volumes []int `json:"volumes,omitzero"` + NodeBalancers []int `json:"nodebalancers,omitzero"` } // GetCreateOptions converts a Tag to TagCreateOptions for use in CreateTag diff --git a/volumes.go b/volumes.go index 2fc8fc802..b93d8976c 100644 --- a/volumes.go +++ b/volumes.go @@ -45,29 +45,29 @@ type Volume struct { // VolumeCreateOptions fields are those accepted by CreateVolume type VolumeCreateOptions struct { - Label string `json:"label,omitempty"` - Region string `json:"region,omitempty"` - LinodeID int `json:"linode_id,omitempty"` - ConfigID int `json:"config_id,omitempty"` + Label string `json:"label,omitzero"` + Region string `json:"region,omitzero"` + LinodeID int `json:"linode_id,omitzero"` + ConfigID int `json:"config_id,omitzero"` // The Volume's size, in GiB. Minimum size is 10GiB, maximum size is 10240GiB. A "0" value will result in the default size. - Size int `json:"size,omitempty"` + Size int `json:"size,omitzero"` // An array of tags applied to this object. Tags are for organizational purposes only. Tags []string `json:"tags"` - PersistAcrossBoots *bool `json:"persist_across_boots,omitempty"` - Encryption string `json:"encryption,omitempty"` + PersistAcrossBoots *bool `json:"persist_across_boots,omitzero"` + Encryption string `json:"encryption,omitzero"` } // VolumeUpdateOptions fields are those accepted by UpdateVolume type VolumeUpdateOptions struct { - Label string `json:"label,omitempty"` - Tags *[]string `json:"tags,omitempty"` + Label string `json:"label,omitzero"` + Tags *[]string `json:"tags,omitzero"` } // VolumeAttachOptions fields are those accepted by AttachVolume type VolumeAttachOptions struct { LinodeID int `json:"linode_id"` - ConfigID int `json:"config_id,omitempty"` - PersistAcrossBoots *bool `json:"persist_across_boots,omitempty"` + ConfigID int `json:"config_id,omitzero"` + PersistAcrossBoots *bool `json:"persist_across_boots,omitzero"` } // UnmarshalJSON implements the json.Unmarshaler interface diff --git a/vpc.go b/vpc.go index 6b26f6bc2..1c839bcda 100644 --- a/vpc.go +++ b/vpc.go @@ -30,26 +30,26 @@ type VPCIPv6Range struct { type VPCCreateOptions struct { Label string `json:"label"` - Description string `json:"description,omitempty"` + Description string `json:"description,omitzero"` Region string `json:"region"` // NOTE: IPv6 VPCs may not currently be available to all users. - IPv6 []VPCCreateOptionsIPv6 `json:"ipv6,omitempty"` + IPv6 []VPCCreateOptionsIPv6 `json:"ipv6,omitzero"` - Subnets []VPCSubnetCreateOptions `json:"subnets,omitempty"` + Subnets []VPCSubnetCreateOptions `json:"subnets,omitzero"` } // VPCCreateOptionsIPv6 represents a single IPv6 range assigned to a VPC // which is specified during a VPC's creation. // NOTE: IPv6 VPCs may not currently be available to all users. type VPCCreateOptionsIPv6 struct { - Range *string `json:"range,omitempty"` - AllocationClass *string `json:"allocation_class,omitempty"` + Range *string `json:"range,omitzero"` + AllocationClass *string `json:"allocation_class,omitzero"` } type VPCUpdateOptions struct { - Label string `json:"label,omitempty"` - Description string `json:"description,omitempty"` + Label string `json:"label,omitzero"` + Description string `json:"description,omitzero"` } func (v VPC) GetCreateOptions() VPCCreateOptions { diff --git a/vpc_subnet.go b/vpc_subnet.go index e44b61326..a3cddc4d6 100644 --- a/vpc_subnet.go +++ b/vpc_subnet.go @@ -62,14 +62,14 @@ type VPCSubnetCreateOptions struct { IPv4 string `json:"ipv4"` // NOTE: IPv6 VPCs may not currently be available to all users. - IPv6 []VPCSubnetCreateOptionsIPv6 `json:"ipv6,omitempty"` + IPv6 []VPCSubnetCreateOptionsIPv6 `json:"ipv6,omitzero"` } // VPCSubnetCreateOptionsIPv6 represents a single IPv6 range assigned to a VPC // which is specified during a VPC subnet's creation. // NOTE: IPv6 VPCs may not currently be available to all users. type VPCSubnetCreateOptionsIPv6 struct { - Range *string `json:"range,omitempty"` + Range *string `json:"range,omitzero"` } type VPCSubnetUpdateOptions struct { From 8b7a4542a64398f549f941fd1a11bfbe4f3379df Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Wed, 6 May 2026 13:26:06 -0400 Subject: [PATCH 04/17] TPT-4414: Change slice pointer types with `omitzero` to be slice (#954) * Refactor: Change pointer slices to slices for various fields with omitzero * Refresh fixtures * Update TestLKECluster_Update to remove pinned lke versions in test --- firewall_rules.go | 4 +- firewall_rulesets.go | 6 +- firewalls.go | 4 +- images.go | 36 +- instance_config_interfaces.go | 14 +- instances.go | 4 +- interfaces.go | 14 +- lke_clusters.go | 4 +- lke_clusters_control_plane.go | 4 +- lke_node_pools.go | 14 +- mysql.go | 2 +- nodebalancer.go | 4 +- object_storage_keys.go | 6 +- postgres.go | 2 +- profile.go | 4 +- test/integration/firewall_rules_test.go | 8 +- test/integration/firewall_rulesets_test.go | 6 +- test/integration/firewalls_test.go | 12 +- .../fixtures/TestFirewallDevice_Delete.yaml | 487 ++++------ .../fixtures/TestFirewallDevice_Get.yaml | 499 ++++------ .../fixtures/TestFirewallDevices_List.yaml | 483 ++++------ .../fixtures/TestFirewallRuleSets_CRUD.yaml | 69 +- .../fixtures/TestFirewallRules_Get.yaml | 14 +- .../fixtures/TestFirewallRules_Update.yaml | 64 +- .../fixtures/TestFirewallSettings_Get.yaml | 10 +- .../TestFirewallSettings_UpdateAllFields.yaml | 46 +- .../TestFirewallSettings_UpdatePartial.yaml | 48 +- .../fixtures/TestFirewallTemplate_Get.yaml | 16 +- .../fixtures/TestFirewallTemplates_List.yaml | 59 +- .../fixtures/TestFirewall_Get.yaml | 14 +- .../fixtures/TestFirewall_Update.yaml | 14 +- .../fixtures/TestFirewalls_List.yaml | 219 ++--- .../fixtures/TestImage_CloudInit.yaml | 877 ++++++++++-------- .../TestInstance_ConfigInterface_Update.yaml | 694 ++++++++------ ...stInstance_CreateWithLinodeInterfaces.yaml | 719 ++++---------- .../fixtures/TestLKECluster_Update.yaml | 778 ++++++++++------ .../fixtures/TestLKECluster_withACL.yaml | 713 ++++++++------ .../fixtures/TestLKENodePool_Update.yaml | 546 ++++++----- .../fixtures/TestObjectStorageKey_List.yaml | 39 +- .../TestObjectStorageKeys_Limited.yaml | 8 +- .../TestObjectStorageKeys_Limited_Bucket.yaml | 4 +- ...estObjectStorageKeys_Regional_Limited.yaml | 426 +++++---- test/integration/fixtures/TestTag_Create.yaml | 829 ++++++++++------- test/integration/images_test.go | 4 +- test/integration/instance_config_test.go | 2 +- test/integration/instance_interfaces_test.go | 4 +- test/integration/lke_clusters_acl_test.go | 8 +- test/integration/lke_clusters_test.go | 11 +- test/integration/lke_node_pools_test.go | 8 +- test/integration/main_test.go | 2 +- test/integration/mysql_test.go | 2 +- test/integration/object_storage_keys_test.go | 10 +- test/integration/postgres_test.go | 2 +- test/integration/tags_test.go | 7 +- test/unit/firewall_rules_test.go | 42 +- test/unit/firewall_rulesets_test.go | 10 +- test/unit/firewalls_test.go | 38 +- test/unit/images_test.go | 6 +- test/unit/instance_config_interfaces_test.go | 2 +- test/unit/interface_test.go | 10 +- .../lke_cluster_control_plane_acl_test.go | 4 +- test/unit/lke_clusters_test.go | 2 +- test/unit/lke_node_pools_test.go | 2 +- test/unit/nodebalancer_test.go | 2 +- test/unit/volume_test.go | 2 +- volumes.go | 6 +- 66 files changed, 4106 insertions(+), 3903 deletions(-) diff --git a/firewall_rules.go b/firewall_rules.go index c6bde2bd1..548a9aa6c 100644 --- a/firewall_rules.go +++ b/firewall_rules.go @@ -18,8 +18,8 @@ const ( // NetworkAddresses are arrays of ipv4 and v6 addresses type NetworkAddresses struct { - IPv4 *[]string `json:"ipv4,omitzero"` - IPv6 *[]string `json:"ipv6,omitzero"` + IPv4 []string `json:"ipv4,omitzero"` + IPv6 []string `json:"ipv6,omitzero"` } // A FirewallRule is a whitelist of ports, protocols, and addresses for which traffic should be allowed. diff --git a/firewall_rulesets.go b/firewall_rulesets.go index 097c25c81..97d5182f9 100644 --- a/firewall_rulesets.go +++ b/firewall_rulesets.go @@ -78,9 +78,9 @@ type RuleSetCreateOptions struct { // Omit a top-level field to leave it unchanged. If Rules is provided, it // replaces the entire ordered rules array. type RuleSetUpdateOptions struct { - Label *string `json:"label,omitzero"` - Description *string `json:"description,omitzero"` - Rules *[]FirewallRule `json:"rules,omitzero"` + Label *string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` + Rules []FirewallRule `json:"rules,omitzero"` } // ListFirewallRuleSets returns a paginated list of Rule Sets. diff --git a/firewalls.go b/firewalls.go index abf503414..02cbd9799 100644 --- a/firewalls.go +++ b/firewalls.go @@ -49,7 +49,7 @@ type FirewallCreateOptions struct { type FirewallUpdateOptions struct { Label string `json:"label,omitzero"` Status FirewallStatus `json:"status,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Tags []string `json:"tags,omitzero"` } // FirewallSettings represents the default firewalls for Linodes, @@ -82,7 +82,7 @@ func (f *Firewall) GetUpdateOptions() FirewallUpdateOptions { return FirewallUpdateOptions{ Label: f.Label, Status: f.Status, - Tags: &f.Tags, + Tags: f.Tags, } } diff --git a/images.go b/images.go index 57203047e..aed63b48a 100644 --- a/images.go +++ b/images.go @@ -115,18 +115,18 @@ type ImageShareEntry struct { // ImageCreateOptions fields are those accepted by CreateImage type ImageCreateOptions struct { - DiskID int `json:"disk_id"` - Label string `json:"label"` - Description string `json:"description,omitzero"` - CloudInit bool `json:"cloud_init,omitzero"` - Tags *[]string `json:"tags,omitzero"` + DiskID int `json:"disk_id"` + Label string `json:"label"` + Description string `json:"description,omitzero"` + CloudInit bool `json:"cloud_init,omitzero"` + Tags []string `json:"tags,omitzero"` } // ImageUpdateOptions fields are those accepted by UpdateImage type ImageUpdateOptions struct { - Label string `json:"label,omitzero"` - Description *string `json:"description,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Label string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` + Tags []string `json:"tags,omitzero"` } // ImageReplicateOptions represents the options accepted by the @@ -143,20 +143,20 @@ type ImageCreateUploadResponse struct { // ImageCreateUploadOptions fields are those accepted by CreateImageUpload type ImageCreateUploadOptions struct { - Region string `json:"region"` - Label string `json:"label"` - Description string `json:"description,omitzero"` - CloudInit bool `json:"cloud_init,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Region string `json:"region"` + Label string `json:"label"` + Description string `json:"description,omitzero"` + CloudInit bool `json:"cloud_init,omitzero"` + Tags []string `json:"tags,omitzero"` } // ImageUploadOptions fields are those accepted by UploadImage type ImageUploadOptions struct { - Region string `json:"region"` - Label string `json:"label"` - Description string `json:"description,omitzero"` - CloudInit bool `json:"cloud_init"` - Tags *[]string `json:"tags,omitzero"` + Region string `json:"region"` + Label string `json:"label"` + Description string `json:"description,omitzero"` + CloudInit bool `json:"cloud_init"` + Tags []string `json:"tags,omitzero"` Image io.Reader } diff --git a/instance_config_interfaces.go b/instance_config_interfaces.go index be218402f..d9dd06764 100644 --- a/instance_config_interfaces.go +++ b/instance_config_interfaces.go @@ -93,16 +93,16 @@ type InstanceConfigInterfaceUpdateOptions struct { // NOTE: IPv6 interfaces may not currently be available to all users. IPv6 *InstanceConfigInterfaceUpdateOptionsIPv6 `json:"ipv6,omitzero"` - IPRanges *[]string `json:"ip_ranges,omitzero"` + IPRanges []string `json:"ip_ranges,omitzero"` } // InstanceConfigInterfaceUpdateOptionsIPv6 represents the IPv6 configuration of a Linode interface // specified during updates. // NOTE: IPv6 interfaces may not currently be available to all users. type InstanceConfigInterfaceUpdateOptionsIPv6 struct { - SLAAC *[]InstanceConfigInterfaceUpdateOptionsIPv6SLAAC `json:"slaac,omitzero"` - Ranges *[]InstanceConfigInterfaceUpdateOptionsIPv6Range `json:"ranges,omitzero"` - IsPublic *bool `json:"is_public,omitzero"` + SLAAC []InstanceConfigInterfaceUpdateOptionsIPv6SLAAC `json:"slaac,omitzero"` + Ranges []InstanceConfigInterfaceUpdateOptionsIPv6Range `json:"ranges,omitzero"` + IsPublic *bool `json:"is_public,omitzero"` } // InstanceConfigInterfaceUpdateOptionsIPv6SLAAC represents a single IPv6 SLAAC of a Linode interface @@ -217,8 +217,8 @@ func (i InstanceConfigInterface) GetUpdateOptions() InstanceConfigInterfaceUpdat ) opts.IPv6 = &InstanceConfigInterfaceUpdateOptionsIPv6{ - SLAAC: &newSLAAC, - Ranges: &newRanges, + SLAAC: newSLAAC, + Ranges: newRanges, IsPublic: copyValue(ipv6.IsPublic), } } @@ -230,7 +230,7 @@ func (i InstanceConfigInterface) GetUpdateOptions() InstanceConfigInterfaceUpdat copiedIPRanges := make([]string, len(i.IPRanges)) copy(copiedIPRanges, i.IPRanges) - opts.IPRanges = &copiedIPRanges + opts.IPRanges = copiedIPRanges } return opts diff --git a/instances.go b/instances.go index f80115d6b..d67ed6c95 100644 --- a/instances.go +++ b/instances.go @@ -214,7 +214,7 @@ type InstanceUpdateOptions struct { Backups *InstanceBackup `json:"backups,omitzero"` Alerts *InstanceAlert `json:"alerts,omitzero"` WatchdogEnabled *bool `json:"watchdog_enabled,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Tags []string `json:"tags,omitzero"` MaintenancePolicy *string `json:"maintenance_policy,omitzero"` } @@ -347,7 +347,7 @@ func (i *Instance) GetUpdateOptions() InstanceUpdateOptions { Backups: i.Backups, Alerts: i.Alerts, WatchdogEnabled: &i.WatchdogEnabled, - Tags: &i.Tags, + Tags: i.Tags, MaintenancePolicy: &i.MaintenancePolicy, } } diff --git a/interfaces.go b/interfaces.go index 1a2b8081b..7d812c820 100644 --- a/interfaces.go +++ b/interfaces.go @@ -131,7 +131,7 @@ type PublicInterfaceCreateOptions struct { } type PublicInterfaceIPv4CreateOptions struct { - Addresses *[]PublicInterfaceIPv4AddressCreateOptions `json:"addresses,omitzero"` + Addresses []PublicInterfaceIPv4AddressCreateOptions `json:"addresses,omitzero"` } type PublicInterfaceIPv4AddressCreateOptions struct { @@ -140,7 +140,7 @@ type PublicInterfaceIPv4AddressCreateOptions struct { } type PublicInterfaceIPv6CreateOptions struct { - Ranges *[]PublicInterfaceIPv6RangeCreateOptions `json:"ranges,omitzero"` + Ranges []PublicInterfaceIPv6RangeCreateOptions `json:"ranges,omitzero"` } type PublicInterfaceIPv6RangeCreateOptions struct { @@ -154,8 +154,8 @@ type VPCInterfaceCreateOptions struct { } type VPCInterfaceIPv4CreateOptions struct { - Addresses *[]VPCInterfaceIPv4AddressCreateOptions `json:"addresses,omitzero"` - Ranges *[]VPCInterfaceIPv4RangeCreateOptions `json:"ranges,omitzero"` + Addresses []VPCInterfaceIPv4AddressCreateOptions `json:"addresses,omitzero"` + Ranges []VPCInterfaceIPv4RangeCreateOptions `json:"ranges,omitzero"` } type VPCInterfaceIPv4AddressCreateOptions struct { @@ -171,9 +171,9 @@ type VPCInterfaceIPv4RangeCreateOptions struct { // VPCInterfaceIPv6CreateOptions specifies IPv6 configuration parameters for VPC creation. // NOTE: IPv6 interfaces may not currently be available to all users. type VPCInterfaceIPv6CreateOptions struct { - SLAAC *[]VPCInterfaceIPv6SLAACCreateOptions `json:"slaac,omitzero"` - Ranges *[]VPCInterfaceIPv6RangeCreateOptions `json:"ranges,omitzero"` - IsPublic *bool `json:"is_public"` + SLAAC []VPCInterfaceIPv6SLAACCreateOptions `json:"slaac,omitzero"` + Ranges []VPCInterfaceIPv6RangeCreateOptions `json:"ranges,omitzero"` + IsPublic *bool `json:"is_public"` } // VPCInterfaceIPv6SLAACCreateOptions defines the IPv6 SLAAC configuration parameters for VPC creation. diff --git a/lke_clusters.go b/lke_clusters.go index c12c08fc8..0fadf2f70 100644 --- a/lke_clusters.go +++ b/lke_clusters.go @@ -74,7 +74,7 @@ type LKEClusterCreateOptions struct { type LKEClusterUpdateOptions struct { K8sVersion string `json:"k8s_version,omitzero"` Label string `json:"label,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Tags []string `json:"tags,omitzero"` ControlPlane *LKEClusterControlPlaneOptions `json:"control_plane,omitzero"` } @@ -165,7 +165,7 @@ func (i LKECluster) GetCreateOptions() (o LKEClusterCreateOptions) { func (i LKECluster) GetUpdateOptions() (o LKEClusterUpdateOptions) { o.K8sVersion = i.K8sVersion o.Label = i.Label - o.Tags = &i.Tags + o.Tags = i.Tags isHA := i.ControlPlane.HighAvailability diff --git a/lke_clusters_control_plane.go b/lke_clusters_control_plane.go index c5080ac56..86a062186 100644 --- a/lke_clusters_control_plane.go +++ b/lke_clusters_control_plane.go @@ -28,8 +28,8 @@ type LKEClusterControlPlaneACL struct { // LKEClusterControlPlaneACLAddressesOptions are the options used to // specify the allowed IP ranges for an LKE cluster's control plane. type LKEClusterControlPlaneACLAddressesOptions struct { - IPv4 *[]string `json:"ipv4,omitzero"` - IPv6 *[]string `json:"ipv6,omitzero"` + IPv4 []string `json:"ipv4,omitzero"` + IPv6 []string `json:"ipv6,omitzero"` } // LKEClusterControlPlaneACLOptions represents the options used when diff --git a/lke_node_pools.go b/lke_node_pools.go index 3cba06eee..3efbc21ee 100644 --- a/lke_node_pools.go +++ b/lke_node_pools.go @@ -108,11 +108,11 @@ type LKENodePoolCreateOptions struct { // LKENodePoolUpdateOptions fields are those accepted by UpdateLKENodePoolUpdate type LKENodePoolUpdateOptions struct { - Count int `json:"count,omitzero"` - Tags *[]string `json:"tags,omitzero"` - Labels *LKENodePoolLabels `json:"labels,omitzero"` - Taints *[]LKENodePoolTaint `json:"taints,omitzero"` - Label *string `json:"label,omitzero"` + Count int `json:"count,omitzero"` + Tags []string `json:"tags,omitzero"` + Labels *LKENodePoolLabels `json:"labels,omitzero"` + Taints []LKENodePoolTaint `json:"taints,omitzero"` + Label *string `json:"label,omitzero"` Autoscaler *LKENodePoolAutoscaler `json:"autoscaler,omitzero"` FirewallID *int `json:"firewall_id,omitzero"` @@ -144,9 +144,9 @@ func (l LKENodePool) GetCreateOptions() (o LKENodePoolCreateOptions) { // GetUpdateOptions converts a LKENodePool to LKENodePoolUpdateOptions for use in UpdateLKENodePoolUpdate func (l LKENodePool) GetUpdateOptions() (o LKENodePoolUpdateOptions) { o.Count = l.Count - o.Tags = &l.Tags + o.Tags = l.Tags o.Labels = &l.Labels - o.Taints = &l.Taints + o.Taints = l.Taints o.Autoscaler = &l.Autoscaler o.K8sVersion = l.K8sVersion o.UpdateStrategy = l.UpdateStrategy diff --git a/mysql.go b/mysql.go index 78caf4fea..bd1607366 100644 --- a/mysql.go +++ b/mysql.go @@ -408,7 +408,7 @@ type MySQLCreateOptions struct { // MySQLUpdateOptions fields are used when altering the existing MySQL Database type MySQLUpdateOptions struct { Label string `json:"label,omitzero"` - AllowList *[]string `json:"allow_list,omitzero"` + AllowList []string `json:"allow_list,omitzero"` Updates *DatabaseMaintenanceWindow `json:"updates,omitzero"` Type string `json:"type,omitzero"` ClusterSize int `json:"cluster_size,omitzero"` diff --git a/nodebalancer.go b/nodebalancer.go index af6c4a33d..b1877ec4f 100644 --- a/nodebalancer.go +++ b/nodebalancer.go @@ -88,7 +88,7 @@ type NodeBalancerUpdateOptions struct { // NOTE: ClientUDPSessThrottle may not currently be available to all users. ClientUDPSessThrottle *int `json:"client_udp_sess_throttle,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Tags []string `json:"tags,omitzero"` } // NodeBalancerPlanType constants start with NBType and include Linode API NodeBalancer's plan types @@ -142,7 +142,7 @@ func (i NodeBalancer) GetUpdateOptions() NodeBalancerUpdateOptions { Label: i.Label, ClientConnThrottle: &i.ClientConnThrottle, ClientUDPSessThrottle: &i.ClientUDPSessThrottle, - Tags: &i.Tags, + Tags: i.Tags, } } diff --git a/object_storage_keys.go b/object_storage_keys.go index ad3f8c29e..b372bb3bf 100644 --- a/object_storage_keys.go +++ b/object_storage_keys.go @@ -31,9 +31,9 @@ type ObjectStorageKeyBucketAccess struct { // ObjectStorageKeyCreateOptions fields are those accepted by CreateObjectStorageKey type ObjectStorageKeyCreateOptions struct { - Label string `json:"label"` - BucketAccess *[]ObjectStorageKeyBucketAccess `json:"bucket_access,omitzero"` - Regions []string `json:"regions,omitzero"` + Label string `json:"label"` + BucketAccess []ObjectStorageKeyBucketAccess `json:"bucket_access,omitzero"` + Regions []string `json:"regions,omitzero"` } // ObjectStorageKeyUpdateOptions fields are those accepted by UpdateObjectStorageKey diff --git a/postgres.go b/postgres.go index 54f3a65c3..c410156a5 100644 --- a/postgres.go +++ b/postgres.go @@ -606,7 +606,7 @@ type PostgresCreateOptions struct { // PostgresUpdateOptions fields are used when altering the existing Postgres Database type PostgresUpdateOptions struct { Label string `json:"label,omitzero"` - AllowList *[]string `json:"allow_list,omitzero"` + AllowList []string `json:"allow_list,omitzero"` Updates *DatabaseMaintenanceWindow `json:"updates,omitzero"` Type string `json:"type,omitzero"` ClusterSize int `json:"cluster_size,omitzero"` diff --git a/profile.go b/profile.go index 087cf6b69..68e6bb0dd 100644 --- a/profile.go +++ b/profile.go @@ -48,7 +48,7 @@ type ProfileUpdateOptions struct { EmailNotifications *bool `json:"email_notifications,omitzero"` IPWhitelistEnabled *bool `json:"ip_whitelist_enabled,omitzero"` LishAuthMethod LishAuthMethod `json:"lish_auth_method,omitzero"` - AuthorizedKeys *[]string `json:"authorized_keys,omitzero"` + AuthorizedKeys []string `json:"authorized_keys,omitzero"` TwoFactorAuth *bool `json:"two_factor_auth,omitzero"` Restricted *bool `json:"restricted,omitzero"` } @@ -62,7 +62,7 @@ func (i Profile) GetUpdateOptions() (o ProfileUpdateOptions) { o.LishAuthMethod = i.LishAuthMethod authorizedKeys := make([]string, len(i.AuthorizedKeys)) copy(authorizedKeys, i.AuthorizedKeys) - o.AuthorizedKeys = &authorizedKeys + o.AuthorizedKeys = authorizedKeys o.TwoFactorAuth = copyBool(&i.TwoFactorAuth) o.Restricted = copyBool(&i.Restricted) diff --git a/test/integration/firewall_rules_test.go b/test/integration/firewall_rules_test.go index a32331f7c..dda91056e 100644 --- a/test/integration/firewall_rules_test.go +++ b/test/integration/firewall_rules_test.go @@ -15,8 +15,8 @@ var ( Ports: "22", Protocol: "TCP", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"0.0.0.0/0"}, - IPv6: &[]string{"::0/0"}, + IPv4: []string{"0.0.0.0/0"}, + IPv6: []string{"::0/0"}, }, } @@ -82,8 +82,8 @@ func TestFirewallRules_Update(t *testing.T) { Ports: "22", Protocol: "TCP", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"0.0.0.0/0"}, - IPv6: &[]string{"::0/0"}, + IPv4: []string{"0.0.0.0/0"}, + IPv6: []string{"::0/0"}, }, }, }, diff --git a/test/integration/firewall_rulesets_test.go b/test/integration/firewall_rulesets_test.go index db7601f7b..4bb1c2398 100644 --- a/test/integration/firewall_rulesets_test.go +++ b/test/integration/firewall_rulesets_test.go @@ -25,7 +25,7 @@ func TestFirewallRuleSets_CRUD(t *testing.T) { Protocol: linodego.NetworkProtocol("TCP"), Ports: "80", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"0.0.0.0/0"}, + IPv4: []string{"0.0.0.0/0"}, }, }, }, @@ -71,7 +71,7 @@ func TestFirewallRuleSets_CRUD(t *testing.T) { Protocol: linodego.NetworkProtocol("TCP"), Ports: "443", Addresses: linodego.NetworkAddresses{ - IPv6: &[]string{"::/0"}, + IPv6: []string{"::/0"}, }, }, } @@ -79,7 +79,7 @@ func TestFirewallRuleSets_CRUD(t *testing.T) { updateOpts := linodego.RuleSetUpdateOptions{ Label: &updatedLabel, Description: &updatedDescription, - Rules: &updatedRules, + Rules: updatedRules, } updated, err := client.UpdateFirewallRuleSet(ctx, ruleSet.ID, updateOpts) diff --git a/test/integration/firewalls_test.go b/test/integration/firewalls_test.go index 1f18a500f..3b8b01333 100644 --- a/test/integration/firewalls_test.go +++ b/test/integration/firewalls_test.go @@ -53,8 +53,8 @@ func TestFirewall_Get(t *testing.T) { Action: "DROP", Protocol: linodego.ICMP, Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"0.0.0.0/0"}, - IPv6: &[]string{"::/0"}, + IPv4: []string{"0.0.0.0/0"}, + IPv6: []string{"::/0"}, }, }, }, @@ -95,7 +95,7 @@ func TestFirewall_Update(t *testing.T) { Action: "DROP", Protocol: linodego.ICMP, Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"0.0.0.0/0"}, + IPv4: []string{"0.0.0.0/0"}, }, }, }, @@ -117,7 +117,7 @@ func TestFirewall_Update(t *testing.T) { updateOpts := firewall.GetUpdateOptions() updateOpts.Status = linodego.FirewallDisabled updateOpts.Label = firewall.Label + "-updated" - updateOpts.Tags = &[]string{} + updateOpts.Tags = []string{} updated, err := client.UpdateFirewall(context.Background(), firewall.ID, updateOpts) if err != nil { @@ -128,8 +128,8 @@ func TestFirewall_Update(t *testing.T) { t.Errorf("expected no firewall entities after update, got %d", len(updated.Entities)) } - if !cmp.Equal(updated.Tags, *updateOpts.Tags) { - t.Errorf("expected tags to be updated: %s", cmp.Diff(updated.Tags, *updateOpts.Tags)) + if !cmp.Equal(updated.Tags, updateOpts.Tags) { + t.Errorf("expected tags to be updated: %s", cmp.Diff(updated.Tags, updateOpts.Tags)) } if updated.Status != updateOpts.Status { t.Errorf("expected status %s but got %s", updateOpts.Status, updated.Status) diff --git a/test/integration/fixtures/TestFirewallDevice_Delete.yaml b/test/integration/fixtures/TestFirewallDevice_Delete.yaml index 80debbdca..b74565fba 100644 --- a/test/integration/fixtures/TestFirewallDevice_Delete.yaml +++ b/test/integration/fixtures/TestFirewallDevice_Delete.yaml @@ -30,74 +30,75 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra - T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": - ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": - []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", "country": "us", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", "country": "cl", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": - ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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", + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", @@ -106,20 +107,20 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", @@ -128,9 +129,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra - T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", @@ -139,9 +140,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", @@ -150,25 +151,26 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", "Maintenance - Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", @@ -177,30 +179,37 @@ interactions: "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.18", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": @@ -210,8 +219,8 @@ interactions: "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", @@ -220,8 +229,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", @@ -230,8 +239,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", @@ -250,9 +259,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", @@ -261,9 +270,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", @@ -272,9 +281,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", @@ -283,9 +292,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", @@ -294,8 +303,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", @@ -304,9 +314,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", @@ -315,9 +325,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", @@ -326,9 +336,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", @@ -338,8 +348,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", @@ -348,9 +358,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", @@ -359,9 +369,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", @@ -369,9 +379,9 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", @@ -379,9 +389,9 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", @@ -390,8 +400,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", @@ -399,8 +409,8 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": - ["NodeBalancers"]}, "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", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", @@ -408,20 +418,20 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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,173.255.225.5,66.228.35.5", + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", @@ -430,8 +440,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", @@ -439,14 +449,14 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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": + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 46}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -469,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:20 GMT + - Tue, 05 May 2026 23:45:19 GMT Pragma: - no-cache Strict-Transport-Security: @@ -495,134 +505,7 @@ interactions: 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/account/availability?page=1 - method: GET - response: - body: '{"data": [{"region": "us-central", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "us-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-southeast", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-east", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "eu-west", "available": [], "unavailable": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "ap-south", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "eu-central", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "ap-northeast", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "ca-central", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-southeast", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-iad", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-ord", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "fr-par", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-sea", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "br-gru", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "nl-ams", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "se-sto", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "es-mad", "available": ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", - "Block Storage"]}, {"region": "in-maa", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "jp-osa", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "it-mil", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-mia", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "id-cgk", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-lax", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "nz-akl-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-den-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "de-ham-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "za-jnb-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "my-kul-1", "available": ["Linodes"], "unavailable": - ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": "co-bog-1", "available": - ["Linodes"], "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, - {"region": "mx-qro-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "us-hou-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "cl-scl-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "gb-lon", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "au-mel", "available": - ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", "Block Storage"]}, - {"region": "in-bom-2", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "de-fra-2", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "sg-sin-2", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "jp-tyo-3", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "de-ber-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "no-osl-1", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-iad-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-par-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "co-bog-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-mrs-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}], "page": 1, "pages": 1, "results": - 46}' - 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 Mar 2026 22:51:20 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - account:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1840" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-w9325gz70sqd","root_pass":"0J]6i895JaSqL]\\$d41J8b\u003e~(Tc!1?+yMRs{J!6NVxQm6tO8LbaJz78b)3@4\u003c,Lk","image":"linode/debian12","booted":false}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-o2em4jg116a5","root_pass":"*?YGoH+''C''4FQ8:yOr@g]YV`p7pJHg59koA6O!^:Oi8Qr0u4[431@c88e)]c20aA","image":"linode/debian12","booted":false}' form: {} headers: Accept: @@ -634,19 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 93152833, "label": "go-test-ins-w9325gz70sqd", "group": "", "status": + body: '{"id": 97185941, "label": "go-test-ins-o2em4jg116a5", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.236.44.156"], "ipv6": "1234::5678/128", + "type": "g6-nanode-1", "ipv4": ["172.236.33.27"], "ipv6": "1234::5678/128", "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, "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": "0f2b1b5738ceb6a8b0b9be46f010a4f34c762cce", - "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", - "lke_cluster_id": null, "capabilities": ["Block Storage Encryption", "SMTP Enabled", - "Maintenance Policy"], "interface_generation": "legacy_config", "maintenance_policy": - "linode/migrate", "locks": []}' + 80, "io": 10000, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -669,7 +552,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:23 GMT + - Tue, 05 May 2026 23:45:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -706,7 +589,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 3913131, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618630, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": @@ -738,7 +621,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:23 GMT + - Tue, 05 May 2026 23:45:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -762,7 +645,7 @@ interactions: code: 200 duration: "" - request: - body: '{"id":93152833,"type":"linode"}' + body: '{"id":97185941,"type":"linode"}' form: {} headers: Accept: @@ -771,12 +654,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913131/devices + url: https://api.linode.com/v4beta/networking/firewalls/9618630/devices method: POST response: - body: '{"id": 10483459, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "entity": {"id": 93152833, "type": "linode", "label": "go-test-ins-w9325gz70sqd", - "url": "/v4/linode/instances/93152833", "parent_entity": null}}' + body: '{"id": 11909960, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "entity": {"id": 97185941, "type": "linode", "label": "go-test-ins-o2em4jg116a5", + "url": "/v4/linode/instances/97185941", "parent_entity": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -801,7 +684,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:24 GMT + - Tue, 05 May 2026 23:45:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -834,7 +717,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913131/devices/10483459 + url: https://api.linode.com/v4beta/networking/firewalls/9618630/devices/11909960 method: DELETE response: body: '{}' @@ -862,7 +745,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:24 GMT + - Tue, 05 May 2026 23:45:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -895,7 +778,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913131/devices/10483459 + url: https://api.linode.com/v4beta/networking/firewalls/9618630/devices/11909960 method: GET response: body: '{"errors": [{"reason": "Not found"}]}' @@ -917,7 +800,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:24 GMT + - Tue, 05 May 2026 23:45:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -945,7 +828,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913131 + url: https://api.linode.com/v4beta/networking/firewalls/9618630 method: DELETE response: body: '{}' @@ -973,7 +856,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:25 GMT + - Tue, 05 May 2026 23:45:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1006,7 +889,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/93152833 + url: https://api.linode.com/v4beta/linode/instances/97185941 method: DELETE response: body: '{}' @@ -1034,7 +917,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:51:25 GMT + - Tue, 05 May 2026 23:45:23 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewallDevice_Get.yaml b/test/integration/fixtures/TestFirewallDevice_Get.yaml index f697cc3d1..48adf7f03 100644 --- a/test/integration/fixtures/TestFirewallDevice_Get.yaml +++ b/test/integration/fixtures/TestFirewallDevice_Get.yaml @@ -30,74 +30,75 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra - T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": - ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": - []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", "country": "us", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", "country": "cl", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": - ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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", + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", @@ -106,20 +107,20 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", @@ -128,9 +129,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra - T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", @@ -139,9 +140,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", @@ -150,25 +151,26 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", "Maintenance - Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", @@ -177,30 +179,37 @@ interactions: "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.18", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": @@ -210,8 +219,8 @@ interactions: "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", @@ -220,8 +229,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", @@ -230,8 +239,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", @@ -250,9 +259,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", @@ -261,9 +270,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", @@ -272,9 +281,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", @@ -283,9 +292,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", @@ -294,8 +303,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", @@ -304,9 +314,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", @@ -315,9 +325,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", @@ -326,9 +336,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", @@ -338,8 +348,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", @@ -348,9 +358,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", @@ -359,9 +369,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", @@ -369,9 +379,9 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", @@ -379,9 +389,9 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", @@ -390,8 +400,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", @@ -399,8 +409,8 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": - ["NodeBalancers"]}, "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", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", @@ -408,20 +418,20 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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,173.255.225.5,66.228.35.5", + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", @@ -430,8 +440,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", @@ -439,14 +449,14 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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": + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 46}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -469,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:33 GMT + - Tue, 05 May 2026 23:45:15 GMT Pragma: - no-cache Strict-Transport-Security: @@ -495,134 +505,7 @@ interactions: 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/account/availability?page=1 - method: GET - response: - body: '{"data": [{"region": "us-central", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "us-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-southeast", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-east", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "eu-west", "available": [], "unavailable": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "ap-south", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "eu-central", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "ap-northeast", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "ca-central", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-southeast", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-iad", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-ord", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "fr-par", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-sea", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "br-gru", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "nl-ams", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "se-sto", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "es-mad", "available": ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", - "Block Storage"]}, {"region": "in-maa", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "jp-osa", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "it-mil", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-mia", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "id-cgk", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-lax", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "nz-akl-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-den-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "de-ham-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "za-jnb-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "my-kul-1", "available": ["Linodes"], "unavailable": - ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": "co-bog-1", "available": - ["Linodes"], "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, - {"region": "mx-qro-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "us-hou-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "cl-scl-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "gb-lon", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "au-mel", "available": - ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", "Block Storage"]}, - {"region": "in-bom-2", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "de-fra-2", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "sg-sin-2", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "jp-tyo-3", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "de-ber-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "no-osl-1", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-iad-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-par-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "co-bog-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-mrs-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}], "page": 1, "pages": 1, "results": - 46}' - 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 Mar 2026 22:50:33 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - account:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1840" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-q27m167oya7q","root_pass":"1;N2vve+~7TsyXbvPJ60+J45mmmM09d,V5U.[j;(Qf+AeZNn7*7K5+D6M:8f|@`7","image":"linode/debian12","booted":false}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-507phxdcj126","root_pass":"brgTP0601\u0026(X8?Ty687zxJD:)$Up|CwMf1''R8sa\u0026b}5`9UXg\u0026gWV8[|G\u003e9B''41ki","image":"linode/debian12","booted":false}' form: {} headers: Accept: @@ -634,19 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 93152753, "label": "go-test-ins-q27m167oya7q", "group": "", "status": + body: '{"id": 97185937, "label": "go-test-ins-507phxdcj126", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.236.44.156"], "ipv6": "1234::5678/128", + "type": "g6-nanode-1", "ipv4": ["172.236.33.27"], "ipv6": "1234::5678/128", "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, "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": "e6fb7e51a1d7b36635dda16eb686150d00ac7289", - "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", - "lke_cluster_id": null, "capabilities": ["Block Storage Encryption", "SMTP Enabled", - "Maintenance Policy"], "interface_generation": "legacy_config", "maintenance_policy": - "linode/migrate", "locks": []}' + 80, "io": 10000, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "7c21ff8b1596655206e1b4c6bc4f1c8ebd03c68c", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -669,7 +552,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:35 GMT + - Tue, 05 May 2026 23:45:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -706,7 +589,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 3913123, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618589, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": @@ -738,7 +621,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:35 GMT + - Tue, 05 May 2026 23:45:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -762,7 +645,7 @@ interactions: code: 200 duration: "" - request: - body: '{"id":93152753,"type":"linode"}' + body: '{"id":97185937,"type":"linode"}' form: {} headers: Accept: @@ -771,12 +654,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913123/devices + url: https://api.linode.com/v4beta/networking/firewalls/9618589/devices method: POST response: - body: '{"id": 10483434, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "entity": {"id": 93152753, "type": "linode", "label": "go-test-ins-q27m167oya7q", - "url": "/v4/linode/instances/93152753", "parent_entity": null}}' + body: '{"id": 11909959, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "entity": {"id": 97185937, "type": "linode", "label": "go-test-ins-507phxdcj126", + "url": "/v4/linode/instances/97185937", "parent_entity": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -801,7 +684,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:35 GMT + - Tue, 05 May 2026 23:45:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -834,12 +717,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913123/devices/10483434 + url: https://api.linode.com/v4beta/networking/firewalls/9618589/devices/11909959 method: GET response: - body: '{"id": 10483434, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "entity": {"id": 93152753, "type": "linode", "label": "go-test-ins-q27m167oya7q", - "url": "/v4/linode/instances/93152753", "parent_entity": null}}' + body: '{"id": 11909959, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "entity": {"id": 97185937, "type": "linode", "label": "go-test-ins-507phxdcj126", + "url": "/v4/linode/instances/97185937", "parent_entity": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -864,7 +747,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:36 GMT + - Tue, 05 May 2026 23:45:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -898,18 +781,18 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913123 + url: https://api.linode.com/v4beta/networking/firewalls/9618589 method: GET response: - body: '{"id": 3913123, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618589, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": "ACCEPT", "outbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "7bcc0f03"}, "tags": - ["testing"], "entities": [{"id": 93152753, "type": "linode", "label": "go-test-ins-q27m167oya7q", - "url": "/v4/linode/instances/93152753", "parent_entity": null}]}' + ["testing"], "entities": [{"id": 97185937, "type": "linode", "label": "go-test-ins-507phxdcj126", + "url": "/v4/linode/instances/97185937", "parent_entity": null}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -934,7 +817,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:36 GMT + - Tue, 05 May 2026 23:45:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -968,7 +851,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913123 + url: https://api.linode.com/v4beta/networking/firewalls/9618589 method: DELETE response: body: '{}' @@ -996,7 +879,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:36 GMT + - Tue, 05 May 2026 23:45:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1029,7 +912,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/93152753 + url: https://api.linode.com/v4beta/linode/instances/97185937 method: DELETE response: body: '{}' @@ -1057,7 +940,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:50:37 GMT + - Tue, 05 May 2026 23:45:19 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewallDevices_List.yaml b/test/integration/fixtures/TestFirewallDevices_List.yaml index 5ce84fbf9..1e827c47d 100644 --- a/test/integration/fixtures/TestFirewallDevices_List.yaml +++ b/test/integration/fixtures/TestFirewallDevices_List.yaml @@ -30,74 +30,75 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra - T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": - ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": - []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", "country": "us", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", "country": "cl", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": - ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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", + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", @@ -106,20 +107,20 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", @@ -128,9 +129,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra - T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", @@ -139,9 +140,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", @@ -150,25 +151,26 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", "Maintenance - Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium - Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", @@ -177,30 +179,37 @@ interactions: "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.18", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": @@ -210,8 +219,8 @@ interactions: "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", @@ -220,8 +229,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", @@ -230,8 +239,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", @@ -250,9 +259,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", @@ -261,9 +270,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", @@ -272,9 +281,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", @@ -283,9 +292,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", @@ -294,8 +303,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", @@ -304,9 +314,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", @@ -315,9 +325,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", @@ -326,9 +336,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", @@ -338,8 +348,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", @@ -348,9 +358,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", @@ -359,9 +369,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", @@ -369,9 +379,9 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", @@ -379,9 +389,9 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", @@ -390,8 +400,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", @@ -399,8 +409,8 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": - ["NodeBalancers"]}, "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", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", @@ -408,20 +418,20 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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,173.255.225.5,66.228.35.5", + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", @@ -430,8 +440,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", @@ -439,14 +449,14 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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": + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 46}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -469,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:49:45 GMT + - Tue, 05 May 2026 23:45:12 GMT Pragma: - no-cache Strict-Transport-Security: @@ -495,134 +505,7 @@ interactions: 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/account/availability?page=1 - method: GET - response: - body: '{"data": [{"region": "us-central", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "us-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-southeast", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-east", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "eu-west", "available": [], "unavailable": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "ap-south", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "eu-central", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "ap-northeast", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "ca-central", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-southeast", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-iad", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-ord", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "fr-par", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-sea", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "br-gru", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "nl-ams", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "se-sto", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "es-mad", "available": ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", - "Block Storage"]}, {"region": "in-maa", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "jp-osa", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "it-mil", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-mia", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "id-cgk", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-lax", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "nz-akl-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-den-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "de-ham-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "za-jnb-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "my-kul-1", "available": ["Linodes"], "unavailable": - ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": "co-bog-1", "available": - ["Linodes"], "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, - {"region": "mx-qro-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "us-hou-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "cl-scl-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "gb-lon", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "au-mel", "available": - ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", "Block Storage"]}, - {"region": "in-bom-2", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "de-fra-2", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "sg-sin-2", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "jp-tyo-3", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "de-ber-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "no-osl-1", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-iad-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-par-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "co-bog-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-mrs-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}], "page": 1, "pages": 1, "results": - 46}' - 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 Mar 2026 22:49:45 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - account:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1840" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-lc0pul6h9485","root_pass":"c*y5+ugacvYby!|J\\mJ,5u\u00269^!#\u003e2p3m66VN!GAD*KYX)c58z1B09K6OS40s)E7!","image":"linode/debian12","booted":false}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-ald015i102rx","root_pass":"P~0zuUbC8G22u1b{}SVlxa\u003e}7+mTmLZ}715y67W4F1`:a2r\u0026BU\u003cP''v9/OSq\u003e$t7~","image":"linode/debian12","booted":false}' form: {} headers: Accept: @@ -634,19 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 93152714, "label": "go-test-ins-lc0pul6h9485", "group": "", "status": + body: '{"id": 97185936, "label": "go-test-ins-ald015i102rx", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.236.44.156"], "ipv6": "1234::5678/128", + "type": "g6-nanode-1", "ipv4": ["172.236.33.27"], "ipv6": "1234::5678/128", "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, "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": "e6fb7e51a1d7b36635dda16eb686150d00ac7289", - "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", - "lke_cluster_id": null, "capabilities": ["Block Storage Encryption", "SMTP Enabled", - "Maintenance Policy"], "interface_generation": "legacy_config", "maintenance_policy": - "linode/migrate", "locks": []}' + 80, "io": 10000, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "6c9b57be39471d7888b736f623fe5527fd93c553", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -669,7 +552,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:49:47 GMT + - Tue, 05 May 2026 23:45:13 GMT Pragma: - no-cache Strict-Transport-Security: @@ -694,7 +577,7 @@ interactions: code: 200 duration: "" - request: - body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"],"devices":{"linodes":[93152714]}}' + body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"],"devices":{"linodes":[97185936]}}' form: {} headers: Accept: @@ -706,15 +589,15 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 3913113, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618549, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": "ACCEPT", "outbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "7bcc0f03"}, "tags": - ["testing"], "entities": [{"id": 93152714, "type": "linode", "label": "go-test-ins-lc0pul6h9485", - "url": "/v4/linode/instances/93152714", "parent_entity": null}]}' + ["testing"], "entities": [{"id": 97185936, "type": "linode", "label": "go-test-ins-ald015i102rx", + "url": "/v4/linode/instances/97185936", "parent_entity": null}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -739,7 +622,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:49:48 GMT + - Tue, 05 May 2026 23:45:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -772,12 +655,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913113/devices?page=1 + url: https://api.linode.com/v4beta/networking/firewalls/9618549/devices?page=1 method: GET response: - body: '{"data": [{"id": 10483419, "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "entity": {"id": 93152714, "type": "linode", "label": - "go-test-ins-lc0pul6h9485", "url": "/v4/linode/instances/93152714", "parent_entity": + body: '{"data": [{"id": 11909957, "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "entity": {"id": 97185936, "type": "linode", "label": + "go-test-ins-ald015i102rx", "url": "/v4/linode/instances/97185936", "parent_entity": null}}], "page": 1, "pages": 1, "results": 1}' headers: Access-Control-Allow-Credentials: @@ -803,7 +686,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:49:48 GMT + - Tue, 05 May 2026 23:45:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -837,7 +720,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3913113 + url: https://api.linode.com/v4beta/networking/firewalls/9618549 method: DELETE response: body: '{}' @@ -865,7 +748,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:49:48 GMT + - Tue, 05 May 2026 23:45:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -898,7 +781,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/93152714 + url: https://api.linode.com/v4beta/linode/instances/97185936 method: DELETE response: body: '{}' @@ -926,7 +809,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 04 Mar 2026 22:49:48 GMT + - Tue, 05 May 2026 23:45:15 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml b/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml index 2ed5bab0c..dfef91138 100644 --- a/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml +++ b/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml @@ -14,10 +14,11 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/rulesets method: POST response: - body: '{"id": 78, "version": 1, "label": "rs-51452000", "description": "Allow + body: '{"id": 66319, "version": 1, "label": "rs-51452000", "description": "Allow inbound HTTP", "type": "inbound", "is_service_defined": false, "rules": [{"action": "ACCEPT", "label": "allow-http", "ports": "80", "protocol": "TCP", "addresses": - {"ipv4": ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}' + {"ipv4": ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "deleted": null}' headers: Access-Control-Allow-Credentials: - "true" @@ -36,13 +37,13 @@ interactions: Connection: - keep-alive Content-Length: - - "325" + - "349" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 13 Oct 2025 21:57:58 GMT + - Tue, 05 May 2026 23:45:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -75,13 +76,14 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/rulesets/78 + url: https://api.linode.com/v4beta/networking/firewalls/rulesets/66319 method: GET response: - body: '{"id": 78, "version": 1, "label": "rs-51452000", "description": "Allow + body: '{"id": 66319, "version": 1, "label": "rs-51452000", "description": "Allow inbound HTTP", "type": "inbound", "is_service_defined": false, "rules": [{"label": "allow-http", "ports": "80", "action": "ACCEPT", "protocol": "TCP", "addresses": - {"ipv4": ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}' + {"ipv4": ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "deleted": null}' headers: Access-Control-Allow-Credentials: - "true" @@ -100,13 +102,13 @@ interactions: Connection: - keep-alive Content-Length: - - "325" + - "349" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 13 Oct 2025 21:57:58 GMT + - Tue, 05 May 2026 23:45:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -140,14 +142,14 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/rulesets/78 + url: https://api.linode.com/v4beta/networking/firewalls/rulesets/66319 method: PUT response: - body: '{"id": 78, "version": 2, "label": "rs-51452000-updated", "description": + body: '{"id": 66319, "version": 2, "label": "rs-51452000-updated", "description": "Updated description", "type": "inbound", "is_service_defined": false, "rules": - [{"action": "ACCEPT", "label": "allow-https", "ports": "443", "protocol": "TCP", + [{"label": "allow-https", "ports": "443", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"]}}], "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05"}' + "2018-01-02T03:04:05", "deleted": null}' headers: Access-Control-Allow-Credentials: - "true" @@ -166,13 +168,13 @@ interactions: Connection: - keep-alive Content-Length: - - "331" + - "355" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 13 Oct 2025 21:57:58 GMT + - Tue, 05 May 2026 23:45:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -208,24 +210,16 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/rulesets?page=1 method: GET response: - body: '{"data": [{"id": 74, "version": 1, "label": "testRuleSet", "description": - "test", "type": "inbound", "is_service_defined": false, "rules": [{"label": "test", - "ports": "22-24", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv4": - ["192.0.2.0/24"]}, "description": "test"}], "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05"}, {"id": 75, "version": 1, "label": "testRuleSet2", - "description": "test2", "type": "inbound", "is_service_defined": false, "rules": - [{"label": "test", "ports": "22-24", "action": "ACCEPT", "protocol": "TCP", - "addresses": {"ipv4": ["192.0.2.0/24"]}, "description": "test"}], "created": - "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}, {"id": 76, "version": - 1, "label": "ruleset-1760391571119054000", "description": "Allow inbound HTTP", - "type": "inbound", "is_service_defined": false, "rules": [{"label": "allow-http", - "ports": "80", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv4": - ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}, - {"id": 78, "version": 2, "label": "rs-51452000-updated", "description": "Updated - description", "type": "inbound", "is_service_defined": false, "rules": [{"label": - "allow-https", "ports": "443", "action": "ACCEPT", "protocol": "TCP", "addresses": - {"ipv6": ["1234::5678/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}], - "page": 1, "pages": 1, "results": 4}' + body: '{"data": [{"id": 66318, "version": 2, "label": "rs-51452000-updated", "description": + "Updated description", "type": "inbound", "is_service_defined": false, "rules": + [{"label": "allow-https", "ports": "443", "action": "ACCEPT", "protocol": "TCP", + "addresses": {"ipv6": ["1234::5678/0"]}}], "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "deleted": "2018-01-02T03:04:05"}, {"id": 66319, "version": + 2, "label": "rs-51452000-updated", "description": "Updated description", "type": + "inbound", "is_service_defined": false, "rules": [{"label": "allow-https", "ports": + "443", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"]}}], + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "deleted": + null}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -243,12 +237,14 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive + Content-Length: + - "778" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 13 Oct 2025 21:57:58 GMT + - Tue, 05 May 2026 23:45:10 GMT Pragma: - no-cache Strict-Transport-Security: @@ -256,7 +252,6 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter - - Accept-Encoding X-Accepted-Oauth-Scopes: - firewall:read_only X-Content-Type-Options: @@ -283,7 +278,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/rulesets/78 + url: https://api.linode.com/v4beta/networking/firewalls/rulesets/66319 method: DELETE response: body: '{}' @@ -311,7 +306,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 13 Oct 2025 21:57:58 GMT + - Tue, 05 May 2026 23:45:11 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewallRules_Get.yaml b/test/integration/fixtures/TestFirewallRules_Get.yaml index f8c9dacbd..3ffc7ca10 100644 --- a/test/integration/fixtures/TestFirewallRules_Get.yaml +++ b/test/integration/fixtures/TestFirewallRules_Get.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT","version":0,"fingerprint":""},"tags":["testing"]}' + body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"]}' form: {} headers: Accept: @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 3885660, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618466, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": @@ -46,7 +46,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 07:07:58 GMT + - Tue, 05 May 2026 23:45:07 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/firewalls/3885660/rules + url: https://api.linode.com/v4beta/networking/firewalls/9618466/rules method: GET response: body: '{"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": @@ -111,7 +111,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 07:07:58 GMT + - Tue, 05 May 2026 23:45:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -145,7 +145,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3885660 + url: https://api.linode.com/v4beta/networking/firewalls/9618466 method: DELETE response: body: '{}' @@ -173,7 +173,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 07:07:59 GMT + - Tue, 05 May 2026 23:45:08 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewallRules_Update.yaml b/test/integration/fixtures/TestFirewallRules_Update.yaml index 49fd6b381..a16157a3e 100644 --- a/test/integration/fixtures/TestFirewallRules_Update.yaml +++ b/test/integration/fixtures/TestFirewallRules_Update.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"],"devices":{}}' + body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"]}' form: {} headers: Accept: @@ -14,12 +14,12 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 692860, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618482, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": - [{"action": "ACCEPT", "label": "go-fwrule-test", "ports": "22", "protocol": - "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}}], "inbound_policy": - "ACCEPT", "outbound": [{"action": "ACCEPT", "label": "go-fwrule-test", "ports": - "22", "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}}], + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, + "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": + "ACCEPT", "outbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": + ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "7bcc0f03"}, "tags": ["testing"], "entities": []}' headers: @@ -40,13 +40,13 @@ interactions: Connection: - keep-alive Content-Length: - - "583" + - "584" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:42 GMT + - Tue, 05 May 2026 23:45:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -61,12 +61,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -82,11 +79,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/692860/rules + url: https://api.linode.com/v4beta/networking/firewalls/9618482/rules method: PUT response: - body: '{"inbound": [{"action": "DROP", "label": "go-fwrule-test_r", "ports": "22", - "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}}], + body: '{"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": + ["0.0.0.0/0"]}, "action": "DROP", "label": "go-fwrule-test_r", "ports": "22"}], "inbound_policy": "ACCEPT", "outbound": null, "outbound_policy": "ACCEPT", "version": 2, "fingerprint": "cddbc8f5"}' headers: @@ -113,7 +110,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:42 GMT + - Tue, 05 May 2026 23:45:08 GMT Pragma: - no-cache Strict-Transport-Security: @@ -128,12 +125,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -149,11 +143,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/692860/rules + url: https://api.linode.com/v4beta/networking/firewalls/9618482/rules method: GET response: - body: '{"inbound": [{"action": "DROP", "label": "go-fwrule-test_r", "ports": "22", - "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}}], + body: '{"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": + ["0.0.0.0/0"]}, "action": "DROP", "label": "go-fwrule-test_r", "ports": "22"}], "inbound_policy": "ACCEPT", "outbound": null, "outbound_policy": "ACCEPT", "version": 2, "fingerprint": "cddbc8f5"}' headers: @@ -180,7 +174,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:42 GMT + - Tue, 05 May 2026 23:45:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -196,12 +190,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -217,7 +208,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/692860 + url: https://api.linode.com/v4beta/networking/firewalls/9618482 method: DELETE response: body: '{}' @@ -245,7 +236,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:42 GMT + - Tue, 05 May 2026 23:45:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -260,12 +251,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestFirewallSettings_Get.yaml b/test/integration/fixtures/TestFirewallSettings_Get.yaml index 691d46647..f230c90d9 100644 --- a/test/integration/fixtures/TestFirewallSettings_Get.yaml +++ b/test/integration/fixtures/TestFirewallSettings_Get.yaml @@ -14,8 +14,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: GET response: - body: '{"default_firewall_ids": {"linode": 2630203, "nodebalancer": 1629606, "public_interface": - 1629606, "vpc_interface": 1629606}}' + body: '{"default_firewall_ids": {"linode": null, "nodebalancer": null, "public_interface": + null, "vpc_interface": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -34,13 +34,13 @@ interactions: Connection: - keep-alive Content-Length: - - "125" + - "113" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:18 GMT + - Tue, 05 May 2026 23:45:26 GMT Pragma: - no-cache Strict-Transport-Security: @@ -58,7 +58,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestFirewallSettings_UpdateAllFields.yaml b/test/integration/fixtures/TestFirewallSettings_UpdateAllFields.yaml index 9899636ed..af7364f03 100644 --- a/test/integration/fixtures/TestFirewallSettings_UpdateAllFields.yaml +++ b/test/integration/fixtures/TestFirewallSettings_UpdateAllFields.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"label":"fw-allfields-1750453218573434000","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"],"devices":{}}' + body: '{"label":"fw-allfields-1778024726382972000","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"]}' form: {} headers: Accept: @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 2898496, "label": "fw-allfields-1750453218573434000", "created": + body: '{"id": 9618684, "label": "fw-allfields-1778024726382972000", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], @@ -46,7 +46,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:18 GMT + - Tue, 05 May 2026 23:45:26 GMT Pragma: - no-cache Strict-Transport-Security: @@ -63,7 +63,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -82,8 +82,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: GET response: - body: '{"default_firewall_ids": {"linode": 2630203, "nodebalancer": 1629606, "public_interface": - 1629606, "vpc_interface": 1629606}}' + body: '{"default_firewall_ids": {"linode": null, "nodebalancer": null, "public_interface": + null, "vpc_interface": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -102,13 +102,13 @@ interactions: Connection: - keep-alive Content-Length: - - "125" + - "113" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:18 GMT + - Tue, 05 May 2026 23:45:26 GMT Pragma: - no-cache Strict-Transport-Security: @@ -126,14 +126,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"default_firewall_ids":{"linode":2898496,"nodebalancer":2898496,"public_interface":2898496,"vpc_interface":2898496}}' + body: '{"default_firewall_ids":{"linode":9618684,"nodebalancer":9618684,"public_interface":9618684,"vpc_interface":9618684}}' form: {} headers: Accept: @@ -145,8 +145,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: PUT response: - body: '{"default_firewall_ids": {"linode": 2898496, "nodebalancer": 2898496, "public_interface": - 2898496, "vpc_interface": 2898496}}' + body: '{"default_firewall_ids": {"linode": 9618684, "nodebalancer": 9618684, "public_interface": + 9618684, "vpc_interface": 9618684}}' headers: Access-Control-Allow-Credentials: - "true" @@ -171,7 +171,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:27 GMT Pragma: - no-cache Strict-Transport-Security: @@ -188,14 +188,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"default_firewall_ids":{"linode":2630203,"nodebalancer":1629606,"public_interface":1629606,"vpc_interface":1629606}}' + body: '{"default_firewall_ids":{"linode":null,"nodebalancer":null,"public_interface":null,"vpc_interface":null}}' form: {} headers: Accept: @@ -207,8 +207,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: PUT response: - body: '{"default_firewall_ids": {"linode": 2630203, "nodebalancer": 1629606, "public_interface": - 1629606, "vpc_interface": 1629606}}' + body: '{"default_firewall_ids": {"linode": null, "nodebalancer": null, "public_interface": + null, "vpc_interface": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -227,13 +227,13 @@ interactions: Connection: - keep-alive Content-Length: - - "125" + - "113" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:27 GMT Pragma: - no-cache Strict-Transport-Security: @@ -250,7 +250,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -266,7 +266,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/2898496 + url: https://api.linode.com/v4beta/networking/firewalls/9618684 method: DELETE response: body: '{}' @@ -294,7 +294,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:27 GMT Pragma: - no-cache Strict-Transport-Security: @@ -311,7 +311,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestFirewallSettings_UpdatePartial.yaml b/test/integration/fixtures/TestFirewallSettings_UpdatePartial.yaml index 04c46d9b9..5450847b2 100644 --- a/test/integration/fixtures/TestFirewallSettings_UpdatePartial.yaml +++ b/test/integration/fixtures/TestFirewallSettings_UpdatePartial.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"label":"fw-partial-1750453219295619000","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"],"devices":{}}' + body: '{"label":"fw-partial-1778024727842672000","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"]}' form: {} headers: Accept: @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 2898497, "label": "fw-partial-1750453219295619000", "created": "2018-01-02T03:04:05", + body: '{"id": 9618701, "label": "fw-partial-1778024727842672000", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": @@ -46,7 +46,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:28 GMT Pragma: - no-cache Strict-Transport-Security: @@ -63,7 +63,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -82,8 +82,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: GET response: - body: '{"default_firewall_ids": {"linode": 2630203, "nodebalancer": 1629606, "public_interface": - 1629606, "vpc_interface": 1629606}}' + body: '{"default_firewall_ids": {"linode": null, "nodebalancer": null, "public_interface": + null, "vpc_interface": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -102,13 +102,13 @@ interactions: Connection: - keep-alive Content-Length: - - "125" + - "113" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:28 GMT Pragma: - no-cache Strict-Transport-Security: @@ -126,14 +126,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"default_firewall_ids":{"linode":2898497}}' + body: '{"default_firewall_ids":{"linode":9618701}}' form: {} headers: Accept: @@ -145,8 +145,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: PUT response: - body: '{"default_firewall_ids": {"linode": 2898497, "nodebalancer": 1629606, "public_interface": - 1629606, "vpc_interface": 1629606}}' + body: '{"default_firewall_ids": {"linode": 9618701, "nodebalancer": null, "public_interface": + null, "vpc_interface": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -165,13 +165,13 @@ interactions: Connection: - keep-alive Content-Length: - - "125" + - "116" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:28 GMT Pragma: - no-cache Strict-Transport-Security: @@ -188,14 +188,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"default_firewall_ids":{"linode":2630203,"nodebalancer":1629606,"public_interface":1629606,"vpc_interface":1629606}}' + body: '{"default_firewall_ids":{"linode":null,"nodebalancer":null,"public_interface":null,"vpc_interface":null}}' form: {} headers: Accept: @@ -207,8 +207,8 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/settings method: PUT response: - body: '{"default_firewall_ids": {"linode": 2630203, "nodebalancer": 1629606, "public_interface": - 1629606, "vpc_interface": 1629606}}' + body: '{"default_firewall_ids": {"linode": null, "nodebalancer": null, "public_interface": + null, "vpc_interface": null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -227,13 +227,13 @@ interactions: Connection: - keep-alive Content-Length: - - "125" + - "113" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:28 GMT Pragma: - no-cache Strict-Transport-Security: @@ -250,7 +250,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -266,7 +266,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/2898497 + url: https://api.linode.com/v4beta/networking/firewalls/9618701 method: DELETE response: body: '{}' @@ -294,7 +294,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 20 Jun 2025 21:00:19 GMT + - Tue, 05 May 2026 23:45:28 GMT Pragma: - no-cache Strict-Transport-Security: @@ -311,7 +311,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestFirewallTemplate_Get.yaml b/test/integration/fixtures/TestFirewallTemplate_Get.yaml index a3eb6eba3..915d533c2 100644 --- a/test/integration/fixtures/TestFirewallTemplate_Get.yaml +++ b/test/integration/fixtures/TestFirewallTemplate_Get.yaml @@ -14,12 +14,12 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/templates/public method: GET response: - body: '{"slug": "public", "rules": {"inbound": [{"action": "ACCEPT", "addresses": - {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, "ports": "22", "protocol": "TCP", - "label": "accept-inbound-ssh", "description": "Accept inbound SSH"}, {"action": - "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, "protocol": - "ICMP", "label": "accept-inbound-icmp", "description": "Accept inbound ICMP"}], - "inbound_policy": "DROP", "outbound": [], "outbound_policy": "ACCEPT"}}' + body: '{"slug": "public", "rules": {"inbound": [{"protocol": "TCP", "addresses": + {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "accept-inbound-ssh", + "ports": "22", "description": "Accept inbound SSH"}, {"protocol": "ICMP", "addresses": + {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "accept-inbound-icmp", + "description": "Accept inbound ICMP"}], "inbound_policy": "DROP", "outbound": + [], "outbound_policy": "ACCEPT"}}' headers: Access-Control-Allow-Credentials: - "true" @@ -44,7 +44,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 21 Apr 2025 07:03:52 GMT + - Tue, 05 May 2026 23:45:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -62,7 +62,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestFirewallTemplates_List.yaml b/test/integration/fixtures/TestFirewallTemplates_List.yaml index bf2f1666f..1137c0b57 100644 --- a/test/integration/fixtures/TestFirewallTemplates_List.yaml +++ b/test/integration/fixtures/TestFirewallTemplates_List.yaml @@ -14,37 +14,36 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/templates?page=1 method: GET response: - body: '{"data": [{"slug": "akamai-non-prod", "rules": {"inbound": [{"action": - "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, "protocol": - "ICMP", "label": "accept-inbound-icmp", "description": "Accept inbound ICMP"}, - {"action": "ACCEPT", "addresses": {"ipv4": ["172.236.119.4/30", "172.234.160.4/30", - "172.236.94.4/30"], "ipv6": ["1234::5678/128", "1234::5678/128", + body: '{"data": [{"slug": "akamai-non-prod", "rules": {"inbound": [{"protocol": + "ICMP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", + "label": "accept-inbound-icmp", "description": "Accept inbound ICMP"}, {"protocol": + "TCP", "addresses": {"ipv6": ["1234::5678/128", "1234::5678/128", "1234::5678/128", "1234::5678/128", "1234::5678/128", "1234::5678/128", "1234::5678/128", "1234::5678/128", - "1234::5678/128"]}, "ports": "22,443", "protocol": "TCP", - "label": "accept-inbound-tcp-ssh-proxies", "description": "Accept inbound TCP - from SSH proxies"}, {"action": "ACCEPT", "addresses": {"ipv4": ["139.144.212.168/31", - "172.232.23.164/31"]}, "ports": "22,443", "protocol": "TCP", "label": "accept-inbound-tcp-eaa-proxies", - "description": "Accept inbound TCP from EAA proxies"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT"}}, {"slug": "vpc", "rules": {"inbound": - [{"action": "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, - "ports": "22", "protocol": "TCP", "label": "accept-inbound-ssh", "description": - "Accept inbound SSH"}, {"action": "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], - "ipv6": ["1234::5678/0"]}, "protocol": "ICMP", "label": "accept-inbound-icmp", "description": - "Accept inbound ICMP"}, {"action": "ACCEPT", "addresses": {"ipv4": ["10.0.0.0/8", - "192.168.0.0/17", "172.16.0.0/12"]}, "ports": "1-65535", "protocol": "TCP", - "label": "accept-inbound-rfc1918", "description": "Accept inbound RFC-1918"}, - {"action": "ACCEPT", "addresses": {"ipv4": ["10.0.0.0/8", "192.168.0.0/17", - "172.16.0.0/12"]}, "description": "Accept inbound RFC-1918", "label": "accept-inbound-rfc1918", - "ports": "1-65535", "protocol": "UDP"}], "inbound_policy": "DROP", "outbound": - [], "outbound_policy": "ACCEPT"}}, {"slug": "public", "rules": {"inbound": [{"action": - "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, "ports": "22", - "protocol": "TCP", "label": "accept-inbound-ssh", "description": "Accept inbound - SSH"}, {"action": "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, - "protocol": "ICMP", "label": "accept-inbound-icmp", "description": "Accept inbound - ICMP"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": "ACCEPT"}}], - "page": 1, "pages": 1, "results": 3}' + "1234::5678/128"], "ipv4": ["172.236.119.4/30", "172.234.160.4/30", + "172.236.94.4/30"]}, "action": "ACCEPT", "label": "accept-inbound-tcp-ssh-proxies", + "ports": "22,443", "description": "Accept inbound TCP from SSH proxies"}, {"protocol": + "TCP", "addresses": {"ipv4": ["139.144.212.168/31", "172.232.23.164/31"]}, "action": + "ACCEPT", "label": "accept-inbound-tcp-eaa-proxies", "ports": "22,443", "description": + "Accept inbound TCP from EAA proxies"}], "inbound_policy": "DROP", "outbound": + [], "outbound_policy": "ACCEPT"}}, {"slug": "vpc", "rules": {"inbound": [{"protocol": + "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", + "label": "accept-inbound-ssh", "ports": "22", "description": "Accept inbound + SSH"}, {"protocol": "ICMP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, + "action": "ACCEPT", "label": "accept-inbound-icmp", "description": "Accept inbound + ICMP"}, {"protocol": "TCP", "addresses": {"ipv4": ["10.0.0.0/8", "192.168.0.0/17", + "172.16.0.0/12"]}, "action": "ACCEPT", "label": "accept-inbound-rfc1918", "ports": + "1-65535", "description": "Accept inbound RFC-1918"}, {"protocol": "UDP", "addresses": + {"ipv4": ["10.0.0.0/8", "192.168.0.0/17", "172.16.0.0/12"]}, "action": "ACCEPT", + "label": "accept-inbound-rfc1918", "ports": "1-65535", "description": "Accept + inbound RFC-1918"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT"}}, {"slug": "public", "rules": {"inbound": [{"protocol": "TCP", "addresses": + {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "accept-inbound-ssh", + "ports": "22", "description": "Accept inbound SSH"}, {"protocol": "ICMP", "addresses": + {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "accept-inbound-icmp", + "description": "Accept inbound ICMP"}], "inbound_policy": "DROP", "outbound": + [], "outbound_policy": "ACCEPT"}}], "page": 1, "pages": 1, "results": 3}' headers: Access-Control-Allow-Credentials: - "true" @@ -67,7 +66,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 21 Apr 2025 07:03:52 GMT + - Tue, 05 May 2026 23:45:07 GMT Pragma: - no-cache Strict-Transport-Security: @@ -86,7 +85,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestFirewall_Get.yaml b/test/integration/fixtures/TestFirewall_Get.yaml index 74b990201..fe797ac97 100644 --- a/test/integration/fixtures/TestFirewall_Get.yaml +++ b/test/integration/fixtures/TestFirewall_Get.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 3885331, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618661, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "ICMP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "DROP", "label": "linodego-fwrule-test"}], "inbound_policy": "ACCEPT", @@ -44,7 +44,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 04:56:47 GMT + - Tue, 05 May 2026 23:45:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -77,10 +77,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3885331 + url: https://api.linode.com/v4beta/networking/firewalls/9618661 method: GET response: - body: '{"id": 3885331, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618661, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "ICMP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "DROP", "label": "linodego-fwrule-test"}], "inbound_policy": "ACCEPT", @@ -110,7 +110,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 04:56:47 GMT + - Tue, 05 May 2026 23:45:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -144,7 +144,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3885331 + url: https://api.linode.com/v4beta/networking/firewalls/9618661 method: DELETE response: body: '{}' @@ -172,7 +172,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 04:56:48 GMT + - Tue, 05 May 2026 23:45:24 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewall_Update.yaml b/test/integration/fixtures/TestFirewall_Update.yaml index 4cd900d81..97bf03c5a 100644 --- a/test/integration/fixtures/TestFirewall_Update.yaml +++ b/test/integration/fixtures/TestFirewall_Update.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 3885332, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618668, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"protocol": "ICMP", "addresses": {"ipv4": ["0.0.0.0/0"]}, "action": "DROP", "label": "linodego-fwrule-test"}], "inbound_policy": "ACCEPT", "outbound": null, @@ -44,7 +44,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 04:56:48 GMT + - Tue, 05 May 2026 23:45:25 GMT Pragma: - no-cache Strict-Transport-Security: @@ -77,10 +77,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3885332 + url: https://api.linode.com/v4beta/networking/firewalls/9618668 method: PUT response: - body: '{"id": 3885332, "label": "linodego-fw-test-updated", "created": "2018-01-02T03:04:05", + body: '{"id": 9618668, "label": "linodego-fw-test-updated", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "disabled", "rules": {"inbound": [{"protocol": "ICMP", "addresses": {"ipv4": ["0.0.0.0/0"]}, "action": "DROP", "label": "linodego-fwrule-test"}], "inbound_policy": "ACCEPT", "outbound": null, @@ -110,7 +110,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 04:56:48 GMT + - Tue, 05 May 2026 23:45:25 GMT Pragma: - no-cache Strict-Transport-Security: @@ -143,7 +143,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/3885332 + url: https://api.linode.com/v4beta/networking/firewalls/9618668 method: DELETE response: body: '{}' @@ -171,7 +171,7 @@ interactions: Content-Type: - application/json Expires: - - Sat, 28 Feb 2026 04:56:49 GMT + - Tue, 05 May 2026 23:45:26 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestFirewalls_List.yaml b/test/integration/fixtures/TestFirewalls_List.yaml index 5c5e853db..d808777f2 100644 --- a/test/integration/fixtures/TestFirewalls_List.yaml +++ b/test/integration/fixtures/TestFirewalls_List.yaml @@ -2,7 +2,7 @@ version: 1 interactions: - request: - body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"],"devices":{}}' + body: '{"label":"linodego-fw-test","rules":{"inbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"inbound_policy":"ACCEPT","outbound":[{"action":"ACCEPT","label":"go-fwrule-test","ports":"22","protocol":"TCP","addresses":{"ipv4":["0.0.0.0/0"],"ipv6":["1234::5678/0"]}}],"outbound_policy":"ACCEPT"},"tags":["testing"]}' form: {} headers: Accept: @@ -14,12 +14,12 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls method: POST response: - body: '{"id": 692864, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", + body: '{"id": 9618652, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": - [{"action": "ACCEPT", "label": "go-fwrule-test", "ports": "22", "protocol": - "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}}], "inbound_policy": - "ACCEPT", "outbound": [{"action": "ACCEPT", "label": "go-fwrule-test", "ports": - "22", "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}}], + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, + "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "inbound_policy": + "ACCEPT", "outbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": + ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": "22"}], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "7bcc0f03"}, "tags": ["testing"], "entities": []}' headers: @@ -40,13 +40,13 @@ interactions: Connection: - keep-alive Content-Length: - - "583" + - "584" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:49 GMT + - Tue, 05 May 2026 23:45:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -61,12 +61,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -85,105 +82,91 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls?page=1 method: GET response: - body: '{"data": [{"id": 433514, "label": "test-fw", "created": "2018-01-02T03:04:05", + body: '{"data": [{"id": 1629606, "label": "akamai-non-prod-1", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": - [{"action": "ACCEPT", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": ["1234::5678/0"]}, - "ports": "22", "protocol": "TCP", "label": "accept-inbound-SSH", "description": - null}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": "ACCEPT", - "version": 4, "fingerprint": "20eec66f"}, "tags": [], "entities": [{"id": 57328123, - "type": "linode", "label": "debian-us-central", "url": "/v4/linode/instances/57328123"}, - {"id": 54748754, "type": "linode", "label": "debian-us-ord", "url": "/v4/linode/instances/54748754"}]}, - {"id": 624183, "label": "e2e-firewall-izUKXM", "created": "2018-01-02T03:04:05", + [{"protocol": "ICMP", "addresses": {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, + "action": "ACCEPT", "label": "accept-inbound-icmp", "description": "Accept inbound + ICMP"}, {"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128", + "1234::5678/128", "1234::5678/128", + "1234::5678/128", "1234::5678/128", + "1234::5678/128", "1234::5678/128", + "1234::5678/128", "1234::5678/128"], + "ipv4": ["172.236.119.4/30", "172.234.160.4/30", "172.236.94.4/30"]}, "action": + "ACCEPT", "label": "accept-inbound-tcp-ssh-proxies", "ports": "22,443", "description": + "Accept inbound TCP from SSH proxies"}, {"protocol": "TCP", "addresses": {"ipv4": + ["139.144.212.168/31", "172.232.23.164/31"]}, "action": "ACCEPT", "label": "accept-inbound-tcp-eaa-proxies", + "ports": "22,443", "description": "Accept inbound TCP from EAA proxies"}], "inbound_policy": + "DROP", "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": + "aaa34813"}, "tags": ["linuke-keep"], "entities": [{"id": 379283, "type": "linode_interface", + "label": null, "url": "/v4/linode/instances/97114135/interfaces/379283", "parent_entity": + {"id": 97114135, "type": "linode", "label": "test-mcp", "url": "/v4/linode/instances/97114135", + "parent_entity": null}}]}, {"id": 6487222, "label": "tf_test-4730363105259144210", + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": + "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6487694, "label": "tf_test-8181405914570718692", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": - [{"label": "ssh-accept-inbound-rule", "addresses": {"ipv4": ["207.172.164.59/32"]}, - "description": "ACCEPT SSH from test machine", "ports": "22", "protocol": "TCP", - "action": "ACCEPT"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": - "ACCEPT", "version": 1, "fingerprint": "45912779"}, "tags": [], "entities": - []}, {"id": 624308, "label": "e2e-firewall-svVoqB", "created": "2018-01-02T03:04:05", + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6488076, "label": "tf-test-2662579243763295399", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": - [{"label": "ssh-accept-inbound-rule", "addresses": {"ipv4": ["207.172.164.59/32"]}, - "description": "ACCEPT SSH from test machine", "ports": "22", "protocol": "TCP", - "action": "ACCEPT"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": - "ACCEPT", "version": 1, "fingerprint": "45912779"}, "tags": [], "entities": - [{"id": 60939824, "type": "linode", "label": "ansible-test-471035164-updated", - "url": "/v4/linode/instances/60939824"}]}, {"id": 682410, "label": "e2e-firewall-bucVPC", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 682453, "label": "e2e-firewall-WJsukx", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 682477, "label": "e2e-firewall-IzEjvH", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 682500, "label": "e2e-firewall-QdxDkS", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 682505, "label": "e2e-firewall-KkroRq", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 682508, "label": "e2e-firewall-WPxzQk", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 682532, "label": "e2e-firewall-rBZhHt", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"label": "ssh-accept-inbound-rule", "addresses": - {"ipv4": ["207.172.164.59/32"]}, "description": "ACCEPT SSH from test machine", - "ports": "22", "protocol": "TCP", "action": "ACCEPT"}], "inbound_policy": "DROP", - "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "45912779"}, - "tags": [], "entities": []}, {"id": 692740, "label": "cloudfw-1721926678901029000", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"action": "ACCEPT", "label": "ssh-inbound-accept-local", - "ports": "22", "protocol": "TCP", "addresses": {"ipv4": ["207.172.164.59/32"]}}], - "inbound_policy": "DROP", "outbound": [], "outbound_policy": "ACCEPT", "version": - 1, "fingerprint": "3e4f4201"}, "tags": [], "entities": []}, {"id": 692760, "label": - "cloudfw-1721927227347144000", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"action": - "ACCEPT", "label": "ssh-inbound-accept-local", "ports": "22", "protocol": "TCP", - "addresses": {"ipv4": ["207.172.164.59/32"]}}], "inbound_policy": "DROP", "outbound": - [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "3e4f4201"}, "tags": - [], "entities": []}, {"id": 692763, "label": "cloudfw-1721927316071520000", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"action": "ACCEPT", "label": "ssh-inbound-accept-local", - "ports": "22", "protocol": "TCP", "addresses": {"ipv4": ["207.172.164.59/32"]}}], - "inbound_policy": "DROP", "outbound": [], "outbound_policy": "ACCEPT", "version": - 1, "fingerprint": "3e4f4201"}, "tags": [], "entities": []}, {"id": 692848, "label": - "cloudfw-1721929346146739000", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": [{"action": - "ACCEPT", "label": "ssh-inbound-accept-local", "ports": "22", "protocol": "TCP", - "addresses": {"ipv4": ["207.172.164.59/32"]}}], "inbound_policy": "DROP", "outbound": - [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "3e4f4201"}, "tags": - [], "entities": []}, {"id": 692854, "label": "cloudfw-1721929441971780000", + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6488152, "label": "tf-test-7434155876252647646", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6488643, "label": "tf_test-4497105480711871048", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6488833, "label": "tf_test-2716164270344383334", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6488942, "label": "tf_test-5198004906850423409", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6488991, "label": "tf_test-8335666987695131249", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 6489132, "label": "tf_test-8711695578112956943", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/128"], + "ipv4": ["74.102.235.249/32"]}, "action": "ACCEPT", "label": "tcp_inbound_ssh_accept_local", + "ports": "22"}], "inbound_policy": "DROP", "outbound": [], "outbound_policy": + "ACCEPT", "version": 1, "fingerprint": "5aa2d804"}, "tags": [], "entities": + []}, {"id": 9618460, "label": "cloudfw-1778024706560062000", "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "status": "enabled", "rules": {"inbound": + [{"protocol": "TCP", "addresses": {"ipv4": ["74.102.235.249/32"]}, "action": + "ACCEPT", "label": "ssh-inbound-accept-local", "ports": "22"}], "inbound_policy": + "DROP", "outbound": [], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": + "e3c5e43b"}, "tags": [], "entities": []}, {"id": 9618652, "label": "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "status": - "enabled", "rules": {"inbound": [{"action": "ACCEPT", "label": "ssh-inbound-accept-local", - "ports": "22", "protocol": "TCP", "addresses": {"ipv4": ["207.172.164.59/32"]}}], - "inbound_policy": "DROP", "outbound": [], "outbound_policy": "ACCEPT", "version": - 1, "fingerprint": "3e4f4201"}, "tags": [], "entities": []}, {"id": 692864, "label": - "linodego-fw-test", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "status": "enabled", "rules": {"inbound": [{"action": "ACCEPT", "label": "go-fwrule-test", - "ports": "22", "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], "ipv6": - ["1234::5678/0"]}}], "inbound_policy": "ACCEPT", "outbound": [{"action": "ACCEPT", "label": - "go-fwrule-test", "ports": "22", "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"], - "ipv6": ["1234::5678/0"]}}], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": - "7bcc0f03"}, "tags": ["testing"], "entities": []}], "page": 1, "pages": 1, "results": - 16}' + "enabled", "rules": {"inbound": [{"protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"], + "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", "ports": + "22"}], "inbound_policy": "ACCEPT", "outbound": [{"protocol": "TCP", "addresses": + {"ipv6": ["1234::5678/0"], "ipv4": ["0.0.0.0/0"]}, "action": "ACCEPT", "label": "go-fwrule-test", + "ports": "22"}], "outbound_policy": "ACCEPT", "version": 1, "fingerprint": "7bcc0f03"}, + "tags": ["testing"], "entities": []}], "page": 1, "pages": 1, "results": 12}' headers: Access-Control-Allow-Credentials: - "true" @@ -206,7 +189,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:49 GMT + - Tue, 05 May 2026 23:45:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -223,12 +206,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -244,7 +224,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/692864 + url: https://api.linode.com/v4beta/networking/firewalls/9618652 method: DELETE response: body: '{}' @@ -272,7 +252,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 17:44:49 GMT + - Tue, 05 May 2026 23:45:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -287,12 +267,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestImage_CloudInit.yaml b/test/integration/fixtures/TestImage_CloudInit.yaml index 381d89283..51b70b1de 100644 --- a/test/integration/fixtures/TestImage_CloudInit.yaml +++ b/test/integration/fixtures/TestImage_CloudInit.yaml @@ -14,290 +14,449 @@ interactions: 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", "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", - "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", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "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", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Cloud Firewall", - "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": - {"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", "Cloud Firewall", "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": 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", "Cloud Firewall", "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": {"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", - "Cloud Firewall", "Managed Databases", "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", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Cloud Firewall", "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", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Cloud Firewall", "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"}, "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", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Cloud Firewall", "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": "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": "es-mad", "label": "Madrid, ES", "country": - "es", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Cloud Firewall", "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"}, - "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", "Cloud Firewall", "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": 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", "Cloud Firewall", "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", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Cloud Firewall", "Managed Databases", "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", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "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", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "Cloud Firewall", "Managed Databases", "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", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "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"], "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"], "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"], "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"], "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"], "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"], "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"], "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"], "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"], "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": - {"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", "Cloud Firewall", "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, "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", "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, "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", "Cloud Firewall", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "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": "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, + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "eu-west", "label": "London, UK", "country": - "gb", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "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": - 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", "Cloud Firewall", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "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": "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": 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", "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"}, + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo, JP", "country": - "jp", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Block Storage", - "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}' + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -312,24 +471,23 @@ interactions: Akamai-Internal-Account: - '*' Cache-Control: - - private, max-age=900 - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "24356" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.14.2 + Expires: + - Wed, 06 May 2026 01:41:43 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - '*' X-Content-Type-Options: @@ -338,19 +496,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" + - "1840" 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-837hb70fb4qy","root_pass":"545$7Z)AA9sXKf,sXaf8^*W}jy((rk|96998De3YdYYw~cKZ{9,KB\u003c=84ki`uM7+","image":"linode/debian9","firewall_id":693368,"booted":false}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-3o0411gu5ucp","root_pass":"U31M3!vA{fc02bspJ''S(H[NFB8G2;eb@2Hi7d/2zu709wg3`\u003cU+p4\\$LW7(Mq?J!","image":"linode/debian12","firewall_id":9689919,"booted":false}' form: {} headers: Accept: @@ -362,17 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61877581, "label": "go-test-ins-837hb70fb4qy", "group": "", "status": + body: '{"id": 97189517, "label": "go-test-ins-3o0411gu5ucp", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["192.46.208.15"], "ipv6": "1234::5678/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": true, "available": false, "schedule": {"day": - null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": - true, "tags": [], "host_uuid": "0e0c1ef96c34828ce8b53e9e04870191260828c7", "has_user_data": - false, "placement_group": null, "disk_encryption": "disabled", "lke_cluster_id": - null}' + "type": "g6-nanode-1", "ipv4": ["172.236.44.171"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "6c9b57be39471d7888b736f623fe5527fd93c553", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -387,22 +544,22 @@ interactions: Akamai-Internal-Account: - '*' Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "841" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.14.2 + Expires: + - Wed, 06 May 2026 01:41:45 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - linodes:read_write X-Content-Type-Options: @@ -411,12 +568,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: - - "10" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -432,15 +586,15 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61877581/disks?page=1 + url: https://api.linode.com/v4beta/linode/instances/97189517/disks?page=1 method: GET response: - body: '{"data": [{"id": 121429953, "status": "not ready", "label": "Debian 9 Disk", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": - "ext4", "size": 25088, "disk_encryption": "disabled"}, {"id": 121429954, "status": + body: '{"data": [{"id": 183299550, "status": "not ready", "label": "Debian 12 + Disk", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": + "ext4", "size": 25088, "disk_encryption": "enabled"}, {"id": 183299552, "status": "not ready", "label": "512 MB Swap Image", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": "swap", "size": 512, "disk_encryption": - "disabled"}], "page": 1, "pages": 1, "results": 2}' + "enabled"}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -455,21 +609,21 @@ interactions: Akamai-Internal-Account: - '*' Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "457" + - "456" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.14.2 + Expires: + - Wed, 06 May 2026 01:41:45 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter @@ -481,19 +635,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"disk_id":121429953,"label":"linodego-test-cloud-init","cloud_init":true,"tags":["test1","test2"]}' + body: '{"disk_id":183299550,"label":"linodego-test-cloud-init","cloud_init":true,"tags":["test1","test2"]}' form: {} headers: Accept: @@ -505,12 +656,14 @@ interactions: url: https://api.linode.com/v4beta/images method: POST response: - body: '{"id": "private/26428978", "label": "linodego-test-cloud-init", "description": + body: '{"id": "private/38637317", "label": "linodego-test-cloud-init", "description": "", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": - 25088, "created_by": "ychen123", "type": "manual", "tags": ["test1", "test2"], - "is_public": false, "deprecated": false, "vendor": null, "expiry": null, "eol": - null, "status": "creating", "capabilities": ["cloud-init"], "regions": [], "total_size": - 25088}' + 25088, "created_by": "zliang27", "type": "manual", "tags": ["test1", "test2"], + "is_public": false, "is_shared": false, "deprecated": false, "vendor": null, + "expiry": null, "eol": null, "status": "creating", "capabilities": ["cloud-init"], + "regions": [], "total_size": 25088, "image_sharing": {"shared_with": {"sharegroup_count": + 0, "sharegroup_list_url": "/images/private/38637317/sharegroups"}, "shared_by": + null}}' headers: Access-Control-Allow-Credentials: - "true" @@ -525,20 +678,21 @@ interactions: Akamai-Internal-Account: - '*' Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: - - "413" + - "574" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.14.2 + Expires: + - Wed, 06 May 2026 01:41:45 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -549,12 +703,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -570,7 +721,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F26428978 + url: https://api.linode.com/v4beta/images/private%2F38637317 method: DELETE response: body: '{}' @@ -588,7 +739,7 @@ interactions: Akamai-Internal-Account: - '*' Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: @@ -597,11 +748,12 @@ interactions: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.14.2 + Expires: + - Wed, 06 May 2026 01:41:46 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -612,12 +764,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -633,7 +782,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61877581 + url: https://api.linode.com/v4beta/linode/instances/97189517 method: DELETE response: body: '{}' @@ -651,7 +800,7 @@ interactions: Akamai-Internal-Account: - '*' Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store Connection: - keep-alive Content-Length: @@ -660,11 +809,12 @@ interactions: - default-src 'none' Content-Type: - application/json - Server: - - nginx/1.14.2 + Expires: + - Wed, 06 May 2026 01:41:46 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 - - max-age=31536000 Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -675,12 +825,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestInstance_ConfigInterface_Update.yaml b/test/integration/fixtures/TestInstance_ConfigInterface_Update.yaml index 6b27dad88..8d949dedb 100644 --- a/test/integration/fixtures/TestInstance_ConfigInterface_Update.yaml +++ b/test/integration/fixtures/TestInstance_ConfigInterface_Update.yaml @@ -14,308 +14,449 @@ interactions: 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", "StackScripts", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases"]}, "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", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_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", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases"]}, "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", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_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", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases"]}, "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", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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", + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases"]}, + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block - Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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", + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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", + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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, "maximum_linodes_per_flexible_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", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases"]}, - "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", + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "gb-lon", - "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Block - Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "au-mel", - "label": "Melbourne, AU", "country": "au", "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", - "NETINT Quadra T1U", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases"]}, "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", - "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block - Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": []}, "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", - "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block - Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT - Quadra T1U", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": []}, - "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_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", - "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases"]}, "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", - "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block - Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": []}, "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": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}, + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "no-osl-1", - "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": - ["Managed Databases"]}, "status": "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", - "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases"]}, "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block - Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", - "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": - ["Managed Databases"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_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", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases"]}, "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, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", - "label": "Newark, NJ", "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", "StackScripts", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases"]}, - "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", - "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "monitors": {"alerts": [], "metrics": []}, "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", + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}, {"id": "ap-south", "label": "Singapore, SG", "country": - "sg", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": - []}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", - "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Disk - Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases"]}, "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, "maximum_linodes_per_flexible_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", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}], "page": 1, - "pages": 1, "results": 32}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -338,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:17 GMT + - Wed, 06 May 2026 01:42:16 GMT Pragma: - no-cache Strict-Transport-Security: @@ -364,7 +505,7 @@ interactions: code: 200 duration: "" - request: - body: '{"region":"us-iad","type":"g6-nanode-1","label":"go-test-ins-wo-disk-5w5bd648nt6s","firewall_id":3118155,"booted":false}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-ins-wo-disk-frs3e56081kn","firewall_id":9690256,"booted":false}' form: {} headers: Accept: @@ -376,18 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 82372490, "label": "go-test-ins-wo-disk-5w5bd648nt6s", "group": + body: '{"id": 97189528, "label": "go-test-ins-wo-disk-frs3e56081kn", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.234.34.68"], "ipv6": "1234::5678/128", - "image": null, "region": "us-iad", "site_type": "core", "specs": {"disk": 25600, + "type": "g6-nanode-1", "ipv4": ["172.236.53.76"], "ipv6": "1234::5678/128", + "image": null, "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, "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": "a43b13eb39143250ac287a23d5f4b7a6b9cbdcb8", - "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", - "lke_cluster_id": null, "capabilities": ["Block Storage Encryption"], "interface_generation": - "legacy_config"}' + 80, "io": 10000, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "6c9b57be39471d7888b736f623fe5527fd93c553", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -410,7 +552,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:18 GMT + - Wed, 06 May 2026 01:42:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -435,7 +577,7 @@ interactions: code: 200 duration: "" - request: - body: '{"label":"go-test-conf-2w36vde54y4t","devices":{},"interfaces":null}' + body: '{"label":"go-test-conf-yj19236bv7xh","devices":{},"interfaces":null}' form: {} headers: Accept: @@ -444,10 +586,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/82372490/configs + url: https://api.linode.com/v4beta/linode/instances/97189528/configs method: POST response: - body: '{"id": 85836401, "label": "go-test-conf-2w36vde54y4t", "helpers": {"updatedb_disabled": + body: '{"id": 100667257, "label": "go-test-conf-yj19236bv7xh", "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", @@ -472,13 +614,13 @@ interactions: Connection: - keep-alive Content-Length: - - "540" + - "541" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:18 GMT + - Wed, 06 May 2026 01:42:17 GMT Pragma: - no-cache Strict-Transport-Security: @@ -502,7 +644,7 @@ interactions: code: 200 duration: "" - request: - body: '{"label":"go-test-vpc-1755896298637431000","region":"us-iad","subnets":[{"label":"linodego-vpc-test-1755896298637567000","ipv4":"192.168.0.0/25"}]}' + body: '{"label":"go-test-vpc-1778031737830980000","region":"au-mel","subnets":[{"label":"linodego-vpc-test-1778031737831097000","ipv4":"192.168.0.0/25"}]}' form: {} headers: Accept: @@ -514,11 +656,13 @@ interactions: url: https://api.linode.com/v4beta/vpcs method: POST response: - body: '{"id": 234045, "label": "go-test-vpc-1755896298637431000", "description": - "", "region": "us-iad", "ipv6": null, "subnets": [{"id": 241126, "label": "linodego-vpc-test-1755896298637567000", - "ipv4": "192.168.0.0/25", "ipv6": null, "linodes": [], "databases": [], "nodebalancers": - [], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}], "created": - "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}' + body: '{"id": 471961, "label": "go-test-vpc-1778031737830980000", "description": + "", "region": "au-mel", "ipv4": [{"range": "10.0.0.0/8"}, {"range": "172.16.0.0/12"}, + {"range": "192.168.0.0/16"}], "ipv6": null, "subnets": [{"id": 629500, "label": + "linodego-vpc-test-1778031737831097000", "ipv4": "192.168.0.0/25", "ipv6": null, + "linodes": [], "databases": [], "nodebalancers": [], "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05"}], "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05"}' headers: Access-Control-Allow-Credentials: - "true" @@ -537,13 +681,13 @@ interactions: Connection: - keep-alive Content-Length: - - "419" + - "511" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:19 GMT + - Wed, 06 May 2026 01:42:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -567,7 +711,7 @@ interactions: code: 200 duration: "" - request: - body: '{"purpose":"vpc","subnet_id":241126,"ip_ranges":["192.168.0.5/32"]}' + body: '{"purpose":"vpc","subnet_id":629500,"ip_ranges":["192.168.0.5/32"]}' form: {} headers: Accept: @@ -576,11 +720,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/82372490/configs/85836401/interfaces + url: https://api.linode.com/v4beta/linode/instances/97189528/configs/100667257/interfaces method: POST response: - body: '{"id": 6763962, "purpose": "vpc", "primary": false, "active": false, "ipam_address": - null, "label": null, "vpc_id": 234045, "subnet_id": 241126, "ipv4": {"vpc": + body: '{"id": 12282598, "purpose": "vpc", "primary": false, "active": false, "ipam_address": + null, "label": null, "vpc_id": 471961, "subnet_id": 629500, "ipv4": {"vpc": "192.168.0.2", "nat_1_1": null}, "ip_ranges": ["192.168.0.5/32"], "ipv6": null}' headers: Access-Control-Allow-Credentials: @@ -600,13 +744,13 @@ interactions: Connection: - keep-alive Content-Length: - - "240" + - "241" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:19 GMT + - Wed, 06 May 2026 01:42:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -639,11 +783,11 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/82372490/configs/85836401/interfaces/6763962 + url: https://api.linode.com/v4beta/linode/instances/97189528/configs/100667257/interfaces/12282598 method: PUT response: - body: '{"id": 6763962, "purpose": "vpc", "primary": true, "active": false, "ipam_address": - null, "label": null, "vpc_id": 234045, "subnet_id": 241126, "ipv4": {"vpc": + body: '{"id": 12282598, "purpose": "vpc", "primary": true, "active": false, "ipam_address": + null, "label": null, "vpc_id": 471961, "subnet_id": 629500, "ipv4": {"vpc": "192.168.0.2", "nat_1_1": null}, "ip_ranges": ["192.168.0.5/32"], "ipv6": null}' headers: Access-Control-Allow-Credentials: @@ -663,13 +807,13 @@ interactions: Connection: - keep-alive Content-Length: - - "239" + - "240" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:19 GMT + - Wed, 06 May 2026 01:42:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -702,12 +846,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/82372490/configs/85836401/interfaces/6763962 + url: https://api.linode.com/v4beta/linode/instances/97189528/configs/100667257/interfaces/12282598 method: PUT response: - body: '{"id": 6763962, "purpose": "vpc", "primary": true, "active": false, "ipam_address": - null, "label": null, "vpc_id": 234045, "subnet_id": 241126, "ipv4": {"vpc": - "192.168.0.10", "nat_1_1": "172.234.34.68"}, "ip_ranges": [], "ipv6": null}' + body: '{"id": 12282598, "purpose": "vpc", "primary": true, "active": false, "ipam_address": + null, "label": null, "vpc_id": 471961, "subnet_id": 629500, "ipv4": {"vpc": + "192.168.0.10", "nat_1_1": "172.236.53.76"}, "ip_ranges": [], "ipv6": null}' headers: Access-Control-Allow-Credentials: - "true" @@ -726,13 +870,13 @@ interactions: Connection: - keep-alive Content-Length: - - "235" + - "236" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:19 GMT + - Wed, 06 May 2026 01:42:19 GMT Pragma: - no-cache Strict-Transport-Security: @@ -765,7 +909,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/82372490 + url: https://api.linode.com/v4beta/linode/instances/97189528 method: DELETE response: body: '{}' @@ -793,7 +937,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:21 GMT + - Wed, 06 May 2026 01:42:19 GMT Pragma: - no-cache Strict-Transport-Security: @@ -826,7 +970,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/vpcs/234045 + url: https://api.linode.com/v4beta/vpcs/471961 method: DELETE response: body: '{}' @@ -854,7 +998,7 @@ interactions: Content-Type: - application/json Expires: - - Fri, 22 Aug 2025 20:58:22 GMT + - Wed, 06 May 2026 01:42:20 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestInstance_CreateWithLinodeInterfaces.yaml b/test/integration/fixtures/TestInstance_CreateWithLinodeInterfaces.yaml index c9f189648..5efcc3b0d 100644 --- a/test/integration/fixtures/TestInstance_CreateWithLinodeInterfaces.yaml +++ b/test/integration/fixtures/TestInstance_CreateWithLinodeInterfaces.yaml @@ -31,74 +31,74 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": - ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", - "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": - []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", "country": "us", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", "country": "cl", - "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", - "Metadata", "Distributed Plans", "Maintenance Policy"], "monitors": {"alerts": - [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", - "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": - 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": - "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": - ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", @@ -107,20 +107,20 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", @@ -130,8 +130,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", @@ -141,8 +141,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", @@ -152,15 +152,15 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", "Maintenance - Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", @@ -179,31 +179,37 @@ interactions: "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": "ok", - "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.18", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk - Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans", - "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": - "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", - "Disk Encryption", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Distributed - Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": @@ -213,8 +219,8 @@ interactions: "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", @@ -223,8 +229,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", @@ -233,8 +239,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", @@ -265,8 +271,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", @@ -275,9 +281,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", @@ -287,8 +293,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", @@ -297,8 +303,9 @@ interactions: "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", @@ -307,9 +314,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", @@ -318,9 +325,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", @@ -329,9 +336,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", @@ -341,8 +348,8 @@ interactions: Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", @@ -351,9 +358,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", @@ -362,9 +369,9 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", @@ -372,9 +379,9 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", @@ -382,9 +389,9 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", @@ -393,8 +400,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", @@ -402,8 +409,8 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": - ["NodeBalancers"]}, "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", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", @@ -411,20 +418,20 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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,173.255.225.5,66.228.35.5", + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", @@ -433,8 +440,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", @@ -442,14 +449,14 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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": + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 46}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -472,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 24 Mar 2026 17:06:58 GMT + - Wed, 06 May 2026 01:42:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -498,261 +505,7 @@ interactions: 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/account/availability?page=1 - method: GET - response: - body: '{"data": [{"region": "us-central", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "us-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-southeast", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-east", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "eu-west", "available": [], "unavailable": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "ap-south", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "eu-central", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "ap-northeast", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "ca-central", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-southeast", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-iad", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-ord", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "fr-par", "available": ["Linodes", "NodeBalancers"], "unavailable": ["Block - Storage", "Kubernetes"]}, {"region": "us-sea", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "br-gru", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "nl-ams", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "se-sto", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "es-mad", "available": ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", - "Block Storage"]}, {"region": "in-maa", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "jp-osa", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "it-mil", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-mia", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "id-cgk", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-lax", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "nz-akl-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-den-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "de-ham-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "za-jnb-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "my-kul-1", "available": ["Linodes"], "unavailable": - ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": "co-bog-1", "available": - ["Linodes"], "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, - {"region": "mx-qro-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "us-hou-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "cl-scl-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "gb-lon", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "au-mel", "available": - ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", "Block Storage"]}, - {"region": "in-bom-2", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "de-fra-2", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "sg-sin-2", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "jp-tyo-3", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "de-ber-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "no-osl-1", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-iad-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-par-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "co-bog-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-mrs-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}], "page": 1, "pages": 1, "results": - 46}' - 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, 24 Mar 2026 17:06:58 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - account:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1840" - 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/account/availability?page=1 - method: GET - response: - body: '{"data": [{"region": "us-central", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "us-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-southeast", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-east", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "eu-west", "available": [], "unavailable": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "ap-south", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "eu-central", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "ap-northeast", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "ca-central", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-southeast", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-iad", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-ord", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "fr-par", "available": ["Linodes", "NodeBalancers"], "unavailable": ["Block - Storage", "Kubernetes"]}, {"region": "us-sea", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "br-gru", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "nl-ams", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "se-sto", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "es-mad", "available": ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", - "Block Storage"]}, {"region": "in-maa", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "jp-osa", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "it-mil", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-mia", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "id-cgk", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-lax", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "nz-akl-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-den-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "de-ham-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "za-jnb-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "my-kul-1", "available": ["Linodes"], "unavailable": - ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": "co-bog-1", "available": - ["Linodes"], "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, - {"region": "mx-qro-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "us-hou-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "cl-scl-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "gb-lon", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "au-mel", "available": - ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", "Block Storage"]}, - {"region": "in-bom-2", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "de-fra-2", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "sg-sin-2", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "jp-tyo-3", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "de-ber-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "no-osl-1", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-iad-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-par-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "co-bog-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-mrs-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}], "page": 1, "pages": 1, "results": - 46}' - 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, 24 Mar 2026 17:06:58 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - account:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1840" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"label":"go-test-vpc-1774372018772667000","region":"au-mel","subnets":[{"label":"linodego-vpc-test-1774372018952471000","ipv4":"192.168.0.0/25"}]}' + body: '{"label":"go-test-vpc-1778031772656360000","region":"au-mel","subnets":[{"label":"linodego-vpc-test-1778031772656574000","ipv4":"192.168.0.0/25"}]}' form: {} headers: Accept: @@ -764,11 +517,13 @@ interactions: url: https://api.linode.com/v4beta/vpcs method: POST response: - body: '{"id": 422885, "label": "go-test-vpc-1774372018772667000", "description": - "", "region": "au-mel", "ipv6": null, "subnets": [{"id": 523986, "label": "linodego-vpc-test-1774372018952471000", - "ipv4": "192.168.0.0/25", "ipv6": null, "linodes": [], "databases": [], "nodebalancers": - [], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}], "created": - "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05"}' + body: '{"id": 471962, "label": "go-test-vpc-1778031772656360000", "description": + "", "region": "au-mel", "ipv4": [{"range": "10.0.0.0/8"}, {"range": "172.16.0.0/12"}, + {"range": "192.168.0.0/16"}], "ipv6": null, "subnets": [{"id": 629501, "label": + "linodego-vpc-test-1778031772656574000", "ipv4": "192.168.0.0/25", "ipv6": null, + "linodes": [], "databases": [], "nodebalancers": [], "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05"}], "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05"}' headers: Access-Control-Allow-Credentials: - "true" @@ -787,13 +542,13 @@ interactions: Connection: - keep-alive Content-Length: - - "419" + - "511" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Tue, 24 Mar 2026 17:06:59 GMT + - Wed, 06 May 2026 01:42:53 GMT Pragma: - no-cache Strict-Transport-Security: @@ -817,134 +572,7 @@ interactions: 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/account/availability?page=1 - method: GET - response: - body: '{"data": [{"region": "us-central", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "us-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-southeast", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-east", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "eu-west", "available": [], "unavailable": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "ap-south", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "eu-central", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "ap-northeast", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-west", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "ca-central", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "ap-southeast", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-iad", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-ord", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "fr-par", "available": ["Linodes", "NodeBalancers"], "unavailable": ["Block - Storage", "Kubernetes"]}, {"region": "us-sea", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "br-gru", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "nl-ams", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "se-sto", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "es-mad", "available": ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", - "Block Storage"]}, {"region": "in-maa", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "jp-osa", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "it-mil", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "us-mia", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "id-cgk", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "us-lax", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "nz-akl-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "us-den-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "de-ham-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "za-jnb-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "my-kul-1", "available": ["Linodes"], "unavailable": - ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": "co-bog-1", "available": - ["Linodes"], "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, - {"region": "mx-qro-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", - "Block Storage", "Kubernetes"]}, {"region": "us-hou-1", "available": ["Linodes"], - "unavailable": ["NodeBalancers", "Block Storage", "Kubernetes"]}, {"region": - "cl-scl-1", "available": ["Linodes"], "unavailable": ["NodeBalancers", "Block - Storage", "Kubernetes"]}, {"region": "gb-lon", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "au-mel", "available": - ["Linodes", "Kubernetes"], "unavailable": ["NodeBalancers", "Block Storage"]}, - {"region": "in-bom-2", "available": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes"], "unavailable": []}, {"region": "de-fra-2", "available": ["Linodes", - "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": []}, {"region": - "sg-sin-2", "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], - "unavailable": []}, {"region": "jp-tyo-3", "available": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes"], "unavailable": []}, {"region": "de-ber-1", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "no-osl-1", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "us-iad-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-par-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}, {"region": "co-bog-2", "available": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], "unavailable": - []}, {"region": "fr-mrs-2", "available": ["Linodes", "NodeBalancers", "Block - Storage", "Kubernetes"], "unavailable": []}], "page": 1, "pages": 1, "results": - 46}' - 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, 24 Mar 2026 17:06:59 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - - Accept-Encoding - X-Accepted-Oauth-Scopes: - - account:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1840" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-intf-du996l59d1lu","root_pass":"CP00c?8nd4w9;F@92B:ov[(h{Z)00Z07qxY*B8@1iaRhD/JA=jGd05O[u\u0026Y@R\u00261g","image":"linode/debian12","interface_generation":"linode","booted":false,"interfaces":[{"firewall_id":4016480,"public":{"ipv4":{"addresses":[{"address":"auto","primary":true}]},"ipv6":{}}},{"firewall_id":4016480,"vpc":{"subnet_id":523986,"ipv4":{"addresses":[{"address":"auto","primary":true,"nat_1_1_address":"auto"}]}}}]}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-test-intf-2x63ssy273oo","root_pass":"iDl^x+k7y)mu,3[A4~Z+2MtK04k(6HVCT^D5B6x-/0Qz{2m5eZ\u003cL*2l148.uKsI[","image":"linode/debian12","interface_generation":"linode","booted":false,"interfaces":[{"firewall_id":9690627,"public":{"ipv4":{"addresses":[{"address":"auto","primary":true}]},"ipv6":{}}},{"firewall_id":9690627,"vpc":{"subnet_id":629501,"ipv4":{"addresses":[{"address":"auto","primary":true,"nat_1_1_address":"auto"}]}}}]}' form: {} headers: Accept: @@ -956,20 +584,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 94760148, "label": "go-test-intf-du996l59d1lu", "group": "", "status": + body: '{"id": 97189542, "label": "go-test-intf-2x63ssy273oo", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["172.236.62.246", "172.236.62.247"], "ipv6": - "1234::5678/128", "image": "linode/debian12", "region": - "au-mel", "site_type": "core", "specs": {"disk": 25600, "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, - "system_alerts": [], "user_alerts": []}, "backups": {"enabled": false, "available": - false, "schedule": {"day": null, "window": null}, "last_successful": null}, - "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": "9a7697483a9ca8c5ddfadf4ddee2c1f1819f1be4", - "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", - "lke_cluster_id": null, "capabilities": ["Block Storage Encryption", "SMTP Enabled", - "Maintenance Policy"], "interface_generation": "linode", "maintenance_policy": - "linode/migrate", "locks": []}' + "type": "g6-nanode-1", "ipv4": ["172.236.53.76", "172.236.53.98"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "7c21ff8b1596655206e1b4c6bc4f1c8ebd03c68c", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "linode", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -992,7 +619,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 24 Mar 2026 17:07:01 GMT + - Wed, 06 May 2026 01:42:55 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1026,7 +653,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/94760148 + url: https://api.linode.com/v4beta/linode/instances/97189542 method: DELETE response: body: '{}' @@ -1054,7 +681,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 24 Mar 2026 17:07:01 GMT + - Wed, 06 May 2026 01:42:55 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1087,7 +714,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/vpcs/422885 + url: https://api.linode.com/v4beta/vpcs/471962 method: DELETE response: body: '{}' @@ -1115,7 +742,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 24 Mar 2026 17:07:02 GMT + - Wed, 06 May 2026 01:42:56 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestLKECluster_Update.yaml b/test/integration/fixtures/TestLKECluster_Update.yaml index 979b2fd63..c15695137 100644 --- a/test/integration/fixtures/TestLKECluster_Update.yaml +++ b/test/integration/fixtures/TestLKECluster_Update.yaml @@ -14,318 +14,449 @@ interactions: url: https://api.linode.com/v4beta/regions?page=1 method: GET response: - body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": - ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ca-central", "label": "Toronto, CA", "country": - "ca", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "ap-southeast", "label": "Sydney, AU", "country": - "au", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-iad", "label": "Washington, DC", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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-ord", "label": "Chicago, IL", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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": "fr-par", "label": "Paris, FR", "country": - "fr", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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-sea", "label": "Seattle, WA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "br-gru", "label": "Sao Paulo, BR", "country": - "br", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "nl-ams", "label": "Amsterdam, NL", "country": - "nl", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "se-sto", "label": "Stockholm, SE", "country": - "se", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": - "es", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "jp-osa", "label": "Osaka, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "it-mil", "label": "Milan, IT", "country": - "it", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "us-mia", "label": "Miami, FL", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": - "id", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-lax", "label": "Los Angeles, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "nz-akl-1", "label": "Auckland, NZ", "country": - "nz", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": - "us", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", - "country": "de", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "fr-mrs-1", "label": "Marseille, FR", - "country": "fr", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, - ZA", "country": "za", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, - MY", "country": "my", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", - "country": "co", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, - MX", "country": "mx", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", - "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", - "country": "cl", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": - "gb", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": - "au", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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": "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": "de-fra-2", "label": "Frankfurt 2, DE", "country": - "de", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "NETINT Quadra T1U", "Linode Interfaces"], - "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": "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": "sg-sin-2", "label": "Singapore 2, SG", "country": - "sg", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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-tyo-3", "label": "Tokyo 3, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "de-ber-1", "label": "Berlin, DE", "country": - "de", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-central", "label": "Dallas, TX", - "country": "us", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group", "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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-west", "label": "Fremont, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": - ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group", "StackScripts", "Linode Interfaces"], "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", + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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,173.255.225.5,66.228.35.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": "eu-west", "label": "London, UK", "country": - "gb", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Linode - Interfaces"], "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": null, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", "label": - "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": - "de", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": - "jp", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 42}' + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -348,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 12 May 2025 19:03:38 GMT + - Wed, 06 May 2026 16:18:35 GMT Pragma: - no-cache Strict-Transport-Security: @@ -367,14 +498,75 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" + 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/lke/tiers/standard/versions?page=1 + method: GET + response: + body: '{"data": [{"id": "1.35", "tier": "standard"}, {"id": "1.34", "tier": "standard"}], + "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: + - "119" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Wed, 06 May 2026 16:18:35 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - lke:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"node_pools":[{"count":1,"type":"g6-standard-2","disks":null,"tags":["test"],"labels":null,"taints":null}],"label":"go-lke-test-update","region":"ap-west","k8s_version":"1.31","tags":["testing"],"tier":"standard"}' + body: '{"node_pools":[{"count":1,"type":"g6-standard-2","disks":null,"tags":["test"],"labels":null,"taints":null}],"label":"go-lke-test-update","region":"au-mel","k8s_version":"1.35","tags":["testing"],"tier":"standard"}' form: {} headers: Accept: @@ -386,10 +578,10 @@ interactions: url: https://api.linode.com/v4beta/lke/clusters method: POST response: - body: '{"id": 433100, "status": "ready", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "label": "go-lke-test-update", "region": "ap-west", "k8s_version": - "1.31", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": - false, "tags": ["testing"]}' + body: '{"id": 600522, "status": "ready", "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "label": "go-lke-test-update", "region": "au-mel", "k8s_version": + "1.35", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": + false, "tags": ["testing"], "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -408,13 +600,13 @@ interactions: Connection: - keep-alive Content-Length: - - "286" + - "298" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 12 May 2025 19:03:49 GMT + - Wed, 06 May 2026 16:18:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -431,14 +623,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"k8s_version":"1.32","label":"go-lke-test-update-updated","tags":["test=true"]}' + body: '{"label":"go-lke-test-update-updated","tags":["test=true"]}' form: {} headers: Accept: @@ -447,13 +639,13 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/433100 + url: https://api.linode.com/v4beta/lke/clusters/600522 method: PUT response: - body: '{"id": 433100, "status": "ready", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "label": "go-lke-test-update-updated", "region": "ap-west", - "k8s_version": "1.32", "tier": "standard", "control_plane": {"high_availability": - false}, "apl_enabled": false, "tags": ["test=true"]}' + body: '{"id": 600522, "status": "ready", "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "label": "go-lke-test-update-updated", "region": "au-mel", + "k8s_version": "1.35", "tier": "standard", "control_plane": {"high_availability": + false}, "apl_enabled": false, "tags": ["test=true"], "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -472,13 +664,13 @@ interactions: Connection: - keep-alive Content-Length: - - "296" + - "308" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 12 May 2025 19:03:52 GMT + - Wed, 06 May 2026 16:18:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -495,7 +687,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -511,13 +703,13 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/433100 + url: https://api.linode.com/v4beta/lke/clusters/600522 method: PUT response: - body: '{"id": 433100, "status": "ready", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "label": "go-lke-test-update-updated", "region": "ap-west", - "k8s_version": "1.32", "tier": "standard", "control_plane": {"high_availability": - true}, "apl_enabled": false, "tags": ["test=true"]}' + body: '{"id": 600522, "status": "ready", "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "label": "go-lke-test-update-updated", "region": "au-mel", + "k8s_version": "1.35", "tier": "standard", "control_plane": {"high_availability": + true}, "apl_enabled": false, "tags": ["test=true"], "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -536,13 +728,13 @@ interactions: Connection: - keep-alive Content-Length: - - "295" + - "307" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 12 May 2025 19:03:55 GMT + - Wed, 06 May 2026 16:18:45 GMT Pragma: - no-cache Strict-Transport-Security: @@ -559,7 +751,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -575,7 +767,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/433100 + url: https://api.linode.com/v4beta/lke/clusters/600522 method: DELETE response: body: '{}' @@ -603,7 +795,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 12 May 2025 19:03:59 GMT + - Wed, 06 May 2026 16:18:49 GMT Pragma: - no-cache Strict-Transport-Security: @@ -620,7 +812,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestLKECluster_withACL.yaml b/test/integration/fixtures/TestLKECluster_withACL.yaml index 764a93201..29b2d65bb 100644 --- a/test/integration/fixtures/TestLKECluster_withACL.yaml +++ b/test/integration/fixtures/TestLKECluster_withACL.yaml @@ -14,318 +14,449 @@ interactions: url: https://api.linode.com/v4beta/regions?page=1 method: GET response: - body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": - ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ca-central", "label": "Toronto, CA", "country": - "ca", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "ap-southeast", "label": "Sydney, AU", "country": - "au", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-iad", "label": "Washington, DC", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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-ord", "label": "Chicago, IL", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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": "fr-par", "label": "Paris, FR", "country": - "fr", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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-sea", "label": "Seattle, WA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": - "br", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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": "nl-ams", "label": "Amsterdam, NL", "country": - "nl", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "se-sto", "label": "Stockholm, SE", "country": - "se", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "es-mad", "label": "Madrid, ES", "country": - "es", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "in-maa", "label": "Chennai, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "jp-osa", "label": "Osaka, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "it-mil", "label": "Milan, IT", "country": - "it", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-mia", "label": "Miami, FL", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "id-cgk", "label": "Jakarta, ID", "country": - "id", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "us-lax", "label": "Los Angeles, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "nz-akl-1", "label": "Auckland, NZ", "country": - "nz", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": - "us", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", - "country": "de", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "fr-mrs-1", "label": "Marseille, FR", - "country": "fr", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, - ZA", "country": "za", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, - MY", "country": "my", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", - "country": "co", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, - MX", "country": "mx", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", - "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", - "country": "cl", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": - "gb", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": - "au", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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": "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": "de-fra-2", "label": "Frankfurt 2, DE", "country": - "de", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "NETINT Quadra T1U", "Linode Interfaces"], - "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": "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": "sg-sin-2", "label": "Singapore 2, SG", "country": - "sg", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "jp-tyo-3", "label": "Tokyo 3, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "de-ber-1", "label": "Berlin, DE", "country": - "de", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-central", "label": "Dallas, TX", - "country": "us", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group", "StackScripts", "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "us-west", "label": "Fremont, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": - ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group", "StackScripts", "Linode Interfaces"], "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", + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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,173.255.225.5,66.228.35.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": "eu-west", "label": "London, UK", "country": - "gb", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Linode - Interfaces"], "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": null, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", "label": - "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": - "de", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country": - "jp", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 42}' + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -348,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:22:55 GMT + - Wed, 06 May 2026 01:49:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -367,7 +498,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -386,7 +517,7 @@ interactions: url: https://api.linode.com/v4beta/lke/tiers/standard/versions?page=1 method: GET response: - body: '{"data": [{"id": "1.32", "tier": "standard"}, {"id": "1.31", "tier": "standard"}], + body: '{"data": [{"id": "1.35", "tier": "standard"}, {"id": "1.34", "tier": "standard"}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: @@ -412,7 +543,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:22:55 GMT + - Wed, 06 May 2026 01:49:41 GMT Pragma: - no-cache Strict-Transport-Security: @@ -435,7 +566,7 @@ interactions: code: 200 duration: "" - request: - body: '{"node_pools":[{"count":1,"type":"g6-standard-2","disks":null,"tags":["test"],"labels":null,"taints":null}],"label":"go-test-def","region":"ap-west","k8s_version":"1.32","tags":["testing"],"control_plane":{"acl":{"enabled":true,"addresses":{"ipv4":["10.0.0.1/32"],"ipv6":["1234::5678"]}}},"tier":"standard"}' + body: '{"node_pools":[{"count":1,"type":"g6-standard-2","disks":null,"tags":["test"],"labels":null,"taints":null}],"label":"go-test-def","region":"au-mel","k8s_version":"1.35","tags":["testing"],"control_plane":{"acl":{"enabled":true,"addresses":{"ipv4":["10.0.0.1/32"],"ipv6":["1234::5678"]}}},"tier":"standard"}' form: {} headers: Accept: @@ -447,10 +578,10 @@ interactions: url: https://api.linode.com/v4beta/lke/clusters method: POST response: - body: '{"id": 444268, "status": "ready", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "label": "go-test-def", "region": "ap-west", "k8s_version": - "1.32", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": - false, "tags": ["testing"]}' + body: '{"id": 600208, "status": "ready", "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "label": "go-test-def", "region": "au-mel", "k8s_version": + "1.35", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": + false, "tags": ["testing"], "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -469,13 +600,13 @@ interactions: Connection: - keep-alive Content-Length: - - "279" + - "291" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:23:07 GMT + - Wed, 06 May 2026 01:49:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -492,7 +623,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -508,10 +639,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/444268/control_plane_acl + url: https://api.linode.com/v4beta/lke/clusters/600208/control_plane_acl method: GET response: - body: '{"acl": {"enabled": true, "revision-id": "8caa3c9d3da6426abcb99afde35e50b8", + body: '{"acl": {"enabled": true, "revision-id": "92be28fe966846a18e9af955d0237c95", "addresses": {"ipv4": ["10.0.0.1/32"], "ipv6": ["1234::5678/128"]}}}' headers: Access-Control-Allow-Credentials: @@ -537,7 +668,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:23:08 GMT + - Wed, 06 May 2026 01:49:49 GMT Pragma: - no-cache Strict-Transport-Security: @@ -555,7 +686,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -571,7 +702,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/444268/control_plane_acl + url: https://api.linode.com/v4beta/lke/clusters/600208/control_plane_acl method: PUT response: body: '{"acl": {"enabled": true, "revision-id": "test-revision-id", "addresses": @@ -600,7 +731,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:23:12 GMT + - Wed, 06 May 2026 01:49:52 GMT Pragma: - no-cache Strict-Transport-Security: @@ -617,7 +748,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -633,7 +764,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/444268/control_plane_acl + url: https://api.linode.com/v4beta/lke/clusters/600208/control_plane_acl method: DELETE response: body: '{}' @@ -661,7 +792,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:23:15 GMT + - Wed, 06 May 2026 01:49:54 GMT Pragma: - no-cache Strict-Transport-Security: @@ -678,7 +809,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -694,7 +825,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/444268/control_plane_acl + url: https://api.linode.com/v4beta/lke/clusters/600208/control_plane_acl method: GET response: body: '{"acl": {"enabled": false, "addresses": {"ipv4": [], "ipv6": []}}}' @@ -722,7 +853,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:23:16 GMT + - Wed, 06 May 2026 01:49:55 GMT Pragma: - no-cache Strict-Transport-Security: @@ -740,7 +871,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -756,7 +887,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/444268 + url: https://api.linode.com/v4beta/lke/clusters/600208 method: DELETE response: body: '{}' @@ -784,7 +915,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 19 May 2025 16:23:20 GMT + - Wed, 06 May 2026 01:49:59 GMT Pragma: - no-cache Strict-Transport-Security: @@ -801,7 +932,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "1600" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestLKENodePool_Update.yaml b/test/integration/fixtures/TestLKENodePool_Update.yaml index 1492f6290..2df1d8d99 100644 --- a/test/integration/fixtures/TestLKENodePool_Update.yaml +++ b/test/integration/fixtures/TestLKENodePool_Update.yaml @@ -17,165 +17,157 @@ interactions: body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", - "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", - "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", - "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", - "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-mia", - "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", - "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "gb-lon", - "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", - "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "no-osl-1", - "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", @@ -184,33 +176,51 @@ interactions: 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", "Premium Plans", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", - "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": "ok", - "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", - "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", @@ -219,8 +229,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", @@ -229,8 +239,8 @@ interactions: "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", @@ -247,10 +257,10 @@ interactions: "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": @@ -258,21 +268,21 @@ interactions: "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": @@ -280,32 +290,98 @@ interactions: "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", @@ -313,9 +389,9 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", @@ -324,8 +400,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", @@ -333,8 +409,8 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": [], "metrics": - ["NodeBalancers"]}, "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", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", @@ -342,20 +418,20 @@ interactions: Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces"], "monitors": {"alerts": [], "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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,173.255.225.5,66.228.35.5", + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", @@ -364,8 +440,8 @@ interactions: "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": - {"alerts": ["Managed Databases"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", @@ -373,14 +449,14 @@ interactions: Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases"], - "metrics": ["Managed Databases", "NodeBalancers"]}, "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": + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 34}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -403,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:18:42 GMT + - Wed, 06 May 2026 02:20:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -441,17 +517,8 @@ interactions: url: https://api.linode.com/v4beta/lke/tiers/standard/versions?page=1 method: GET response: - body: '{"data": [{"id": "1.35", "tier": "standard"}, {"id": "1.34", "tier": "standard"}, - {"id": "1.33", "tier": "standard"}, {"id": "1.32", "tier": "standard"}, {"id": - "1.31", "tier": "standard"}, {"id": "1.30", "tier": "standard"}, {"id": "1.29", - "tier": "standard"}, {"id": "1.28", "tier": "standard"}, {"id": "1.27", "tier": - "standard"}, {"id": "1.26", "tier": "standard"}, {"id": "1.25", "tier": "standard"}, - {"id": "1.24", "tier": "standard"}, {"id": "1.23", "tier": "standard"}, {"id": - "1.22", "tier": "standard"}, {"id": "1.21", "tier": "standard"}, {"id": "1.20", - "tier": "standard"}, {"id": "1.19", "tier": "standard"}, {"id": "1.18", "tier": - "standard"}, {"id": "1.17", "tier": "standard"}, {"id": "1.15", "tier": "standard"}, - {"id": "1.16", "tier": "standard"}, {"id": "1.14", "tier": "standard"}, {"id": - "1.13", "tier": "standard"}], "page": 1, "pages": 1, "results": 23}' + body: '{"data": [{"id": "1.35", "tier": "standard"}, {"id": "1.34", "tier": "standard"}], + "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -469,12 +536,14 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive + Content-Length: + - "119" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:18:42 GMT + - Wed, 06 May 2026 02:20:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -482,7 +551,6 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter - - Accept-Encoding X-Accepted-Oauth-Scopes: - lke:read_only X-Content-Type-Options: @@ -510,7 +578,7 @@ interactions: url: https://api.linode.com/v4beta/lke/clusters method: POST response: - body: '{"id": 584698, "status": "ready", "created": "2018-01-02T03:04:05", "updated": + body: '{"id": 600212, "status": "ready", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "label": "go-lke-test-def", "region": "au-mel", "k8s_version": "1.35", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": false, "tags": ["testing"], "locks": []}' @@ -538,7 +606,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:18:50 GMT + - Wed, 06 May 2026 02:20:28 GMT Pragma: - no-cache Strict-Transport-Security: @@ -571,12 +639,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/584698/pools + url: https://api.linode.com/v4beta/lke/clusters/600212/pools method: POST response: - body: '{"id": 855505, "type": "g6-standard-2", "label": "", "count": 2, "nodes": - [{"id": "855505-03c5d1140000", "instance_id": 94907209, "status": "not_ready"}, - {"id": "855505-3b671b360000", "instance_id": null, "status": "not_ready"}], + body: '{"id": 880477, "type": "g6-standard-2", "label": "", "count": 2, "nodes": + [{"id": "880477-07c1ed2b0000", "instance_id": 97190708, "status": "not_ready"}, + {"id": "880477-082adf5a0000", "instance_id": null, "status": "not_ready"}], "disks": [{"size": 1000, "type": "ext4"}], "autoscaler": {"enabled": false, "min": 2, "max": 2}, "labels": {}, "taints": [], "tags": ["testing"], "disk_encryption": "enabled", "locks": []}' @@ -604,7 +672,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:18:52 GMT + - Wed, 06 May 2026 02:20:30 GMT Pragma: - no-cache Strict-Transport-Security: @@ -637,12 +705,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/584698/pools/855505 + url: https://api.linode.com/v4beta/lke/clusters/600212/pools/880477 method: PUT response: - body: '{"id": 855505, "type": "g6-standard-2", "label": "", "count": 2, "nodes": - [{"id": "855505-03c5d1140000", "instance_id": 94907209, "status": "not_ready"}, - {"id": "855505-3b671b360000", "instance_id": null, "status": "not_ready"}], + body: '{"id": 880477, "type": "g6-standard-2", "label": "", "count": 2, "nodes": + [{"id": "880477-07c1ed2b0000", "instance_id": 97190708, "status": "not_ready"}, + {"id": "880477-082adf5a0000", "instance_id": 97190709, "status": "not_ready"}], "disks": [{"size": 1000, "type": "ext4"}], "autoscaler": {"enabled": true, "min": 2, "max": 5}, "labels": {}, "taints": [], "tags": [], "disk_encryption": "enabled", "locks": []}' @@ -664,13 +732,13 @@ interactions: Connection: - keep-alive Content-Length: - - "408" + - "412" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:18:54 GMT + - Wed, 06 May 2026 02:20:32 GMT Pragma: - no-cache Strict-Transport-Security: @@ -703,13 +771,13 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/584698/pools/855505 + url: https://api.linode.com/v4beta/lke/clusters/600212/pools/880477 method: PUT response: - body: '{"id": 855505, "type": "g6-standard-2", "label": "", "count": 3, "nodes": - [{"id": "855505-03c5d1140000", "instance_id": 94907209, "status": "not_ready"}, - {"id": "855505-242f20850000", "instance_id": 94907215, "status": "not_ready"}, - {"id": "855505-3b671b360000", "instance_id": 94907213, "status": "not_ready"}], + body: '{"id": 880477, "type": "g6-standard-2", "label": "", "count": 3, "nodes": + [{"id": "880477-07c1ed2b0000", "instance_id": 97190708, "status": "not_ready"}, + {"id": "880477-082adf5a0000", "instance_id": 97190709, "status": "not_ready"}, + {"id": "880477-2286c1820000", "instance_id": 97190711, "status": "not_ready"}], "disks": [{"size": 1000, "type": "ext4"}], "autoscaler": {"enabled": true, "min": 2, "max": 5}, "labels": {"foo": "bar"}, "taints": [{"key": "foo", "value": "bar", "effect": "NoSchedule"}], "tags": ["bar", "foo", "test"], "disk_encryption": @@ -738,7 +806,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:18:57 GMT + - Wed, 06 May 2026 02:20:36 GMT Pragma: - no-cache Strict-Transport-Security: @@ -771,7 +839,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/584698/pools/855505 + url: https://api.linode.com/v4beta/lke/clusters/600212/pools/880477 method: DELETE response: body: '{}' @@ -799,7 +867,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:19:00 GMT + - Wed, 06 May 2026 02:20:38 GMT Pragma: - no-cache Strict-Transport-Security: @@ -832,7 +900,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/lke/clusters/584698 + url: https://api.linode.com/v4beta/lke/clusters/600212 method: DELETE response: body: '{}' @@ -860,7 +928,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 26 Mar 2026 19:19:04 GMT + - Wed, 06 May 2026 02:20:42 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestObjectStorageKey_List.yaml b/test/integration/fixtures/TestObjectStorageKey_List.yaml index 7d1eb9587..62a719490 100644 --- a/test/integration/fixtures/TestObjectStorageKey_List.yaml +++ b/test/integration/fixtures/TestObjectStorageKey_List.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 3498036, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3573414, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, @@ -59,7 +59,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:12 GMT + - Wed, 06 May 2026 02:22:10 GMT Pragma: - no-cache Strict-Transport-Security: @@ -96,8 +96,8 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys?page=1 method: GET response: - body: '{"pages": 1, "page": 1, "results": 1, "data": [{"id": 3498036, "label": - "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[REDACTED]", "limited": + body: '{"pages": 1, "page": 1, "results": 2, "data": [{"id": 3513975, "label": + "go-test-def_r", "access_key": "[SANITIZED]", "secret_key": "[REDACTED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "es-mad", "s3_endpoint": @@ -118,7 +118,30 @@ interactions: "us-ord-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", "endpoint_type": "E1"}, {"id": "us-southeast", - "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}]}' + "s3_endpoint": "us-southeast-1.linodeobjects.com", "endpoint_type": "E0"}]}, + {"id": 3573414, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + "[REDACTED]", "limited": false, "bucket_access": null, "regions": [{"id": "ap-south", + "s3_endpoint": "ap-south-1.linodeobjects.com", "endpoint_type": "E0"}, {"id": + "br-gru", "s3_endpoint": "br-gru-1.linodeobjects.com", "endpoint_type": "E1"}, + {"id": "es-mad", "s3_endpoint": "es-mad-1.linodeobjects.com", "endpoint_type": + "E1"}, {"id": "eu-central", "s3_endpoint": "eu-central-1.linodeobjects.com", + "endpoint_type": "E0"}, {"id": "fr-par", "s3_endpoint": "fr-par-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "id-cgk", "s3_endpoint": "id-cgk-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "in-maa", "s3_endpoint": "in-maa-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "it-mil", "s3_endpoint": "it-mil-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "jp-osa", "s3_endpoint": "jp-osa-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "nl-ams", "s3_endpoint": "nl-ams-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "se-sto", "s3_endpoint": "se-sto-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-east", "s3_endpoint": "us-east-1.linodeobjects.com", + "endpoint_type": "E0"}, {"id": "us-iad", "s3_endpoint": "us-iad-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-lax", "s3_endpoint": "us-lax-4.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-mia", "s3_endpoint": "us-mia-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-ord", "s3_endpoint": "us-ord-10.linodeobjects.com", + "endpoint_type": "E3"}, {"id": "us-sea", "s3_endpoint": "us-sea-1.linodeobjects.com", + "endpoint_type": "E1"}, {"id": "us-southeast", "s3_endpoint": "us-southeast-1.linodeobjects.com", + "endpoint_type": "E0"}]}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -141,7 +164,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:13 GMT + - Wed, 06 May 2026 02:22:10 GMT Pragma: - no-cache Strict-Transport-Security: @@ -176,7 +199,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/3498036 + url: https://api.linode.com/v4beta/object-storage/keys/3573414 method: DELETE response: body: '{}' @@ -204,7 +227,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:15 GMT + - Wed, 06 May 2026 02:22:11 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml b/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml index bc2b65b14..ff1b13a76 100644 --- a/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml +++ b/test/integration/fixtures/TestObjectStorageKeys_Limited.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 3498038, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3573416, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": true, "bucket_access": [{"cluster": "us-east-1", "bucket_name": "go-bucket-test-def", "permissions": "read_only", "region": "us-east"}, {"cluster": "us-east-1", "bucket_name": "go-bucket-test-def", "permissions": "read_write", @@ -44,7 +44,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:20 GMT + - Wed, 06 May 2026 02:22:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -77,7 +77,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/3498038 + url: https://api.linode.com/v4beta/object-storage/keys/3573416 method: DELETE response: body: '{}' @@ -105,7 +105,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:21 GMT + - Wed, 06 May 2026 02:22:19 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml b/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml index 59b573519..383843d17 100644 --- a/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml +++ b/test/integration/fixtures/TestObjectStorageKeys_Limited_Bucket.yaml @@ -42,7 +42,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:17 GMT + - Wed, 06 May 2026 02:22:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -103,7 +103,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:24 GMT + - Wed, 06 May 2026 02:22:23 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml b/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml index eec661585..d067a2ff3 100644 --- a/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml +++ b/test/integration/fixtures/TestObjectStorageKeys_Regional_Limited.yaml @@ -17,122 +17,109 @@ interactions: body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed - Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", - "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", - "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", - "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", - "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-mia", - "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "Block Storage - Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], - "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed - Databases", "NodeBalancers"]}, "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", + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", - "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", - "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "gb-lon", - "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", - "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": "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": @@ -140,44 +127,47 @@ interactions: "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", - "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", - "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": - ["Managed Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": - ["Managed Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "no-osl-1", - "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", "Block Storage - Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", @@ -186,8 +176,8 @@ interactions: 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC - Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", "Premium Plans", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", @@ -197,22 +187,40 @@ interactions: "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", "Metadata", - "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode - Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed - Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "status": "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": - 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", - "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block - Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", @@ -249,57 +257,121 @@ interactions: "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", - "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance - Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", - "NodeBalancers"]}, "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", + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": - ["Managed Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": - ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, - "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes - Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 - Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter - LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": - ["Managed Databases", "NodeBalancers"]}, "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", + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud - Firewall", "Vlans", "VPCs", "VPC Dual Stack", "VPC IPv6 Stack", "Managed Databases", + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", @@ -384,7 +456,7 @@ interactions: "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, "maximum_linodes_per_flexible_pg": - 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 34}' + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -407,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:24 GMT + - Wed, 06 May 2026 02:22:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -473,7 +545,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:31 GMT + - Wed, 06 May 2026 02:22:29 GMT Pragma: - no-cache Strict-Transport-Security: @@ -509,7 +581,7 @@ interactions: url: https://api.linode.com/v4beta/object-storage/keys method: POST response: - body: '{"id": 3498041, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3573417, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[SANITIZED]", "limited": true, "bucket_access": [{"cluster": "", "bucket_name": "go-bucket-test-defgo-test-def-regional", "permissions": "read_only", "region": "au-mel"}], "regions": [{"id": "au-mel", "s3_endpoint": "au-mel-1.linodeobjects.com", @@ -538,7 +610,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:37 GMT + - Wed, 06 May 2026 02:22:36 GMT Pragma: - no-cache Strict-Transport-Security: @@ -571,10 +643,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/3498041 + url: https://api.linode.com/v4beta/object-storage/keys/3573417 method: PUT response: - body: '{"id": 3498041, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": + body: '{"id": 3573417, "label": "go-test-def", "access_key": "[SANITIZED]", "secret_key": "[REDACTED]", "limited": true, "bucket_access": [{"cluster": "", "bucket_name": "go-bucket-test-defgo-test-def-regional", "permissions": "read_only", "region": "au-mel"}], "regions": [{"id": "au-mel", "s3_endpoint": "au-mel-1.linodeobjects.com", @@ -604,7 +676,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:41 GMT + - Wed, 06 May 2026 02:22:39 GMT Pragma: - no-cache Strict-Transport-Security: @@ -637,7 +709,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/keys/3498041 + url: https://api.linode.com/v4beta/object-storage/keys/3573417 method: DELETE response: body: '{}' @@ -665,7 +737,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:44 GMT + - Wed, 06 May 2026 02:22:42 GMT Pragma: - no-cache Strict-Transport-Security: @@ -726,7 +798,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:19:51 GMT + - Wed, 06 May 2026 02:22:51 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestTag_Create.yaml b/test/integration/fixtures/TestTag_Create.yaml index 0e1459ccf..06d4852cd 100644 --- a/test/integration/fixtures/TestTag_Create.yaml +++ b/test/integration/fixtures/TestTag_Create.yaml @@ -14,265 +14,449 @@ interactions: url: https://api.linode.com/v4beta/regions?page=1 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, - 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": - "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": - "core"}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": - ["Linodes", "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "VPCs", "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": - {"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", "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", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Metadata", "Premium Plans", "Placement + Group", "StackScripts", "Maintenance Policy"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "", "ipv6": + ""}, "placement_group_limits": {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "co-bog-2", + "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "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": - ["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"}, "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", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "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", - "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": - ["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", "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": - "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": 100, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": - "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "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": "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": - "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "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": "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", "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": - 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", "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": - 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", + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "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}' + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -295,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:07 GMT + - Wed, 06 May 2026 02:21:18 GMT Pragma: - no-cache Strict-Transport-Security: @@ -314,14 +498,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-ins-test-tag","tags":["go-tag-test"]}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-ins-test-tag","tags":["go-tag-test"]}' form: {} headers: Accept: @@ -333,16 +517,20 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61338609, "label": "go-ins-test-tag", "group": "", "status": "provisioning", + body: '{"id": 97190737, "label": "go-ins-test-tag", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "type": - "g6-nanode-1", "ipv4": ["172.105.33.33"], "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": + "g6-nanode-1", "ipv4": ["172.237.224.9"], "ipv6": "1234::5678/128", + "image": null, "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, + "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": ["go-tag-test"], - "host_uuid": "7c02d8248cd598c0fbe8286e88e0299137474f35", "has_user_data": false, - "placement_group": null, "lke_cluster_id": null}' + "host_uuid": "2048da2cf8f9a3f121e2eadb96aa0a5137cbebef", "has_user_data": false, + "placement_group": null, "disk_encryption": "enabled", "lke_cluster_id": null, + "capabilities": ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], + "interface_generation": "legacy_config", "maintenance_policy": "linode/migrate", + "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -360,20 +548,19 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "781" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:07 GMT + - Wed, 06 May 2026 02:21: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: @@ -384,14 +571,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "10" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"go-ins-test-tag","alerts":{"cpu":90,"io":10000,"network_in":10,"network_out":10,"transfer_quota":80},"watchdog_enabled":true,"tags":["go-tag-test","go-tag-test-bar"],"group":""}' + body: '{"label":"go-ins-test-tag","alerts":{"cpu":90,"io":10000,"network_in":10,"network_out":10,"transfer_quota":80},"watchdog_enabled":true,"tags":["go-tag-test","go-tag-test-bar"],"maintenance_policy":"linode/migrate"}' form: {} headers: Accept: @@ -400,19 +587,23 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61338609 + url: https://api.linode.com/v4beta/linode/instances/97190737 method: PUT response: - body: '{"id": 61338609, "label": "go-ins-test-tag", "group": "", "status": "provisioning", + body: '{"id": 97190737, "label": "go-ins-test-tag", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "type": - "g6-nanode-1", "ipv4": ["172.105.33.33"], "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": "Scheduling", "window": "Scheduling"}, - "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": - ["go-tag-test", "go-tag-test-bar"], "host_uuid": "7c02d8248cd598c0fbe8286e88e0299137474f35", - "has_user_data": false, "placement_group": null, "lke_cluster_id": null}' + "g6-nanode-1", "ipv4": ["172.237.224.9"], "ipv6": "1234::5678/128", + "image": null, "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, + "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": ["go-tag-test", + "go-tag-test-bar"], "host_uuid": "2048da2cf8f9a3f121e2eadb96aa0a5137cbebef", + "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", + "lke_cluster_id": null, "capabilities": ["Block Storage Encryption", "SMTP Enabled", + "Maintenance Policy"], "interface_generation": "legacy_config", "maintenance_policy": + "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -430,20 +621,19 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "816" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:07 GMT + - Wed, 06 May 2026 02:21: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: @@ -454,14 +644,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"go-tag-test-foo","linodes":[61338609]}' + body: '{"label":"go-tag-test-foo","linodes":[97190737]}' form: {} headers: Accept: @@ -498,7 +688,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:07 GMT + - Wed, 06 May 2026 02:21:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -515,7 +705,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -534,11 +724,19 @@ interactions: url: https://api.linode.com/v4beta/tags?page=1 method: GET response: - body: '{"data": [{"label": "1720017781112637000-tag"}, {"label": "1720034737644008000-tag"}, - {"label": "1720036462525806000-tag"}, {"label": "1720187490628487000-tag"}, - {"label": "1720191694198091000-tag"}, {"label": "1720193251044123000-tag"}, - {"label": "go-tag-test"}, {"label": "go-tag-test-bar"}, {"label": "go-tag-test-foo"}], - "page": 1, "pages": 1, "results": 9}' + body: '{"data": [{"label": "bar"}, {"label": "cool"}, {"label": "cooler"}, {"label": + "foo"}, {"label": "go-tag-test"}, {"label": "go-tag-test-bar"}, {"label": "go-tag-test-foo"}, + {"label": "linuke-keep"}, {"label": "test"}, {"label": "test1"}, {"label": "test2"}, + {"label": "test3"}, {"label": "test4"}, {"label": "test5"}, {"label": "test6"}, + {"label": "test=true"}, {"label": "testing"}, {"label": "tf_test"}, {"label": + "tf_test-2820816664991140163"}, {"label": "tf_test-2820816664991140163-0"}, + {"label": "tf_test-2820816664991140163-1"}, {"label": "tf_test-2820816664991140163-2"}, + {"label": "tf_test-7201639259805312086"}, {"label": "tf_test-7201639259805312086-0"}, + {"label": "tf_test-7201639259805312086-1"}, {"label": "tf_test-7201639259805312086-2"}, + {"label": "tf_test-8869206596896669974"}, {"label": "tf_test-8869206596896669974-0"}, + {"label": "tf_test-8869206596896669974-1"}, {"label": "tf_test-8869206596896669974-2"}, + {"label": "tf_test_2"}, {"label": "tf_test_updated"}], "page": 1, "pages": 1, + "results": 32}' headers: Access-Control-Allow-Credentials: - "true" @@ -556,14 +754,12 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "361" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:08 GMT + - Wed, 06 May 2026 02:21:22 GMT Pragma: - no-cache Strict-Transport-Security: @@ -571,6 +767,7 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - account:read_only X-Content-Type-Options: @@ -581,7 +778,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -601,16 +798,20 @@ interactions: method: GET response: body: '{"page": 1, "pages": 1, "results": 1, "data": [{"type": "linode", "data": - {"id": 61338609, "label": "go-ins-test-tag", "group": "", "status": "provisioning", + {"id": 97190737, "label": "go-ins-test-tag", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "type": - "g6-nanode-1", "ipv4": ["172.105.33.33"], "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": "Scheduling", "window": "Scheduling"}, - "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": - ["go-tag-test", "go-tag-test-bar", "go-tag-test-foo"], "host_uuid": "7c02d8248cd598c0fbe8286e88e0299137474f35", - "has_user_data": false, "placement_group": null, "lke_cluster_id": null}}]}' + "g6-nanode-1", "ipv4": ["172.237.224.9"], "ipv6": "1234::5678/128", + "image": null, "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, + "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": ["go-tag-test", + "go-tag-test-bar", "go-tag-test-foo"], "host_uuid": "2048da2cf8f9a3f121e2eadb96aa0a5137cbebef", + "has_user_data": false, "placement_group": null, "disk_encryption": "enabled", + "lke_cluster_id": null, "capabilities": ["Block Storage Encryption", "SMTP Enabled", + "Maintenance Policy"], "interface_generation": "legacy_config", "maintenance_policy": + "linode/migrate", "locks": []}}]}' headers: Access-Control-Allow-Credentials: - "true" @@ -633,7 +834,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:08 GMT + - Wed, 06 May 2026 02:21:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -652,7 +853,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -696,7 +897,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:08 GMT + - Wed, 06 May 2026 02:21:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -713,7 +914,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -757,7 +958,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:08 GMT + - Wed, 06 May 2026 02:21:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -774,7 +975,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -818,7 +1019,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:08 GMT + - Wed, 06 May 2026 02:21:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -835,7 +1036,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -851,7 +1052,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61338609 + url: https://api.linode.com/v4beta/linode/instances/97190737 method: DELETE response: body: '{}' @@ -879,7 +1080,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 11 Jul 2024 18:29:09 GMT + - Wed, 06 May 2026 02:21:24 GMT Pragma: - no-cache Strict-Transport-Security: @@ -896,7 +1097,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/images_test.go b/test/integration/images_test.go index 8abb13c75..88a012300 100644 --- a/test/integration/images_test.go +++ b/test/integration/images_test.go @@ -115,7 +115,7 @@ func TestImage_CreateUpload(t *testing.T) { Label: "linodego-image-create-upload", Description: "An image that does stuff.", CloudInit: true, - Tags: &[]string{"foo", "bar"}, + Tags: []string{"foo", "bar"}, }) if err != nil { t.Errorf("Failed to create image upload: %v", err) @@ -159,7 +159,7 @@ func TestImage_CloudInit(t *testing.T) { DiskID: instanceDisks[0].ID, Label: "linodego-test-cloud-init", CloudInit: true, - Tags: &[]string{"test1", "test2"}, + Tags: []string{"test1", "test2"}, }) if err != nil { t.Errorf("Failed to create image: %v", err) diff --git a/test/integration/instance_config_test.go b/test/integration/instance_config_test.go index 918ce153a..bb5f3f11b 100644 --- a/test/integration/instance_config_test.go +++ b/test/integration/instance_config_test.go @@ -577,7 +577,7 @@ func TestInstance_ConfigInterface_Update(t *testing.T) { NAT1To1: &NAT1To1Any, } newIPRanges := make([]string, 0) - updateOpts.IPRanges = &newIPRanges + updateOpts.IPRanges = newIPRanges updatedIntfc, err = client.UpdateInstanceConfigInterface( context.Background(), diff --git a/test/integration/instance_interfaces_test.go b/test/integration/instance_interfaces_test.go index fc63b7cb9..9641c884a 100644 --- a/test/integration/instance_interfaces_test.go +++ b/test/integration/instance_interfaces_test.go @@ -102,7 +102,7 @@ func TestInstance_CreateWithLinodeInterfaces( FirewallID: linodego.Pointer(firewallID), Public: &linodego.PublicInterfaceCreateOptions{ IPv4: &linodego.PublicInterfaceIPv4CreateOptions{ - Addresses: &[]linodego.PublicInterfaceIPv4AddressCreateOptions{ + Addresses: []linodego.PublicInterfaceIPv4AddressCreateOptions{ { Address: linodego.Pointer("auto"), Primary: linodego.Pointer(true), @@ -117,7 +117,7 @@ func TestInstance_CreateWithLinodeInterfaces( VPC: &linodego.VPCInterfaceCreateOptions{ SubnetID: vpcSubnet.ID, IPv4: &linodego.VPCInterfaceIPv4CreateOptions{ - Addresses: &[]linodego.VPCInterfaceIPv4AddressCreateOptions{ + Addresses: []linodego.VPCInterfaceIPv4AddressCreateOptions{ { Address: linodego.Pointer("auto"), Primary: linodego.Pointer(true), diff --git a/test/integration/lke_clusters_acl_test.go b/test/integration/lke_clusters_acl_test.go index 56cc254fd..dd99ca762 100644 --- a/test/integration/lke_clusters_acl_test.go +++ b/test/integration/lke_clusters_acl_test.go @@ -20,8 +20,8 @@ func TestLKECluster_withACL(t *testing.T) { ACL: &linodego.LKEClusterControlPlaneACLOptions{ Enabled: &valueTrue, Addresses: &linodego.LKEClusterControlPlaneACLAddressesOptions{ - IPv4: &[]string{"10.0.0.1/32"}, - IPv6: &[]string{"1234::5678"}, + IPv4: []string{"10.0.0.1/32"}, + IPv6: []string{"1234::5678"}, }, }, } @@ -48,8 +48,8 @@ func TestLKECluster_withACL(t *testing.T) { ACL: linodego.LKEClusterControlPlaneACLOptions{ Enabled: &valueTrue, Addresses: &linodego.LKEClusterControlPlaneACLAddressesOptions{ - IPv4: &[]string{"10.0.0.2/32"}, - IPv6: &[]string{}, + IPv4: []string{"10.0.0.2/32"}, + IPv6: []string{}, }, RevisionID: testRevisionID, }, diff --git a/test/integration/lke_clusters_test.go b/test/integration/lke_clusters_test.go index 6d52bdc23..d105e091a 100644 --- a/test/integration/lke_clusters_test.go +++ b/test/integration/lke_clusters_test.go @@ -128,7 +128,6 @@ func TestLKECluster_Enterprise_BYOVPC_smoke(t *testing.T) { func TestLKECluster_Update(t *testing.T) { client, cluster, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { createOpts.Label = "go-lke-test-update" - createOpts.K8sVersion = "1.31" }}, "fixtures/TestLKECluster_Update") defer teardown() if err != nil { @@ -137,12 +136,10 @@ func TestLKECluster_Update(t *testing.T) { updatedTags := []string{"test=true"} updatedLabel := cluster.Label + "-updated" - updatedK8sVersion := "1.32" updatedCluster, err := client.UpdateLKECluster(context.Background(), cluster.ID, linodego.LKEClusterUpdateOptions{ - Tags: &updatedTags, - Label: updatedLabel, - K8sVersion: updatedK8sVersion, + Tags: updatedTags, + Label: updatedLabel, }) if err != nil { t.Fatalf("failed to update LKE Cluster (%d): %s", cluster.ID, err) @@ -152,10 +149,6 @@ func TestLKECluster_Update(t *testing.T) { t.Errorf("expected label to be updated to %q; got %q", updatedLabel, updatedCluster.Label) } - if updatedCluster.K8sVersion != updatedK8sVersion { - t.Errorf("expected k8s version to be updated to %q; got %q", updatedK8sVersion, updatedCluster.K8sVersion) - } - if !reflect.DeepEqual(updatedTags, updatedCluster.Tags) { t.Errorf("expected tags to be updated to %#v; got %#v", updatedTags, updatedCluster.Tags) } diff --git a/test/integration/lke_node_pools_test.go b/test/integration/lke_node_pools_test.go index bea95820b..0349c4b46 100644 --- a/test/integration/lke_node_pools_test.go +++ b/test/integration/lke_node_pools_test.go @@ -207,8 +207,8 @@ func TestLKENodePool_Update(t *testing.T) { } updatedTags := []string{} updated, err := client.UpdateLKENodePool(context.TODO(), lkeCluster.ID, nodePool.ID, linodego.LKENodePoolUpdateOptions{ - Count: 2, // downsize - Tags: &updatedTags, // remove all tags + Count: 2, // downsize + Tags: updatedTags, // remove all tags Autoscaler: &updatedAutoscaler, }) if err != nil { @@ -237,9 +237,9 @@ func TestLKENodePool_Update(t *testing.T) { }} updated, err = client.UpdateLKENodePool(context.TODO(), lkeCluster.ID, nodePool.ID, linodego.LKENodePoolUpdateOptions{ Count: 3, // upsize - Tags: &updatedTags, // repopulate tags + Tags: updatedTags, // repopulate tags Labels: &updatedLabels, // set a label - Taints: &updatedTaints, // set a taint + Taints: updatedTaints, // set a taint }) if err != nil { t.Fatal(err) diff --git a/test/integration/main_test.go b/test/integration/main_test.go index 6f497ff13..979f34da5 100644 --- a/test/integration/main_test.go +++ b/test/integration/main_test.go @@ -82,7 +82,7 @@ func getDefaultFirewallRuleSet(publicIPv4 string) linodego.FirewallRuleSet { Action: "ACCEPT", Ports: "22", Protocol: "TCP", - Addresses: linodego.NetworkAddresses{IPv4: &[]string{publicIPv4}}, + Addresses: linodego.NetworkAddresses{IPv4: []string{publicIPv4}}, } return linodego.FirewallRuleSet{ diff --git a/test/integration/mysql_test.go b/test/integration/mysql_test.go index a873563e2..9d46bf23e 100644 --- a/test/integration/mysql_test.go +++ b/test/integration/mysql_test.go @@ -55,7 +55,7 @@ func TestDatabase_MySQL_Suite(t *testing.T) { updatedLabel := database.Label + "-updated" opts := linodego.MySQLUpdateOptions{ - AllowList: &allowList, + AllowList: allowList, Label: updatedLabel, Updates: &updatedWindow, } diff --git a/test/integration/object_storage_keys_test.go b/test/integration/object_storage_keys_test.go index 215353ec6..d7c586144 100644 --- a/test/integration/object_storage_keys_test.go +++ b/test/integration/object_storage_keys_test.go @@ -114,7 +114,7 @@ func TestObjectStorageKeys_Limited(t *testing.T) { defer teardown() createOpts := testBasicObjectStorageKeyCreateOpts - createOpts.BucketAccess = &[]ObjectStorageKeyBucketAccess{ + createOpts.BucketAccess = []ObjectStorageKeyBucketAccess{ { Region: "us-east", BucketName: bucket.Label, @@ -132,11 +132,11 @@ func TestObjectStorageKeys_Limited(t *testing.T) { if err != nil { t.Error(err) } - if !objectStorageKey.Limited || !cmp.Equal(objectStorageKey.BucketAccess, createOpts.BucketAccess) { + if !objectStorageKey.Limited || !cmp.Equal(*objectStorageKey.BucketAccess, createOpts.BucketAccess) { t.Errorf( "objectStorageKey returned (%v) does not match objectStorageKey creation request (%v)", *objectStorageKey.BucketAccess, - *createOpts.BucketAccess, + createOpts.BucketAccess, ) } } @@ -145,7 +145,7 @@ func TestObjectStorageKeys_Limited_NoAccess(t *testing.T) { t.Skip("skipping test due to unexpected API behavior with limited object storage keys") createOpts := testBasicObjectStorageKeyCreateOpts - createOpts.BucketAccess = &[]ObjectStorageKeyBucketAccess{} + createOpts.BucketAccess = []ObjectStorageKeyBucketAccess{} _, objectStorageKey, teardown, err := setupObjectStorageKey(t, createOpts, "fixtures/TestObjectStorageKeys_Limited_NoAccess", nil, nil) defer teardown() @@ -178,7 +178,7 @@ func TestObjectStorageKeys_Regional_Limited(t *testing.T) { } createOpts := testBasicObjectStorageKeyCreateOpts - createOpts.BucketAccess = &[]ObjectStorageKeyBucketAccess{ + createOpts.BucketAccess = []ObjectStorageKeyBucketAccess{ { Region: region, BucketName: bucket.Label, diff --git a/test/integration/postgres_test.go b/test/integration/postgres_test.go index 150e09e65..55f17cc24 100644 --- a/test/integration/postgres_test.go +++ b/test/integration/postgres_test.go @@ -55,7 +55,7 @@ func TestDatabase_Postgres_Suite(t *testing.T) { updatedLabel := database.Label + "-updated" opts := linodego.PostgresUpdateOptions{ - AllowList: &allowList, + AllowList: allowList, Label: updatedLabel, Updates: &updatedWindow, } diff --git a/test/integration/tags_test.go b/test/integration/tags_test.go index b2dc748a2..1662747eb 100644 --- a/test/integration/tags_test.go +++ b/test/integration/tags_test.go @@ -19,11 +19,8 @@ func TestTag_Create_create_smoke(t *testing.T) { } updateOpts := instance.GetUpdateOptions() - if updateOpts.Tags == nil { - updateOpts.Tags = new([]string) - } - newTags := append(*updateOpts.Tags, "go-tag-test-bar") - updateOpts.Tags = &newTags + newTags := append(updateOpts.Tags, "go-tag-test-bar") + updateOpts.Tags = newTags updateOpts.Backups = nil instance, err = client.UpdateInstance(context.Background(), instance.ID, updateOpts) if err != nil { diff --git a/test/unit/firewall_rules_test.go b/test/unit/firewall_rules_test.go index 2e04f9f77..ded63bf89 100644 --- a/test/unit/firewall_rules_test.go +++ b/test/unit/firewall_rules_test.go @@ -34,8 +34,8 @@ func TestFirewallRule_Get(t *testing.T) { assert.Equal(t, "An example firewall rule description.", firewallRule.Inbound[0].Description) assert.Equal(t, "22-24, 80, 443", firewallRule.Inbound[0].Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), firewallRule.Inbound[0].Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *firewallRule.Inbound[0].Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *firewallRule.Inbound[0].Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, firewallRule.Inbound[0].Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, firewallRule.Inbound[0].Addresses.IPv6) assert.Equal(t, "DROP", firewallRule.OutboundPolicy) assert.Equal(t, 1, len(firewallRule.Outbound)) @@ -44,8 +44,8 @@ func TestFirewallRule_Get(t *testing.T) { assert.Equal(t, "An example firewall rule description.", firewallRule.Outbound[0].Description) assert.Equal(t, "22-24, 80, 443", firewallRule.Outbound[0].Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), firewallRule.Outbound[0].Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *firewallRule.Outbound[0].Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *firewallRule.Outbound[0].Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, firewallRule.Outbound[0].Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, firewallRule.Outbound[0].Addresses.IPv6) } func TestFirewallRule_MarshalJSON(t *testing.T) { @@ -61,7 +61,7 @@ func TestFirewallRule_MarshalJSON(t *testing.T) { Ports: "443", Protocol: linodego.NetworkProtocol("TCP"), Addresses: linodego.NetworkAddresses{ - IPv4: &ipv4, + IPv4: ipv4, }, } data, err = json.Marshal(ruleWithoutRuleset) @@ -95,8 +95,8 @@ func TestFirewallRule_Update(t *testing.T) { Ports: "22-24, 80, 443", Protocol: "TCP", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"192.0.2.0/24", "198.51.100.2/32"}, - IPv6: &[]string{"2001:DB8::/128"}, + IPv4: []string{"192.0.2.0/24", "198.51.100.2/32"}, + IPv6: []string{"2001:DB8::/128"}, }, }, }, @@ -109,8 +109,8 @@ func TestFirewallRule_Update(t *testing.T) { Ports: "22-24, 80, 443", Protocol: "TCP", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"192.0.2.0/24", "198.51.100.2/32"}, - IPv6: &[]string{"2001:DB8::/128"}, + IPv4: []string{"192.0.2.0/24", "198.51.100.2/32"}, + IPv6: []string{"2001:DB8::/128"}, }, }, }, @@ -131,8 +131,8 @@ func TestFirewallRule_Update(t *testing.T) { assert.Equal(t, "An example firewall rule description.", firewallRule.Inbound[0].Description) assert.Equal(t, "22-24, 80, 443", firewallRule.Inbound[0].Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), firewallRule.Inbound[0].Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *firewallRule.Inbound[0].Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *firewallRule.Inbound[0].Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, firewallRule.Inbound[0].Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, firewallRule.Inbound[0].Addresses.IPv6) assert.Equal(t, "DROP", firewallRule.OutboundPolicy) assert.Equal(t, 1, len(firewallRule.Outbound)) @@ -141,8 +141,8 @@ func TestFirewallRule_Update(t *testing.T) { assert.Equal(t, "An example firewall rule description.", firewallRule.Outbound[0].Description) assert.Equal(t, "22-24, 80, 443", firewallRule.Outbound[0].Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), firewallRule.Outbound[0].Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *firewallRule.Outbound[0].Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *firewallRule.Outbound[0].Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, firewallRule.Outbound[0].Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, firewallRule.Outbound[0].Addresses.IPv6) } func TestFirewallRule_GetExpansion(t *testing.T) { @@ -160,8 +160,8 @@ func TestFirewallRule_GetExpansion(t *testing.T) { Ports: "22", Protocol: linodego.NetworkProtocol("TCP"), Addresses: linodego.NetworkAddresses{ - IPv4: &inboundIPv4, - IPv6: &inboundIPv6, + IPv4: inboundIPv4, + IPv6: inboundIPv6, }, }, }, @@ -174,8 +174,8 @@ func TestFirewallRule_GetExpansion(t *testing.T) { Ports: "22", Protocol: linodego.NetworkProtocol("TCP"), Addresses: linodego.NetworkAddresses{ - IPv4: &outboundIPv4, - IPv6: &outboundIPv6, + IPv4: outboundIPv4, + IPv6: outboundIPv6, }, }, }, @@ -204,10 +204,10 @@ func TestFirewallRule_GetExpansion(t *testing.T) { assert.Equal(t, "22", firewallRuleSet.Inbound[0].Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), firewallRuleSet.Inbound[0].Protocol) if assert.NotNil(t, firewallRuleSet.Inbound[0].Addresses.IPv4) { - assert.ElementsMatch(t, []string{"pl::vpcs:1234"}, *firewallRuleSet.Inbound[0].Addresses.IPv4) + assert.ElementsMatch(t, []string{"pl::vpcs:1234"}, firewallRuleSet.Inbound[0].Addresses.IPv4) } if assert.NotNil(t, firewallRuleSet.Inbound[0].Addresses.IPv6) { - assert.ElementsMatch(t, []string{"pl::vpcs:"}, *firewallRuleSet.Inbound[0].Addresses.IPv6) + assert.ElementsMatch(t, []string{"pl::vpcs:"}, firewallRuleSet.Inbound[0].Addresses.IPv6) } } @@ -220,10 +220,10 @@ func TestFirewallRule_GetExpansion(t *testing.T) { assert.Equal(t, "22", firewallRuleSet.Outbound[0].Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), firewallRuleSet.Outbound[0].Protocol) if assert.NotNil(t, firewallRuleSet.Outbound[0].Addresses.IPv4) { - assert.ElementsMatch(t, []string{"pl::vpcs:1234"}, *firewallRuleSet.Outbound[0].Addresses.IPv4) + assert.ElementsMatch(t, []string{"pl::vpcs:1234"}, firewallRuleSet.Outbound[0].Addresses.IPv4) } if assert.NotNil(t, firewallRuleSet.Outbound[0].Addresses.IPv6) { - assert.ElementsMatch(t, []string{"pl::vpcs:"}, *firewallRuleSet.Outbound[0].Addresses.IPv6) + assert.ElementsMatch(t, []string{"pl::vpcs:"}, firewallRuleSet.Outbound[0].Addresses.IPv6) } } diff --git a/test/unit/firewall_rulesets_test.go b/test/unit/firewall_rulesets_test.go index 0d6992bad..5c069f900 100644 --- a/test/unit/firewall_rulesets_test.go +++ b/test/unit/firewall_rulesets_test.go @@ -65,10 +65,10 @@ func TestFirewallRuleSets_List(t *testing.T) { rule := rs.Rules[0] assert.Equal(t, "ACCEPT", rule.Action) if assert.NotNil(t, rule.Addresses.IPv4) { - assert.Equal(t, []string{"pl::vpcs:primary"}, *rule.Addresses.IPv4) + assert.Equal(t, []string{"pl::vpcs:primary"}, rule.Addresses.IPv4) } if assert.NotNil(t, rule.Addresses.IPv6) { - assert.Equal(t, []string{"pl::vpcs:primary"}, *rule.Addresses.IPv6) + assert.Equal(t, []string{"pl::vpcs:primary"}, rule.Addresses.IPv6) } if assert.NotNil(t, rs.Created) { @@ -132,7 +132,7 @@ func TestFirewallRuleSets_Create(t *testing.T) { { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"pl::vpcs:primary"}, + IPv4: []string{"pl::vpcs:primary"}, }, Label: "ingress", Protocol: linodego.NetworkProtocol("TCP"), @@ -181,7 +181,7 @@ func TestFirewallRuleSets_Update(t *testing.T) { { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ - IPv6: &[]string{"pl::system:obj-storage"}, + IPv6: []string{"pl::system:obj-storage"}, }, Label: "egress", Protocol: linodego.NetworkProtocol("UDP"), @@ -192,7 +192,7 @@ func TestFirewallRuleSets_Update(t *testing.T) { req := linodego.RuleSetUpdateOptions{ Label: &label, Description: &description, - Rules: &rules, + Rules: rules, } response := map[string]any{ diff --git a/test/unit/firewalls_test.go b/test/unit/firewalls_test.go index f2161d65e..e312334f4 100644 --- a/test/unit/firewalls_test.go +++ b/test/unit/firewalls_test.go @@ -48,8 +48,8 @@ func TestFirewall_List(t *testing.T) { assert.Equal(t, "ACCEPT", outboundRule.Action) assert.Equal(t, linodego.NetworkProtocol("TCP"), outboundRule.Protocol) assert.Equal(t, "22-24, 80, 443", outboundRule.Ports) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *outboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *outboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, outboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, outboundRule.Addresses.IPv6) assert.ElementsMatch(t, []string{"example tag", "another example"}, firewall.Tags) @@ -74,8 +74,8 @@ func TestFirewall_Create(t *testing.T) { { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"192.0.2.0/24", "198.51.100.2/32"}, - IPv6: &[]string{"2001:DB8::/128"}, + IPv4: []string{"192.0.2.0/24", "198.51.100.2/32"}, + IPv6: []string{"2001:DB8::/128"}, }, Description: "An example firewall rule description.", Label: "firewallrule123", @@ -87,8 +87,8 @@ func TestFirewall_Create(t *testing.T) { { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ - IPv4: &[]string{"192.0.2.0/24", "198.51.100.2/32"}, - IPv6: &[]string{"2001:DB8::/128"}, + IPv4: []string{"192.0.2.0/24", "198.51.100.2/32"}, + IPv6: []string{"2001:DB8::/128"}, }, Description: "An example firewall rule description.", Label: "firewallrule123", @@ -127,8 +127,8 @@ func TestFirewall_Create(t *testing.T) { assert.Equal(t, "An example firewall rule description.", inboundRule.Description) assert.Equal(t, "22-24, 80, 443", inboundRule.Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), inboundRule.Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *inboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *inboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, inboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, inboundRule.Addresses.IPv6) assert.Len(t, firewall.Rules.Outbound, 1) outboundRule := firewall.Rules.Outbound[0] @@ -137,8 +137,8 @@ func TestFirewall_Create(t *testing.T) { assert.Equal(t, "An example firewall rule description.", outboundRule.Description) assert.Equal(t, "22-24, 80, 443", outboundRule.Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), outboundRule.Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *outboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *outboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, outboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, outboundRule.Addresses.IPv6) assert.Len(t, firewall.Entities, 1) entity := firewall.Entities[0] @@ -188,8 +188,8 @@ func TestFirewall_Get(t *testing.T) { assert.Equal(t, "An example firewall rule description.", inboundRule.Description) assert.Equal(t, "22-24, 80, 443", inboundRule.Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), inboundRule.Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *inboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *inboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, inboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, inboundRule.Addresses.IPv6) assert.Len(t, firewall.Rules.Outbound, 1) outboundRule := firewall.Rules.Outbound[0] @@ -198,8 +198,8 @@ func TestFirewall_Get(t *testing.T) { assert.Equal(t, "An example firewall rule description.", outboundRule.Description) assert.Equal(t, "22-24, 80, 443", outboundRule.Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), outboundRule.Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *outboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *outboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, outboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, outboundRule.Addresses.IPv6) } func TestFirewall_Update(t *testing.T) { @@ -216,7 +216,7 @@ func TestFirewall_Update(t *testing.T) { requestData := linodego.FirewallUpdateOptions{ Label: "firewall123", Status: "enabled", - Tags: &[]string{"updated tag", "another updated tag"}, + Tags: []string{"updated tag", "another updated tag"}, } firewall, err := base.Client.UpdateFirewall(context.Background(), firewallID, requestData) @@ -242,8 +242,8 @@ func TestFirewall_Update(t *testing.T) { assert.Equal(t, "An example firewall rule description.", inboundRule.Description) assert.Equal(t, "22-24, 80, 443", inboundRule.Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), inboundRule.Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *inboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *inboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, inboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, inboundRule.Addresses.IPv6) assert.Len(t, firewall.Rules.Outbound, 1) outboundRule := firewall.Rules.Outbound[0] @@ -252,8 +252,8 @@ func TestFirewall_Update(t *testing.T) { assert.Equal(t, "An example firewall rule description.", outboundRule.Description) assert.Equal(t, "22-24, 80, 443", outboundRule.Ports) assert.Equal(t, linodego.NetworkProtocol("TCP"), outboundRule.Protocol) - assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, *outboundRule.Addresses.IPv4) - assert.ElementsMatch(t, []string{"2001:DB8::/128"}, *outboundRule.Addresses.IPv6) + assert.ElementsMatch(t, []string{"192.0.2.0/24", "198.51.100.2/32"}, outboundRule.Addresses.IPv4) + assert.ElementsMatch(t, []string{"2001:DB8::/128"}, outboundRule.Addresses.IPv6) } func TestFirewall_Delete(t *testing.T) { diff --git a/test/unit/images_test.go b/test/unit/images_test.go index e89cec8ef..4c1ccb894 100644 --- a/test/unit/images_test.go +++ b/test/unit/images_test.go @@ -178,7 +178,7 @@ func TestImage_Create(t *testing.T) { Label: "Debian 11", Description: "Example image description.", CloudInit: true, - Tags: &[]string{"repair-image", "fix-1"}, + Tags: []string{"repair-image", "fix-1"}, } base.MockPost("images", fixtureData) @@ -220,7 +220,7 @@ func TestImage_Update(t *testing.T) { requestData := linodego.ImageUpdateOptions{ Label: "Debian 11", Description: &desc, - Tags: &[]string{"repair-image", "fix-1"}, + Tags: []string{"repair-image", "fix-1"}, } imageID := "123" @@ -265,7 +265,7 @@ func TestImage_Upload(t *testing.T) { Label: "Debian 11", Description: "Example image description.", CloudInit: true, - Tags: &[]string{"repair-image", "fix-1"}, + Tags: []string{"repair-image", "fix-1"}, Image: strings.NewReader("mock image data"), } diff --git a/test/unit/instance_config_interfaces_test.go b/test/unit/instance_config_interfaces_test.go index c78f4e9a8..3a70384ae 100644 --- a/test/unit/instance_config_interfaces_test.go +++ b/test/unit/instance_config_interfaces_test.go @@ -114,7 +114,7 @@ func TestInstanceConfigInterface_Update(t *testing.T) { IPv4: &linodego.VPCIPv4{ NAT1To1: &nat1to1, }, - IPRanges: &ipRanges, + IPRanges: ipRanges, } base.MockPut("linode/instances/123/configs/456/interfaces/1", fixtureData) diff --git a/test/unit/interface_test.go b/test/unit/interface_test.go index fc407ff25..7a2f61b2e 100644 --- a/test/unit/interface_test.go +++ b/test/unit/interface_test.go @@ -158,7 +158,7 @@ func TestInterface_CreatePublic(t *testing.T) { opts := linodego.LinodeInterfaceCreateOptions{ Public: &linodego.PublicInterfaceCreateOptions{ IPv4: &linodego.PublicInterfaceIPv4CreateOptions{ - Addresses: &[]linodego.PublicInterfaceIPv4AddressCreateOptions{ + Addresses: []linodego.PublicInterfaceIPv4AddressCreateOptions{ { Address: linodego.Pointer("auto"), Primary: linodego.Pointer(true), @@ -227,13 +227,13 @@ func TestInterface_UpdateVPC(t *testing.T) { }, VPC: &linodego.VPCInterfaceUpdateOptions{ IPv4: &linodego.VPCInterfaceIPv4CreateOptions{ - Addresses: &[]linodego.VPCInterfaceIPv4AddressCreateOptions{ + Addresses: []linodego.VPCInterfaceIPv4AddressCreateOptions{ { Address: linodego.Pointer("192.168.23.4"), Primary: linodego.Pointer(true), }, }, - Ranges: &[]linodego.VPCInterfaceIPv4RangeCreateOptions{ + Ranges: []linodego.VPCInterfaceIPv4RangeCreateOptions{ { Range: "192.168.23.16/28", }, @@ -243,12 +243,12 @@ func TestInterface_UpdateVPC(t *testing.T) { }, }, IPv6: &linodego.VPCInterfaceIPv6CreateOptions{ - SLAAC: &[]linodego.VPCInterfaceIPv6SLAACCreateOptions{ + SLAAC: []linodego.VPCInterfaceIPv6SLAACCreateOptions{ { Range: "1235::/64", }, }, - Ranges: &[]linodego.VPCInterfaceIPv6RangeCreateOptions{ + Ranges: []linodego.VPCInterfaceIPv6RangeCreateOptions{ { Range: "4322::/64", }, diff --git a/test/unit/lke_cluster_control_plane_acl_test.go b/test/unit/lke_cluster_control_plane_acl_test.go index 06442ae29..934c64462 100644 --- a/test/unit/lke_cluster_control_plane_acl_test.go +++ b/test/unit/lke_cluster_control_plane_acl_test.go @@ -43,8 +43,8 @@ func TestLKEClusterControlPlaneACL_Update(t *testing.T) { Enabled: BoolToPtr(true), RevisionID: "rev-abc123", Addresses: &linodego.LKEClusterControlPlaneACLAddressesOptions{ - IPv4: &[]string{"10.0.0.1/32"}, - IPv6: &[]string{"2001:db8::/64"}, + IPv4: []string{"10.0.0.1/32"}, + IPv6: []string{"2001:db8::/64"}, }, }, } diff --git a/test/unit/lke_clusters_test.go b/test/unit/lke_clusters_test.go index 0dfad0d51..0a1a3fd21 100644 --- a/test/unit/lke_clusters_test.go +++ b/test/unit/lke_clusters_test.go @@ -131,7 +131,7 @@ func TestLKECluster_Update(t *testing.T) { updateOptions := linodego.LKEClusterUpdateOptions{ Label: "updated-cluster", - Tags: &[]string{"new-tag"}, + Tags: []string{"new-tag"}, ControlPlane: &linodego.LKEClusterControlPlaneOptions{ AuditLogsEnabled: linodego.Pointer(true), }, diff --git a/test/unit/lke_node_pools_test.go b/test/unit/lke_node_pools_test.go index c01b63670..f4b3a2572 100644 --- a/test/unit/lke_node_pools_test.go +++ b/test/unit/lke_node_pools_test.go @@ -125,7 +125,7 @@ func TestLKENodePool_Update(t *testing.T) { updateOptions := linodego.LKENodePoolUpdateOptions{ Count: 5, - Tags: &[]string{"updated-tag"}, + Tags: []string{"updated-tag"}, Labels: Ptr(linodego.LKENodePoolLabels{"env": "prod"}), Autoscaler: &linodego.LKENodePoolAutoscaler{ Enabled: true, diff --git a/test/unit/nodebalancer_test.go b/test/unit/nodebalancer_test.go index e78f7f2fb..9702fb901 100644 --- a/test/unit/nodebalancer_test.go +++ b/test/unit/nodebalancer_test.go @@ -130,7 +130,7 @@ func TestNodeBalancer_Update(t *testing.T) { label := "Updated NodeBalancer" updateOpts := linodego.NodeBalancerUpdateOptions{ Label: &label, - Tags: &[]string{"updated", "production"}, + Tags: []string{"updated", "production"}, } nodebalancer, err := base.Client.UpdateNodeBalancer(context.Background(), 123, updateOpts) assert.NoError(t, err) diff --git a/test/unit/volume_test.go b/test/unit/volume_test.go index 24d5f5b0a..a882bd18d 100644 --- a/test/unit/volume_test.go +++ b/test/unit/volume_test.go @@ -103,7 +103,7 @@ func TestUpdateVolume(t *testing.T) { opts := linodego.VolumeUpdateOptions{ Label: "updated-volume", - Tags: &[]string{"updated"}, + Tags: []string{"updated"}, } updatedVolume, err := base.Client.UpdateVolume(context.Background(), volumeID, opts) diff --git a/volumes.go b/volumes.go index b93d8976c..cd83e696c 100644 --- a/volumes.go +++ b/volumes.go @@ -59,8 +59,8 @@ type VolumeCreateOptions struct { // VolumeUpdateOptions fields are those accepted by UpdateVolume type VolumeUpdateOptions struct { - Label string `json:"label,omitzero"` - Tags *[]string `json:"tags,omitzero"` + Label string `json:"label,omitzero"` + Tags []string `json:"tags,omitzero"` } // VolumeAttachOptions fields are those accepted by AttachVolume @@ -96,7 +96,7 @@ func (v *Volume) UnmarshalJSON(b []byte) error { // GetUpdateOptions converts a Volume to VolumeUpdateOptions for use in UpdateVolume func (v Volume) GetUpdateOptions() (updateOpts VolumeUpdateOptions) { updateOpts.Label = v.Label - updateOpts.Tags = &v.Tags + updateOpts.Tags = v.Tags return updateOpts } From b45b4025daea8149d0c2a164eb430eab121011dd Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Wed, 6 May 2026 14:25:45 -0400 Subject: [PATCH 05/17] TPT-4434: Added custom type for Region Capabilities and updated tests (#953) * Added custom type for Region Capabilities and updated tests * Fix formatting --- regions.go | 101 +++++++++--------- test/integration/image_sharegroups_test.go | 2 +- test/integration/images_test.go | 7 +- test/integration/instance_config_test.go | 29 +++-- test/integration/instance_interfaces_test.go | 4 +- test/integration/instances_test.go | 28 +++-- test/integration/integration_suite_test.go | 10 +- test/integration/lke_clusters_test.go | 5 +- test/integration/mysql_test.go | 2 +- test/integration/nodebalancer_configs_test.go | 10 +- test/integration/nodebalancers_test.go | 2 +- test/integration/object_storage_keys_test.go | 2 +- test/integration/placement_group_test.go | 2 +- test/integration/postgres_test.go | 2 +- test/integration/tags_test.go | 3 +- test/integration/vlans_test.go | 2 +- test/integration/volumes_test.go | 20 ++-- test/integration/vpc_subnet_test.go | 14 ++- test/integration/vpc_test.go | 4 +- test/integration/waitfor_test.go | 6 +- test/unit/region_test.go | 4 +- 21 files changed, 153 insertions(+), 106 deletions(-) diff --git a/regions.go b/regions.go index ad0a0a2ba..b049cc1a5 100644 --- a/regions.go +++ b/regions.go @@ -5,59 +5,60 @@ import ( "time" ) +// RegionCapability constants start with Capability and include all known Linode region capabilities. +type RegionCapability string + // This is an enumeration of Capabilities Linode offers that can be referenced // through the user-facing parts of the application. -// Defined as strings rather than a custom type to avoid breaking change. -// Can be changed in the potential v2 version. const ( - CapabilityACLB string = "Akamai Cloud Load Balancer" - CapabilityACLP string = "Akamai Cloud Pulse" - CapabilityACLPStreams string = "Akamai Cloud Pulse Streams" - CapabilityAkamaiRAMProtection string = "Akamai RAM Protection" - CapabilityBackups string = "Backups" - CapabilityBlockStorage string = "Block Storage" - CapabilityBlockStorageEncryption string = "Block Storage Encryption" - CapabilityBlockStorageMigrations string = "Block Storage Migrations" - CapabilityBlockStoragePerformanceB1 string = "Block Storage Performance B1" - CapabilityBlockStoragePerformanceB1Default string = "Block Storage Performance B1 Default" - CapabilityCloudFirewall string = "Cloud Firewall" - CapabilityCloudFirewallRuleSet string = "Cloud Firewall Rule Set" - CapabilityCloudNAT string = "Cloud NAT" - CapabilityDBAAS string = "Managed Databases" - CapabilityDBAASBeta string = "Managed Databases Beta" - CapabilityDiskEncryption string = "Disk Encryption" - CapabilityDistributedPlans string = "Distributed Plans" - CapabilityEdgePlans string = "Edge Plans" - CapabilityGPU string = "GPU Linodes" - CapabilityKubernetesEnterprise string = "Kubernetes Enterprise" - CapabilityKubernetesEnterpriseBYOVPC string = "Kubernetes Enterprise BYO VPC" - CapabilityKubernetesEnterpriseDualStack string = "Kubernetes Enterprise Dual Stack" - CapabilityLADiskEncryption string = "LA Disk Encryption" - CapabilityLinodeInterfaces string = "Linode Interfaces" - CapabilityLinodes string = "Linodes" - CapabilityLKE string = "Kubernetes" - CapabilityLKEControlPlaneACL string = "LKE Network Access Control List (IP ACL)" - CapabilityLkeHaControlPlanes string = "LKE HA Control Planes" - CapabilityMachineImages string = "Machine Images" - CapabilityMaintenancePolicy string = "Maintenance Policy" - CapabilityMetadata string = "Metadata" - CapabilityNLB string = "Network LoadBalancer" - CapabilityNodeBalancers string = "NodeBalancers" - CapabilityObjectStorage string = "Object Storage" - CapabilityObjectStorageAccessKeyRegions string = "Object Storage Access Key Regions" - CapabilityObjectStorageEndpointTypes string = "Object Storage Endpoint Types" - CapabilityPlacementGroup string = "Placement Group" - CapabilityPremiumPlans string = "Premium Plans" - CapabilityQuadraT1UVPU string = "NETINT Quadra T1U" - CapabilitySMTPEnabled string = "SMTP Enabled" - CapabilityStackScripts string = "StackScripts" - CapabilitySupportTicketSeverity string = "Support Ticket Severity" - CapabilityVlans string = "Vlans" - CapabilityVPCs string = "VPCs" - CapabilityVPCDualStack string = "VPC Dual Stack" - CapabilityVPCIPv6LargePrefixes string = "VPC IPv6 Large Prefixes" - CapabilityVPCIPv6Stack string = "VPC IPv6 Stack" - CapabilityVPCsExtra string = "VPCs Extra" + CapabilityACLP RegionCapability = "Akamai Cloud Pulse" + CapabilityACLPStreams RegionCapability = "Akamai Cloud Pulse Streams" + CapabilityAkamaiRAMProtection RegionCapability = "Akamai RAM Protection" + CapabilityACLB RegionCapability = "Akamai Cloud Load Balancer" + CapabilityBackups RegionCapability = "Backups" + CapabilityBlockStorage RegionCapability = "Block Storage" + CapabilityBlockStorageEncryption RegionCapability = "Block Storage Encryption" + CapabilityBlockStorageMigrations RegionCapability = "Block Storage Migrations" + CapabilityBlockStoragePerformanceB1 RegionCapability = "Block Storage Performance B1" + CapabilityBlockStoragePerformanceB1Default RegionCapability = "Block Storage Performance B1 Default" + CapabilityCloudFirewall RegionCapability = "Cloud Firewall" + CapabilityCloudFirewallRuleSet RegionCapability = "Cloud Firewall Rule Set" + CapabilityCloudNAT RegionCapability = "Cloud NAT" + CapabilityDBAAS RegionCapability = "Managed Databases" + CapabilityDBAASBeta RegionCapability = "Managed Databases Beta" + CapabilityDiskEncryption RegionCapability = "Disk Encryption" + CapabilityDistributedPlans RegionCapability = "Distributed Plans" + CapabilityEdgePlans RegionCapability = "Edge Plans" + CapabilityGPU RegionCapability = "GPU Linodes" + CapabilityKubernetesEnterprise RegionCapability = "Kubernetes Enterprise" + CapabilityKubernetesEnterpriseBYOVPC RegionCapability = "Kubernetes Enterprise BYO VPC" + CapabilityKubernetesEnterpriseDualStack RegionCapability = "Kubernetes Enterprise Dual Stack" + CapabilityLADiskEncryption RegionCapability = "LA Disk Encryption" + CapabilityLinodeInterfaces RegionCapability = "Linode Interfaces" + CapabilityLinodes RegionCapability = "Linodes" + CapabilityLKE RegionCapability = "Kubernetes" + CapabilityLKEControlPlaneACL RegionCapability = "LKE Network Access Control List (IP ACL)" + CapabilityLkeHaControlPlanes RegionCapability = "LKE HA Control Planes" + CapabilityMachineImages RegionCapability = "Machine Images" + CapabilityMaintenancePolicy RegionCapability = "Maintenance Policy" + CapabilityMetadata RegionCapability = "Metadata" + CapabilityNLB RegionCapability = "Network LoadBalancer" + CapabilityNodeBalancers RegionCapability = "NodeBalancers" + CapabilityObjectStorage RegionCapability = "Object Storage" + CapabilityObjectStorageAccessKeyRegions RegionCapability = "Object Storage Access Key Regions" + CapabilityObjectStorageEndpointTypes RegionCapability = "Object Storage Endpoint Types" + CapabilityPlacementGroup RegionCapability = "Placement Group" + CapabilityPremiumPlans RegionCapability = "Premium Plans" + CapabilityQuadraT1UVPU RegionCapability = "NETINT Quadra T1U" + CapabilitySMTPEnabled RegionCapability = "SMTP Enabled" + CapabilityStackScripts RegionCapability = "StackScripts" + CapabilitySupportTicketSeverity RegionCapability = "Support Ticket Severity" + CapabilityVlans RegionCapability = "Vlans" + CapabilityVPCs RegionCapability = "VPCs" + CapabilityVPCDualStack RegionCapability = "VPC Dual Stack" + CapabilityVPCIPv6LargePrefixes RegionCapability = "VPC IPv6 Large Prefixes" + CapabilityVPCIPv6Stack RegionCapability = "VPC IPv6 Stack" + CapabilityVPCsExtra RegionCapability = "VPCs Extra" ) // Region-related endpoints have a custom expiry time as the diff --git a/test/integration/image_sharegroups_test.go b/test/integration/image_sharegroups_test.go index 11dfb78eb..0dd4f9f30 100644 --- a/test/integration/image_sharegroups_test.go +++ b/test/integration/image_sharegroups_test.go @@ -14,7 +14,7 @@ func TestImageSharing_Suite(t *testing.T) { client, instance, teardown, err := setupInstance( t, "fixtures/TestImageSharing_Suite", true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []string{"Linodes"})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityDBAAS})[0] options.Image = "linode/alpine3.22" }) if err != nil { diff --git a/test/integration/images_test.go b/test/integration/images_test.go index 88a012300..567048283 100644 --- a/test/integration/images_test.go +++ b/test/integration/images_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dnaeon/go-vcr/recorder" + "github.com/linode/linodego" . "github.com/linode/linodego" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -110,7 +111,7 @@ func TestImage_CreateUpload(t *testing.T) { defer teardown() image, uploadURL, err := client.CreateImageUpload(context.Background(), ImageCreateUploadOptions{ - Region: getRegionsWithCaps(t, client, []string{"Metadata"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityMetadata})[0], Label: "linodego-image-create-upload", Description: "An image that does stuff.", @@ -139,7 +140,7 @@ func TestImage_CloudInit(t *testing.T) { client, instance, teardown, err := setupInstance( t, "fixtures/TestImage_CloudInit", true, func(client *Client, options *InstanceCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []string{"Metadata"})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityMetadata})[0] }) if err != nil { t.Fatal(err) @@ -180,7 +181,7 @@ func TestImage_Replicate(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestImage_Replicate") defer teardown() - availableRegions := getRegionsWithCapsAndSiteType(t, client, []string{"Object Storage"}, "core") + availableRegions := getRegionsWithCapsAndSiteType(t, client, []linodego.RegionCapability{linodego.CapabilityObjectStorage}, "core") image, uploadURL, err := client.CreateImageUpload(context.Background(), ImageCreateUploadOptions{ Region: availableRegions[1], diff --git a/test/integration/instance_config_test.go b/test/integration/instance_config_test.go index bb5f3f11b..0e4068cdf 100644 --- a/test/integration/instance_config_test.go +++ b/test/integration/instance_config_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/linode/linodego" . "github.com/linode/linodego" "github.com/stretchr/testify/require" ) @@ -68,7 +69,10 @@ func setupInstanceWithVPCAndNATOneToOne(t *testing.T, fixturesYaml string) ( t, fixturesYaml, func(client *Client, opts *InstanceCreateOptions) { - opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityVPCs, + })[0] }, ) if err != nil { @@ -160,7 +164,8 @@ func setupInstanceWithDualStackVPCAndNAT11(t *testing.T, fixturesYaml string) ( // TODO: Revert once rolled out to all DCs. // NOTE: There is currently no VPC Dual Stack region capability // so this needs to be hardcoded. - // opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0] + // opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes, + // linodego.CapabilityVPCs})[0] opts.Region = "no-osl-1" }, ) @@ -212,7 +217,10 @@ func setupInstanceWith3Interfaces(t *testing.T, fixturesYaml string) ( t, fixturesYaml, func(client *Client, opts *InstanceCreateOptions) { - opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityVPCs, + })[0] }, ) if err != nil { @@ -304,7 +312,10 @@ func TestInstance_ConfigInterfaces_AppendDelete(t *testing.T) { "fixtures/TestInstance_ConfigInterfaces_AppendDelete", func(client *Client, opts *InstanceCreateOptions) { // Ensure we're in a region that supports VLANs - opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"})[0] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityVlans, + linodego.CapabilityVPCs, + })[0] }, ) defer teardown() @@ -454,7 +465,10 @@ func TestInstance_ConfigInterfaces_Update(t *testing.T) { "fixtures/TestInstance_ConfigInterfaces_Update", func(client *Client, opts *InstanceCreateOptions) { // Ensure we're in a region that supports VLANs - opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"})[0] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityVlans, + linodego.CapabilityVPCs, + })[0] }, ) defer teardown() @@ -528,7 +542,10 @@ func TestInstance_ConfigInterface_Update(t *testing.T) { "fixtures/TestInstance_ConfigInterface_Update", func(client *Client, opts *InstanceCreateOptions) { // Ensure we're in a region that supports VLANs - opts.Region = getRegionsWithCaps(t, client, []string{"vlans", "VPCs"})[0] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityVlans, + linodego.CapabilityVPCs, + })[0] }, ) defer teardown() diff --git a/test/integration/instance_interfaces_test.go b/test/integration/instance_interfaces_test.go index 9641c884a..a5d100b23 100644 --- a/test/integration/instance_interfaces_test.go +++ b/test/integration/instance_interfaces_test.go @@ -21,7 +21,7 @@ func createInstanceWithLinodeInterfaces( createOpts := linodego.InstanceCreateOptions{ Label: "go-test-intf-" + randLabel(), RootPass: randPassword(), - Region: getRegionsWithCaps(t, client, []string{linodego.CapabilityLinodeInterfaces})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodeInterfaces})[0], Type: "g6-nanode-1", Image: "linode/debian12", Booted: linodego.Pointer(false), @@ -80,7 +80,7 @@ func TestInstance_CreateWithLinodeInterfaces( client, fixtureTeardown := createTestClient(t, "fixtures/TestInstance_CreateWithLinodeInterfaces") t.Cleanup(fixtureTeardown) - testRegion := getRegionsWithCaps(t, client, []string{linodego.CapabilityVPCs, linodego.CapabilityLinodeInterfaces})[0] + testRegion := getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityVPCs, linodego.CapabilityLinodeInterfaces})[0] _, vpcSubnet, vpcTeardown, err := createVPCWithSubnet( t, client, diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index 8a1d09b0f..b86af0464 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -249,7 +249,7 @@ func TestInstance_MigrateToPG(t *testing.T) { clientTeardown() }() - regions := getRegionsWithCaps(t, client, []string{"Placement Group"}) + regions := getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityPlacementGroup}) pgOutboundCreateOpts := linodego.PlacementGroupCreateOptions{ Label: "linodego-test-" + getUniqueText(), @@ -367,7 +367,7 @@ func TestInstance_Disks_List_WithEncryption(t *testing.T) { "fixtures/TestInstance_Disks_List_WithEncryption", true, func(c *linodego.Client, ico *linodego.InstanceCreateOptions) { - ico.Region = getRegionsWithCaps(t, c, []string{"Disk Encryption"})[0] + ico.Region = getRegionsWithCaps(t, c, []linodego.RegionCapability{linodego.CapabilityDiskEncryption})[0] }, ) defer teardown() @@ -687,7 +687,7 @@ func TestInstance_Rebuild(t *testing.T) { t, "fixtures/TestInstance_Rebuild", true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []string{"Metadata"})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityMetadata})[0] }, ) defer teardown() @@ -725,7 +725,7 @@ func TestInstance_RebuildWithEncryption(t *testing.T) { "fixtures/TestInstance_RebuildWithEncryption", true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []string{"Disk Encryption"})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityDiskEncryption})[0] options.DiskEncryption = linodego.InstanceDiskEncryptionEnabled }, ) @@ -762,7 +762,7 @@ func TestInstance_Clone(t *testing.T) { client, instance, teardownOriginalLinode, err := setupInstance( t, "fixtures/TestInstance_Clone", true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { - targetRegion = getRegionsWithCaps(t, client, []string{"Metadata"})[0] + targetRegion = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityMetadata})[0] options.Region = targetRegion }) @@ -858,7 +858,7 @@ func TestInstance_withMetadata(t *testing.T) { options.Metadata = &linodego.InstanceMetadataOptions{ UserData: base64.StdEncoding.EncodeToString([]byte("reallycoolmetadata")), } - options.Region = getRegionsWithCaps(t, client, []string{"Metadata"})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityMetadata})[0] }) if err != nil { t.Fatal(err) @@ -891,7 +891,10 @@ func TestInstance_withBlockStorageEncryption(t *testing.T) { client, clientTeardown := createTestClient(t, "fixtures/TestInstance_withBlockStorageEncryption") inst, err := createInstance(t, client, true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []string{"Linodes", "Block Storage Encryption"})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityBlockStorageEncryption, + })[0] options.Label = "go-inst-test-create-bde" }) require.NoError(t, err) @@ -959,7 +962,7 @@ func createInstance(t *testing.T, client *linodego.Client, enableCloudFirewall b createOpts := linodego.InstanceCreateOptions{ Label: "go-test-ins-" + randLabel(), RootPass: randPassword(), - Region: getRegionsWithCaps(t, client, []string{"linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], Type: "g6-nanode-1", Image: "linode/debian12", Booted: linodego.Pointer(false), @@ -1011,8 +1014,11 @@ func createInstanceWithoutDisks( t.Helper() createOpts := linodego.InstanceCreateOptions{ - Label: "go-test-ins-wo-disk-" + randLabel(), - Region: getRegionsWithCaps(t, client, []string{"Linodes", "Maintenance Policy"})[0], + Label: "go-test-ins-wo-disk-" + randLabel(), + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityMaintenancePolicy, + })[0], Type: "g6-nanode-1", Booted: linodego.Pointer(false), } @@ -1071,7 +1077,7 @@ func TestInstance_MaintenancePolicy(t *testing.T) { region := getRegionsWithCapsAndSiteType( t, client, - []string{"Linodes", "Maintenance Policy"}, + []linodego.RegionCapability{linodego.CapabilityLinodes, linodego.CapabilityMaintenancePolicy}, "core", )[0] diff --git a/test/integration/integration_suite_test.go b/test/integration/integration_suite_test.go index 3ca0cb8a2..404694b81 100644 --- a/test/integration/integration_suite_test.go +++ b/test/integration/integration_suite_test.go @@ -194,7 +194,7 @@ Parameters: Returns: - string values representing the IDs of regions that have a given set of capabilities. */ -func getRegionsWithCaps(t *testing.T, client *linodego.Client, capabilities []string) []string { +func getRegionsWithCaps(t *testing.T, client *linodego.Client, capabilities []linodego.RegionCapability) []string { result := make([]string, 0) regions, err := client.ListRegions(context.Background(), nil) @@ -215,7 +215,7 @@ func getRegionsWithCaps(t *testing.T, client *linodego.Client, capabilities []st // getRegionWithCapsAndPlans resolves a list of regions that meet the given capabilities // and has availability for all the provided plans. -func getRegionsWithCapsAndPlans(t *testing.T, client *linodego.Client, capabilities, plans []string) []string { +func getRegionsWithCapsAndPlans(t *testing.T, client *linodego.Client, capabilities []linodego.RegionCapability, plans []string) []string { regionsWithCaps := getRegionsWithCaps(t, client, capabilities) regionsAvailabilities, err := client.ListRegionsAvailability(context.Background(), nil) @@ -255,7 +255,7 @@ func getRegionsWithCapsAndPlans(t *testing.T, client *linodego.Client, capabilit } // getRegionsWithCapsAndSiteType returns a list of regions that meet the given capabilities and site type -func getRegionsWithCapsAndSiteType(t *testing.T, client *linodego.Client, capabilities []string, siteType string) []string { +func getRegionsWithCapsAndSiteType(t *testing.T, client *linodego.Client, capabilities []linodego.RegionCapability, siteType string) []string { result := make([]string, 0) regions, err := client.ListRegions(context.Background(), nil) @@ -274,7 +274,7 @@ func getRegionsWithCapsAndSiteType(t *testing.T, client *linodego.Client, capabi return result } -func regionHasCaps(r linodego.Region, capabilities []string) bool { +func regionHasCaps(r linodego.Region, capabilities []linodego.RegionCapability) bool { capsMap := make(map[string]bool) for _, c := range r.Capabilities { @@ -282,7 +282,7 @@ func regionHasCaps(r linodego.Region, capabilities []string) bool { } for _, c := range capabilities { - if _, ok := capsMap[strings.ToUpper(c)]; !ok { + if _, ok := capsMap[strings.ToUpper(string(c))]; !ok { return false } } diff --git a/test/integration/lke_clusters_test.go b/test/integration/lke_clusters_test.go index d105e091a..f351221cb 100644 --- a/test/integration/lke_clusters_test.go +++ b/test/integration/lke_clusters_test.go @@ -434,7 +434,10 @@ func setupLKECluster(t *testing.T, clusterModifiers []clusterModifier, fixturesY } if createOpts.Region == "" { - createOpts.Region = getRegionsWithCaps(t, client, []string{"Kubernetes", "LA Disk Encryption"})[0] + createOpts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLKE, + linodego.CapabilityLADiskEncryption, + })[0] } if createOpts.K8sVersion == "" { diff --git a/test/integration/mysql_test.go b/test/integration/mysql_test.go index 9d46bf23e..d277f577c 100644 --- a/test/integration/mysql_test.go +++ b/test/integration/mysql_test.go @@ -161,7 +161,7 @@ func createMySQLDatabase(t *testing.T, client *linodego.Client, createOpts := linodego.MySQLCreateOptions{ Label: "go-mysql-test-def" + randLabel(), - Region: getRegionsWithCaps(t, client, []string{"Managed Databases"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityDBAAS})[0], Type: "g6-nanode-1", Engine: "mysql/8", ClusterSize: 3, diff --git a/test/integration/nodebalancer_configs_test.go b/test/integration/nodebalancer_configs_test.go index 6fc19203e..f318371da 100644 --- a/test/integration/nodebalancer_configs_test.go +++ b/test/integration/nodebalancer_configs_test.go @@ -256,7 +256,10 @@ func setupNodeBalancerWithVPCAndInstance( t, fixturesYaml, func(client *linodego.Client, options *linodego.VPCCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[1] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityVPCs, + })[1] }, ) if err != nil { @@ -269,7 +272,10 @@ func setupNodeBalancerWithVPCAndInstance( client, true, func(client *linodego.Client, opts *linodego.InstanceCreateOptions) { - opts.Region = getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[1] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityVPCs, + })[1] opts.Image = "linode/ubuntu22.04" opts.RootPass = "0o37Klm56P4ssw0rd" diff --git a/test/integration/nodebalancers_test.go b/test/integration/nodebalancers_test.go index 5d909a26a..e566c039f 100644 --- a/test/integration/nodebalancers_test.go +++ b/test/integration/nodebalancers_test.go @@ -201,7 +201,7 @@ func setupNodeBalancer(t *testing.T, fixturesYaml string, nbModifiers []nbModifi client, fixtureTeardown := createTestClient(t, fixturesYaml) createOpts := linodego.NodeBalancerCreateOptions{ Label: &label, - Region: getRegionsWithCaps(t, client, []string{"NodeBalancers"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityNodeBalancers})[0], ClientConnThrottle: &clientConnThrottle, FirewallID: GetFirewallID(), } diff --git a/test/integration/object_storage_keys_test.go b/test/integration/object_storage_keys_test.go index d7c586144..7ce548d89 100644 --- a/test/integration/object_storage_keys_test.go +++ b/test/integration/object_storage_keys_test.go @@ -160,7 +160,7 @@ func TestObjectStorageKeys_Limited_NoAccess(t *testing.T) { func TestObjectStorageKeys_Regional_Limited(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestObjectStorageKeys_Regional_Limited") - regions := getRegionsWithCaps(t, client, []string{"Object Storage"}) + regions := getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityObjectStorage}) if len(regions) < 1 { t.Fatal("Can't get region with Object Storage capability") } diff --git a/test/integration/placement_group_test.go b/test/integration/placement_group_test.go index a6f4c7e42..cf4325ffc 100644 --- a/test/integration/placement_group_test.go +++ b/test/integration/placement_group_test.go @@ -121,7 +121,7 @@ func createPlacementGroup( t.Helper() createOpts := linodego.PlacementGroupCreateOptions{ Label: "linodego-test-" + getUniqueText(), - Region: getRegionsWithCaps(t, client, []string{"Placement Group"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityPlacementGroup})[0], PlacementGroupType: linodego.PlacementGroupTypeAntiAffinityLocal, PlacementGroupPolicy: linodego.PlacementGroupPolicyFlexible, } diff --git a/test/integration/postgres_test.go b/test/integration/postgres_test.go index 55f17cc24..9684d3373 100644 --- a/test/integration/postgres_test.go +++ b/test/integration/postgres_test.go @@ -165,7 +165,7 @@ func createPostgresDatabase(t *testing.T, client *linodego.Client, createOpts := linodego.PostgresCreateOptions{ Label: "go-postgres-testing-def" + randLabel(), - Region: getRegionsWithCaps(t, client, []string{"Managed Databases"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityDBAAS})[0], Type: "g6-nanode-1", Engine: "postgresql/14", ClusterSize: 3, diff --git a/test/integration/tags_test.go b/test/integration/tags_test.go index 1662747eb..5313ed424 100644 --- a/test/integration/tags_test.go +++ b/test/integration/tags_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/linode/linodego" . "github.com/linode/linodego" ) @@ -92,7 +93,7 @@ func setupTaggedInstance(t *testing.T, fixturesYaml string) (*Client, *Instance, client, fixtureTeardown := createTestClient(t, fixturesYaml) createOpts := InstanceCreateOptions{ Label: "go-ins-test-tag", - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], Type: "g6-nanode-1", Tags: []string{"go-tag-test"}, } diff --git a/test/integration/vlans_test.go b/test/integration/vlans_test.go index 64bcced77..a861d5d7c 100644 --- a/test/integration/vlans_test.go +++ b/test/integration/vlans_test.go @@ -96,7 +96,7 @@ func createVLANInstance(t *testing.T, client *linodego.Client, instanceName, vla opts.Booted = &trueBool opts.Label = instanceName - opts.Region = getRegionsWithCaps(t, client, []string{"Vlans"})[0] + opts.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityVlans})[0] }) if err != nil { return nil, nil, err diff --git a/test/integration/volumes_test.go b/test/integration/volumes_test.go index 0060dfe7c..38042e572 100644 --- a/test/integration/volumes_test.go +++ b/test/integration/volumes_test.go @@ -16,7 +16,7 @@ func TestVolume_Create_smoke(t *testing.T) { createOpts := linodego.VolumeCreateOptions{ Label: "go-vol-test-create", - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], } volume, err := client.CreateVolume(context.Background(), createOpts) if err != nil { @@ -41,8 +41,11 @@ func TestVolume_Create_withEncryption(t *testing.T) { defer teardown() createOpts := linodego.VolumeCreateOptions{ - Label: "go-vol-test-create-encryption", - Region: getRegionsWithCaps(t, client, []string{"Linodes", "Block Storage Encryption"})[0], + Label: "go-vol-test-create-encryption", + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityBlockStorageEncryption, + })[0], Encryption: "enabled", } volume, err := client.CreateVolume(context.Background(), createOpts) @@ -120,8 +123,11 @@ func TestVolume_Get_withEncryption(t *testing.T) { defer teardown() createOpts := linodego.VolumeCreateOptions{ - Label: "go-vol-test-get-encryption", - Region: getRegionsWithCaps(t, client, []string{"Linodes", "Block Storage Encryption"})[0], + Label: "go-vol-test-get-encryption", + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityBlockStorageEncryption, + })[0], Encryption: "enabled", } volume, err := client.CreateVolume(context.Background(), createOpts) @@ -254,7 +260,7 @@ func setupVolume(t *testing.T, fixturesYaml string) (*linodego.Client, *linodego client, fixtureTeardown := createTestClient(t, fixturesYaml) createOpts := linodego.VolumeCreateOptions{ Label: "go-vol-test-def", - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], } volume, err := client.CreateVolume(context.Background(), createOpts) if err != nil { @@ -280,7 +286,7 @@ func createVolume( t.Helper() createOpts := linodego.VolumeCreateOptions{ Label: "go-vol-test" + randLabel(), - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], } for _, mod := range vModifier { diff --git a/test/integration/vpc_subnet_test.go b/test/integration/vpc_subnet_test.go index ad40704ad..ba8b2c0d2 100644 --- a/test/integration/vpc_subnet_test.go +++ b/test/integration/vpc_subnet_test.go @@ -82,8 +82,11 @@ func createVPCWithSubnet(t *testing.T, client *linodego.Client, vpcModifier ...v ) { t.Helper() createOpts := linodego.VPCCreateOptions{ - Label: "go-test-vpc-" + getUniqueText(), - Region: getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0], + Label: "go-test-vpc-" + getUniqueText(), + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityVPCs, + })[0], Subnets: []VPCSubnetCreateOptions{ { Label: "linodego-vpc-test-" + getUniqueText(), @@ -117,8 +120,11 @@ func createVPCWithDualStackSubnet(t *testing.T, client *linodego.Client, vpcModi ) { t.Helper() createOpts := linodego.VPCCreateOptions{ - Label: "go-test-vpc-" + getUniqueText(), - Region: getRegionsWithCaps(t, client, []string{"Linodes", "VPCs"})[0], + Label: "go-test-vpc-" + getUniqueText(), + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{ + linodego.CapabilityLinodes, + linodego.CapabilityVPCs, + })[0], IPv6: []VPCCreateOptionsIPv6{ { Range: linodego.Pointer("/52"), diff --git a/test/integration/vpc_test.go b/test/integration/vpc_test.go index 0e4509004..3f75fd0c8 100644 --- a/test/integration/vpc_test.go +++ b/test/integration/vpc_test.go @@ -36,7 +36,7 @@ func createVPC(t *testing.T, client *linodego.Client, vpcModifier ...vpcModifier t.Helper() createOpts := linodego.VPCCreateOptions{ Label: "go-test-vpc-" + getUniqueText(), - Region: getRegionsWithCaps(t, client, []string{"VPCs"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{CapabilityVPCs})[0], } for _, mod := range vpcModifier { @@ -60,7 +60,7 @@ func createVPC_invalid_label(t *testing.T, client *linodego.Client) error { t.Helper() createOpts := linodego.VPCCreateOptions{ Label: "gotest_vpc_invalid_label" + getUniqueText(), - Region: getRegionsWithCaps(t, client, []string{"VPCs"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{CapabilityVPCs})[0], } _, err := client.CreateVPC(context.Background(), createOpts) diff --git a/test/integration/waitfor_test.go b/test/integration/waitfor_test.go index 244b220f6..df388e52e 100644 --- a/test/integration/waitfor_test.go +++ b/test/integration/waitfor_test.go @@ -18,7 +18,7 @@ func TestEventPoller_InstancePower(t *testing.T) { } instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], Type: "g6-nanode-1", Image: "linode/ubuntu22.04", RootPass: randPassword(), @@ -102,7 +102,7 @@ func TestWaitForResourceFree(t *testing.T) { // Create a booted instance instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], Type: "g6-nanode-1", Image: "linode/ubuntu22.04", RootPass: randPassword(), @@ -145,7 +145,7 @@ func TestEventPoller_Secondary(t *testing.T) { } instance, err := client.CreateInstance(context.Background(), linodego.InstanceCreateOptions{ - Region: getRegionsWithCaps(t, client, []string{"Linodes"})[0], + Region: getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0], Type: "g6-nanode-1", Label: "go-ins-poll-test", Booted: linodego.Pointer(false), diff --git a/test/unit/region_test.go b/test/unit/region_test.go index b902eb888..e24a66163 100644 --- a/test/unit/region_test.go +++ b/test/unit/region_test.go @@ -46,7 +46,7 @@ func TestListRegions(t *testing.T) { assert.Greater(t, region.PlacementGroupLimits.MaximumPGsPerCustomer, 0, "Expected MaximumPGsPerCustomer to be greater than 0") assert.Greater(t, region.PlacementGroupLimits.MaximumLinodesPerPG, 0, "Expected MaximumLinodesPerPG to be greater than 0") } - assert.Contains(t, region.Capabilities, linodego.CapabilityLinodes, "Expected region to support Linodes") + assert.Contains(t, region.Capabilities, string(linodego.CapabilityLinodes), "Expected region to support Linodes") // Test monitors field assert.NotNil(t, region.Monitors.Alerts, "Expected monitors alerts to be initialized") assert.NotNil(t, region.Monitors.Metrics, "Expected monitors metrics to be initialized") @@ -82,7 +82,7 @@ func TestGetRegion(t *testing.T) { assert.Greater(t, region.PlacementGroupLimits.MaximumPGsPerCustomer, 0, "Expected MaximumPGsPerCustomer to be greater than 0") assert.Greater(t, region.PlacementGroupLimits.MaximumLinodesPerPG, 0, "Expected MaximumLinodesPerPG to be greater than 0") } - assert.Contains(t, region.Capabilities, linodego.CapabilityLinodes, "Expected region to support Linodes") + assert.Contains(t, region.Capabilities, string(linodego.CapabilityLinodes), "Expected region to support Linodes") // Test monitors field assert.NotNil(t, region.Monitors.Alerts, "Expected monitors alerts to be initialized") assert.NotNil(t, region.Monitors.Metrics, "Expected monitors metrics to be initialized") From ed2a3720b0b4f286dabca8a481d97adc2d20541a Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Wed, 6 May 2026 14:26:39 -0400 Subject: [PATCH 06/17] Added disctinction between Object Storage Bucket Access POST/PUT endpoints (#951) --- object_storage_buckets.go | 14 +- request_helpers.go | 13 + ...TestObjectStorageBucket_Access_Modify.yaml | 340 ++++++++++++++++++ ...TestObjectStorageBucket_Access_Update.yaml | 69 ++-- .../object_storage_buckets_test.go | 35 ++ test/unit/object_storage_bucket_test.go | 20 +- 6 files changed, 455 insertions(+), 36 deletions(-) create mode 100644 test/integration/fixtures/TestObjectStorageBucket_Access_Modify.yaml diff --git a/object_storage_buckets.go b/object_storage_buckets.go index ba94e736a..717946490 100644 --- a/object_storage_buckets.go +++ b/object_storage_buckets.go @@ -80,6 +80,12 @@ type ObjectStorageBucketCreateOptions struct { CorsEnabled *bool `json:"cors_enabled,omitzero"` } +// ObjectStorageBucketModifyAccessOptions fields are those accepted by ModifyObjectStorageBucketAccess +type ObjectStorageBucketModifyAccessOptions struct { + ACL ObjectStorageACL `json:"acl,omitzero"` + CorsEnabled *bool `json:"cors_enabled,omitzero"` +} + // ObjectStorageBucketUpdateAccessOptions fields are those accepted by UpdateObjectStorageBucketAccess type ObjectStorageBucketUpdateAccessOptions struct { ACL ObjectStorageACL `json:"acl,omitzero"` @@ -126,10 +132,16 @@ func (c *Client) CreateObjectStorageBucket(ctx context.Context, opts ObjectStora return doPOSTRequest[ObjectStorageBucket](ctx, c, "object-storage/buckets", opts) } +// ModifyObjectStorageBucketAccess modifies the access configuration for an ObjectStorageBucket +func (c *Client) ModifyObjectStorageBucketAccess(ctx context.Context, regionID, label string, opts ObjectStorageBucketModifyAccessOptions) error { + e := formatAPIPath("object-storage/buckets/%s/%s/access", regionID, label) + return doPOSTRequestNoResponseBody(ctx, c, e, opts) +} + // UpdateObjectStorageBucketAccess updates the access configuration for an ObjectStorageBucket func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, regionID, label string, opts ObjectStorageBucketUpdateAccessOptions) error { e := formatAPIPath("object-storage/buckets/%s/%s/access", regionID, label) - return doPOSTRequestNoResponseBody(ctx, c, e, opts) + return doPUTRequestNoResponseBody(ctx, c, e, opts) } // GetObjectStorageBucketAccess gets the current access config for a bucket diff --git a/request_helpers.go b/request_helpers.go index 1dc46c132..3efdeca3b 100644 --- a/request_helpers.go +++ b/request_helpers.go @@ -272,6 +272,19 @@ func doPUTRequest[T, O any]( return &resultType, nil } +// doPUTRequestNoResponseBody runs a PUT request using the given client, API endpoint, +// and options/body. It expects only empty response from the endpoint. +func doPUTRequestNoResponseBody[T any]( + ctx context.Context, + client *Client, + endpoint string, + options ...T, +) error { + _, err := doPUTRequest[any, T](ctx, client, endpoint, options...) + + return err +} + // doDELETERequest runs a DELETE request using the given client // and API endpoint. func doDELETERequest( diff --git a/test/integration/fixtures/TestObjectStorageBucket_Access_Modify.yaml b/test/integration/fixtures/TestObjectStorageBucket_Access_Modify.yaml new file mode 100644 index 000000000..d94cae081 --- /dev/null +++ b/test/integration/fixtures/TestObjectStorageBucket_Access_Modify.yaml @@ -0,0 +1,340 @@ +--- +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/object-storage/endpoints?page=1 + method: GET + response: + body: '{"data": [{"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, + {"region": "jp-tyo-3", "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com"}, + {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, + {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, + {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, + {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, + {"region": "us-iad", "endpoint_type": "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, + {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, + {"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, + {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, + {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, + {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, + {"region": "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, + {"region": "gb-lon", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com"}, + {"region": "de-fra-2", "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com"}, + {"region": "us-lax", "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com"}, + {"region": "us-lax", "endpoint_type": "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, + {"region": "sg-sin-2", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com"}, + {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, + {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, + {"region": "au-mel", "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com"}, + {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, + {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, + {"region": "us-east", "endpoint_type": "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, + {"region": "us-iad-2", "endpoint_type": "E3", "s3_endpoint": null}], "page": + 1, "pages": 1, "results": 26}' + 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, 05 May 2026 20:24:35 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - object_storage:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"in-maa","label":"go-bucket-test-def","endpoint_type":"E1"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/object-storage/buckets + method: POST + response: + body: '{"hostname": "go-bucket-test-def.in-maa-1.linodeobjects.com", "label": + "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "in-maa", + "cluster": "in-maa-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": + "in-maa-1.linodeobjects.com"}' + 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, 05 May 2026 20:24:39 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - object_storage:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "60" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"acl":"private","cors_enabled":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/object-storage/buckets/in-maa/go-bucket-test-def/access + 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: + - Tue, 05 May 2026 20:24:43 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - object_storage:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/object-storage/buckets/in-maa/go-bucket-test-def/access + method: GET + response: + body: '{"acl": "private", "acl_xml": "640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89eFULL_CONTROL", + "cors_enabled": false, "cors_xml": 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: + - "591" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 05 May 2026 20:24:48 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - object_storage:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/object-storage/buckets/in-maa/go-bucket-test-def + 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, 05 May 2026 20:24:53 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - object_storage:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml b/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml index d6af6dbf9..a2e251c3e 100644 --- a/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml +++ b/test/integration/fixtures/TestObjectStorageBucket_Access_Update.yaml @@ -14,32 +14,33 @@ interactions: url: https://api.linode.com/v4beta/object-storage/endpoints?page=1 method: GET response: - body: '{"data": [{"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, - {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, - {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, - {"region": "de-fra-2", "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com"}, - {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, - {"region": "sg-sin-2", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com"}, - {"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, - {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, - {"region": "jp-tyo-3", "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com"}, + body: '{"data": [{"region": "us-lax", "endpoint_type": "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, {"region": "us-lax", "endpoint_type": "E3", "s3_endpoint": "us-lax-4.linodeobjects.com"}, - {"region": "us-lax", "endpoint_type": "E1", "s3_endpoint": "us-lax-1.linodeobjects.com"}, - {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, - {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, - {"region": "us-east", "endpoint_type": "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, + {"region": "us-southeast", "endpoint_type": "E0", "s3_endpoint": "us-southeast-1.linodeobjects.com"}, + {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, {"region": "us-ord", "endpoint_type": "E3", "s3_endpoint": "us-ord-10.linodeobjects.com"}, {"region": "us-ord", "endpoint_type": "E1", "s3_endpoint": "us-ord-1.linodeobjects.com"}, - {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, - {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, {"region": "gb-lon", "endpoint_type": "E3", "s3_endpoint": "gb-lon-1.linodeobjects.com"}, - {"region": "se-sto", "endpoint_type": "E1", "s3_endpoint": "se-sto-1.linodeobjects.com"}, - {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, + {"region": "sg-sin-2", "endpoint_type": "E3", "s3_endpoint": "sg-sin-1.linodeobjects.com"}, + {"region": "it-mil", "endpoint_type": "E1", "s3_endpoint": "it-mil-1.linodeobjects.com"}, {"region": "au-mel", "endpoint_type": "E2", "s3_endpoint": "au-mel-1.linodeobjects.com"}, - {"region": "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, + {"region": "de-fra-2", "endpoint_type": "E3", "s3_endpoint": "de-fra-1.linodeobjects.com"}, + {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}, + {"region": "jp-osa", "endpoint_type": "E1", "s3_endpoint": "jp-osa-1.linodeobjects.com"}, + {"region": "es-mad", "endpoint_type": "E1", "s3_endpoint": "es-mad-1.linodeobjects.com"}, {"region": "us-iad", "endpoint_type": "E1", "s3_endpoint": "us-iad-1.linodeobjects.com"}, - {"region": "fr-par", "endpoint_type": "E1", "s3_endpoint": "fr-par-1.linodeobjects.com"}], - "page": 1, "pages": 1, "results": 25}' + {"region": "nl-ams", "endpoint_type": "E1", "s3_endpoint": "nl-ams-1.linodeobjects.com"}, + {"region": "ap-south", "endpoint_type": "E0", "s3_endpoint": "ap-south-1.linodeobjects.com"}, + {"region": "us-mia", "endpoint_type": "E1", "s3_endpoint": "us-mia-1.linodeobjects.com"}, + {"region": "eu-central", "endpoint_type": "E0", "s3_endpoint": "eu-central-1.linodeobjects.com"}, + {"region": "br-gru", "endpoint_type": "E1", "s3_endpoint": "br-gru-1.linodeobjects.com"}, + {"region": "jp-tyo-3", "endpoint_type": "E3", "s3_endpoint": "jp-tyo-1.linodeobjects.com"}, + {"region": "us-east", "endpoint_type": "E0", "s3_endpoint": "us-east-1.linodeobjects.com"}, + {"region": "id-cgk", "endpoint_type": "E1", "s3_endpoint": "id-cgk-1.linodeobjects.com"}, + {"region": "in-maa", "endpoint_type": "E1", "s3_endpoint": "in-maa-1.linodeobjects.com"}, + {"region": "us-sea", "endpoint_type": "E1", "s3_endpoint": "us-sea-1.linodeobjects.com"}, + {"region": "us-iad-2", "endpoint_type": "E3", "s3_endpoint": null}], "page": + 1, "pages": 1, "results": 26}' headers: Access-Control-Allow-Credentials: - "true" @@ -62,7 +63,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:18:42 GMT + - Tue, 05 May 2026 20:23:21 GMT Pragma: - no-cache Strict-Transport-Security: @@ -88,7 +89,7 @@ interactions: code: 200 duration: "" - request: - body: '{"region":"it-mil","label":"go-bucket-test-def","endpoint_type":"E1"}' + body: '{"region":"us-lax","label":"go-bucket-test-def","endpoint_type":"E1"}' form: {} headers: Accept: @@ -100,10 +101,10 @@ interactions: url: https://api.linode.com/v4beta/object-storage/buckets method: POST response: - body: '{"hostname": "go-bucket-test-def.it-mil-1.linodeobjects.com", "label": - "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "it-mil", - "cluster": "it-mil-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": - "it-mil-1.linodeobjects.com"}' + body: '{"hostname": "go-bucket-test-def.us-lax-1.linodeobjects.com", "label": + "go-bucket-test-def", "created": "2018-01-02T03:04:05", "region": "us-lax", + "cluster": "us-lax-1", "size": 0, "objects": 0, "endpoint_type": "E1", "s3_endpoint": + "us-lax-1.linodeobjects.com"}' headers: Access-Control-Allow-Credentials: - "true" @@ -128,7 +129,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:18:46 GMT + - Tue, 05 May 2026 20:23:23 GMT Pragma: - no-cache Strict-Transport-Security: @@ -161,8 +162,8 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/it-mil/go-bucket-test-def/access - method: POST + url: https://api.linode.com/v4beta/object-storage/buckets/us-lax/go-bucket-test-def/access + method: PUT response: body: '{}' headers: @@ -189,7 +190,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 30 Apr 2026 20:18:48 GMT + - Tue, 05 May 2026 20:23:27 GMT Pragma: - no-cache Strict-Transport-Security: @@ -222,7 +223,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/object-storage/buckets/it-mil/go-bucket-test-def/access + url: https://api.linode.com/v4beta/object-storage/buckets/us-lax/go-bucket-test-def/access method: GET response: body: '{"acl": "private", "acl_xml": "640757b5-ebe9-45b1-abd5-581f215ef89e640757b5-ebe9-45b1-abd5-581f215ef89e Date: Wed, 13 May 2026 15:19:48 -0400 Subject: [PATCH 07/17] TPT-3454: Refactor wait functions to use context for timeouts and polling (#964) * Refactor wait functions to use context for timeouts and polling * fix context cancelled in cleanup * nolint generic return type * Fix grammar Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Make preTask a private function; cleanup unnecessary previousEvents allocation * Fix error msg format Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- test/integration/databases_test.go | 14 +- test/integration/iam_io_ready_test.go | 40 +- test/integration/image_sharegroups_test.go | 5 +- test/integration/images_test.go | 13 +- test/integration/instance_config_test.go | 7 +- test/integration/instance_snapshots_test.go | 20 +- test/integration/instances_test.go | 84 ++-- test/integration/integration_suite_test.go | 9 + test/integration/lke_clusters_test.go | 18 +- test/integration/lke_node_pools_test.go | 12 +- .../monitor_alert_definitions_test.go | 5 +- test/integration/monitor_api_service_test.go | 9 +- .../monitor_services_token_creation_test.go | 5 +- test/integration/mysql_db_config_test.go | 6 +- test/integration/mysql_test.go | 28 +- test/integration/postgres_db_config_test.go | 7 +- test/integration/postgres_test.go | 28 +- test/integration/vlans_test.go | 9 +- test/integration/volumes_test.go | 14 +- test/integration/waitfor_test.go | 21 +- test/unit/waitfor_test.go | 144 ++++++ waitfor.go | 471 ++++++++---------- 22 files changed, 570 insertions(+), 399 deletions(-) create mode 100644 test/unit/waitfor_test.go diff --git a/test/integration/databases_test.go b/test/integration/databases_test.go index 99090a35d..0003a7224 100644 --- a/test/integration/databases_test.go +++ b/test/integration/databases_test.go @@ -66,7 +66,9 @@ func TestDatabase_Type(t *testing.T) { } func TestDatabase_List(t *testing.T) { - client, database, teardown, err := setupPostgresDatabase(t, nil, "fixtures/TestDatabase_List") + ctx := waitContext(t, 5400*time.Second) + + client, database, teardown, err := setupPostgresDatabase(t, ctx, nil, "fixtures/TestDatabase_List") if err != nil { t.Error(err) } @@ -90,18 +92,18 @@ func TestDatabase_List(t *testing.T) { } } -func waitForDatabaseUpdated(t *testing.T, client *linodego.Client, dbID int, +func waitForDatabaseUpdated(t *testing.T, ctx context.Context, client *linodego.Client, dbID int, dbType linodego.DatabaseEngineType, minStart *time.Time, ) { - _, err := client.WaitForEventFinished(context.Background(), dbID, linodego.EntityDatabase, - linodego.ActionDatabaseUpdate, *minStart, 1200) + _, err := client.WaitForEventFinished(ctx, dbID, linodego.EntityDatabase, + linodego.ActionDatabaseUpdate, *minStart) if err != nil { t.Fatalf("failed to wait for database update: %s", err) } // Sometimes the event has finished but the status hasn't caught up - err = client.WaitForDatabaseStatus(context.Background(), dbID, dbType, - linodego.DatabaseStatusActive, 120) + err = client.WaitForDatabaseStatus(ctx, dbID, dbType, + linodego.DatabaseStatusActive) if err != nil { t.Fatalf("failed to wait for database active: %s", err) } diff --git a/test/integration/iam_io_ready_test.go b/test/integration/iam_io_ready_test.go index 220de4a97..7be336a6f 100644 --- a/test/integration/iam_io_ready_test.go +++ b/test/integration/iam_io_ready_test.go @@ -3,6 +3,7 @@ package integration import ( "context" "testing" + "time" "github.com/linode/linodego" "github.com/stretchr/testify/assert" @@ -21,6 +22,7 @@ func findVolumeByID(volumes []linodego.Volume, id int) linodego.Volume { func setupVolumeAttachedToLinode( t *testing.T, + ctx context.Context, fixturesYaml string, detachVolume bool, ) (*linodego.Client, *linodego.Volume, *linodego.Instance, func()) { @@ -39,7 +41,7 @@ func setupVolumeAttachedToLinode( require.NoErrorf(t, err, "Error deleting instance: %v", err) } - instance, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceRunning, 180) + instance, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceRunning) require.NoErrorf(t, err, "Error waiting for instance to be running: %v", err) volume, teardownVolume, err := createVolume(t, client, func(l *linodego.Client, options *linodego.VolumeCreateOptions) { @@ -51,15 +53,19 @@ func setupVolumeAttachedToLinode( volume, err = client.AttachVolume(context.Background(), volume.ID, &linodego.VolumeAttachOptions{LinodeID: instance.ID}) require.NoErrorf(t, err, "Error attaching volume to instance: %v", err) - volume, err = client.WaitForVolumeIOReadyStatus(context.Background(), volume.ID, true, 45) + volume, err = client.WaitForVolumeIOReadyStatus(ctx, volume.ID, true) require.NoErrorf(t, err, "Error waiting for IO Ready status of attached volume: %v", err) teardown := func() { if detachVolume { - err = client.DetachVolume(context.Background(), volume.ID) + // Use a fresh context here because the context returned by t.Context() is canceled before t.Cleanup callbacks run. + cleanupCtx, cancel := context.WithTimeout(context.Background(), 45*time.Second) + defer cancel() + + err = client.DetachVolume(cleanupCtx, volume.ID) require.NoErrorf(t, err, "Error detaching volume: %v", err) - _, err = client.WaitForVolumeIOReadyStatus(context.Background(), volume.ID, false, 45) + _, err = client.WaitForVolumeIOReadyStatus(cleanupCtx, volume.ID, false) require.NoErrorf(t, err, "Error waiting for IO Ready status of detached volume: %v", err) } teardownVolume() @@ -96,6 +102,8 @@ func requireSingleAttachedInstanceVolume(t *testing.T, client *linodego.Client, } func TestIAM_GetIOReadyForNotAttachedVolume(t *testing.T) { + ctx := waitContext(t, 30*time.Second) + client, recordStopper := createTestClient(t, "fixtures/TestIAM_GetIOReadyForNotAttachedVolume") t.Cleanup(recordStopper) @@ -105,7 +113,7 @@ func TestIAM_GetIOReadyForNotAttachedVolume(t *testing.T) { t.Cleanup(teardown) require.NoErrorf(t, err, "Error creating not attached volume: %v", err) - volume, err = client.WaitForVolumeStatus(context.Background(), volume.ID, linodego.VolumeActive, 30) + volume, err = client.WaitForVolumeStatus(ctx, volume.ID, linodego.VolumeActive) require.NoErrorf(t, err, "Error waiting for volume to be active: %v", err) volumeList, err := client.ListVolumes(context.Background(), nil) @@ -128,7 +136,9 @@ func TestIAM_GetIOReadyForNotAttachedVolume(t *testing.T) { } func TestIAM_GetIOReadyForAttachedDetachedVolume(t *testing.T) { - client, volume, instance, teardown := setupVolumeAttachedToLinode(t, "fixtures/TestIAM_GetIOReadyForAttachedDetachedVolume", false) + ctx := waitContext(t, 270*time.Second) + + client, volume, instance, teardown := setupVolumeAttachedToLinode(t, ctx, "fixtures/TestIAM_GetIOReadyForAttachedDetachedVolume", false) t.Cleanup(teardown) requireSingleAttachedInstanceVolume(t, client, instance) @@ -139,7 +149,7 @@ func TestIAM_GetIOReadyForAttachedDetachedVolume(t *testing.T) { err = client.DetachVolume(context.Background(), volume.ID) require.NoErrorf(t, err, "Error detaching volume: %v", err) - _, err = client.WaitForVolumeIOReadyStatus(context.Background(), volume.ID, false, 45) + _, err = client.WaitForVolumeIOReadyStatus(ctx, volume.ID, false) require.NoErrorf(t, err, "Error waiting for IO Ready status of detached volume: %v", err) instanceVolumes, err := client.ListInstanceVolumes(context.Background(), instance.ID, nil) @@ -154,7 +164,9 @@ func TestIAM_GetIOReadyForAttachedDetachedVolume(t *testing.T) { } func TestIAM_GetIOReadyForUpdatedVolume(t *testing.T) { - client, volume, instance, teardown := setupVolumeAttachedToLinode(t, "fixtures/TestIAM_GetIOReadyForUpdatedVolume", true) + ctx := waitContext(t, 270*time.Second) + + client, volume, instance, teardown := setupVolumeAttachedToLinode(t, ctx, "fixtures/TestIAM_GetIOReadyForUpdatedVolume", true) t.Cleanup(teardown) assertVolumeAttachedToInstance(t, volume, instance) assert.NotContains(t, "-updated", volume.Label) @@ -182,7 +194,9 @@ func TestIAM_GetIOReadyForUpdatedVolume(t *testing.T) { } func TestIAM_GetIOReadyForClonedVolume(t *testing.T) { - client, volume, instance, teardown := setupVolumeAttachedToLinode(t, "fixtures/TestIAM_GetIOReadyForClonedVolume", true) + ctx := waitContext(t, 300*time.Second) + + client, volume, instance, teardown := setupVolumeAttachedToLinode(t, ctx, "fixtures/TestIAM_GetIOReadyForClonedVolume", true) t.Cleanup(teardown) requireSingleAttachedInstanceVolume(t, client, instance) @@ -195,7 +209,7 @@ func TestIAM_GetIOReadyForClonedVolume(t *testing.T) { }) require.NoErrorf(t, err, "Error cloning volume: %v", err) - _, err = client.WaitForVolumeStatus(context.Background(), volumeCloned.ID, linodego.VolumeActive, 30) + _, err = client.WaitForVolumeStatus(ctx, volumeCloned.ID, linodego.VolumeActive) require.NoErrorf(t, err, "Error waiting for IO Ready status of attached volume: %v", err) volumeCloned, err = client.GetVolume(context.Background(), volumeCloned.ID) @@ -212,7 +226,9 @@ func TestIAM_GetIOReadyForClonedVolume(t *testing.T) { } func TestIAM_GetIOReadyForResizedVolume(t *testing.T) { - client, volume, instance, teardown := setupVolumeAttachedToLinode(t, "fixtures/TestIAM_GetIOReadyForResizedVolume", true) + ctx := waitContext(t, 300*time.Second) + + client, volume, instance, teardown := setupVolumeAttachedToLinode(t, ctx, "fixtures/TestIAM_GetIOReadyForResizedVolume", true) t.Cleanup(teardown) assertVolumeAttachedToInstance(t, volume, instance) @@ -221,7 +237,7 @@ func TestIAM_GetIOReadyForResizedVolume(t *testing.T) { err := client.ResizeVolume(context.Background(), volume.ID, newSize) require.NoErrorf(t, err, "Error resizing volume: %v", err) - _, err = client.WaitForVolumeStatus(context.Background(), volume.ID, linodego.VolumeActive, 30) + _, err = client.WaitForVolumeStatus(ctx, volume.ID, linodego.VolumeActive) require.NoErrorf(t, err, "Error waiting for volume to be active: %v", err) instanceVolume := requireSingleAttachedInstanceVolume(t, client, instance) diff --git a/test/integration/image_sharegroups_test.go b/test/integration/image_sharegroups_test.go index 0dd4f9f30..349ba7e60 100644 --- a/test/integration/image_sharegroups_test.go +++ b/test/integration/image_sharegroups_test.go @@ -5,12 +5,15 @@ import ( "fmt" "slices" "testing" + "time" "github.com/linode/linodego" "github.com/stretchr/testify/require" ) func TestImageSharing_Suite(t *testing.T) { + ctx := waitContext(t, 600*time.Second) + client, instance, teardown, err := setupInstance( t, "fixtures/TestImageSharing_Suite", true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { @@ -42,7 +45,7 @@ func TestImageSharing_Suite(t *testing.T) { require.NoError(t, err) }) - _, err = client.WaitForImageStatus(context.Background(), image.ID, linodego.ImageStatusAvailable, 600) + _, err = client.WaitForImageStatus(ctx, image.ID, linodego.ImageStatusAvailable) require.NoError(t, err) if image.IsShared { diff --git a/test/integration/images_test.go b/test/integration/images_test.go index 567048283..1e2f17fd1 100644 --- a/test/integration/images_test.go +++ b/test/integration/images_test.go @@ -5,6 +5,7 @@ import ( "context" "slices" "testing" + "time" "github.com/dnaeon/go-vcr/recorder" "github.com/linode/linodego" @@ -69,6 +70,8 @@ func TestImages_List_smoke(t *testing.T) { } func TestImage_Upload(t *testing.T) { + ctx := waitContext(t, 300*time.Second) + client, teardown := createTestClient(t, "fixtures/TestImage_Upload") defer teardown() @@ -90,7 +93,7 @@ func TestImage_Upload(t *testing.T) { t.Errorf("Expected upload URL, got none") } - if _, err := client.WaitForImageStatus(context.Background(), image.ID, ImageStatusPendingUpload, 60); err != nil { + if _, err := client.WaitForImageStatus(ctx, image.ID, ImageStatusPendingUpload); err != nil { t.Errorf("Failed to wait for image pending upload status: %v", err) } @@ -101,7 +104,7 @@ func TestImage_Upload(t *testing.T) { } } - if _, err := client.WaitForImageStatus(context.Background(), image.ID, ImageStatusAvailable, 240); err != nil { + if _, err := client.WaitForImageStatus(ctx, image.ID, ImageStatusAvailable); err != nil { t.Errorf("Failed to wait for image available upload status: %v", err) } } @@ -178,6 +181,8 @@ func TestImage_CloudInit(t *testing.T) { } func TestImage_Replicate(t *testing.T) { + ctx := waitContext(t, 460*time.Second) + client, teardown := createTestClient(t, "fixtures/TestImage_Replicate") defer teardown() @@ -201,7 +206,7 @@ func TestImage_Replicate(t *testing.T) { t.Errorf("Expected upload URL, got none") } - if _, err := client.WaitForImageStatus(context.Background(), image.ID, ImageStatusPendingUpload, 60); err != nil { + if _, err := client.WaitForImageStatus(ctx, image.ID, ImageStatusPendingUpload); err != nil { t.Errorf("Failed to wait for image pending upload status: %v", err) } @@ -212,7 +217,7 @@ func TestImage_Replicate(t *testing.T) { } } - if _, err := client.WaitForImageStatus(context.Background(), image.ID, ImageStatusAvailable, 400); err != nil { + if _, err := client.WaitForImageStatus(ctx, image.ID, ImageStatusAvailable); err != nil { t.Errorf("Failed to wait for image available upload status: %v", err) } diff --git a/test/integration/instance_config_test.go b/test/integration/instance_config_test.go index 0e4068cdf..5b93ca820 100644 --- a/test/integration/instance_config_test.go +++ b/test/integration/instance_config_test.go @@ -4,6 +4,7 @@ import ( "context" "reflect" "testing" + "time" "github.com/linode/linodego" . "github.com/linode/linodego" @@ -656,6 +657,8 @@ func TestInstance_Config_Update(t *testing.T) { } func TestInstance_Config_VolumeLimitExtension(t *testing.T) { + ctx := waitContext(t, 1000*time.Second) + client, instance, config, teardown, err := setupInstanceWithoutDisks( t, "fixtures/TestInstance_Config_VolumeLimitExtension", true, @@ -705,10 +708,10 @@ func TestInstance_Config_VolumeLimitExtension(t *testing.T) { RootDevice: "/dev/sdk", } - _, err = client.WaitForVolumeStatus(context.Background(), volume1.ID, VolumeActive, 500) + _, err = client.WaitForVolumeStatus(ctx, volume1.ID, VolumeActive) require.NoError(t, err) - _, err = client.WaitForVolumeStatus(context.Background(), volume2.ID, VolumeActive, 500) + _, err = client.WaitForVolumeStatus(ctx, volume2.ID, VolumeActive) require.NoError(t, err) updatedConfig, err := client.UpdateInstanceConfig(context.Background(), instance.ID, config.ID, configOpts) diff --git a/test/integration/instance_snapshots_test.go b/test/integration/instance_snapshots_test.go index 8ef1da669..d28ddc2c4 100644 --- a/test/integration/instance_snapshots_test.go +++ b/test/integration/instance_snapshots_test.go @@ -11,7 +11,9 @@ import ( var testSnapshotLabel = "snapshot-linodego-testing" func TestInstanceBackups_List(t *testing.T) { - client, instance, backup, teardown, err := setupInstanceBackup(t, "fixtures/TestInstanceBackups_List") + ctx := waitContext(t, 1500*time.Second) + + client, instance, backup, teardown, err := setupInstanceBackup(t, ctx, "fixtures/TestInstanceBackups_List") defer teardown() if err != nil { t.Error(err) @@ -52,7 +54,7 @@ func TestInstanceBackups_List(t *testing.T) { t.Errorf("Expected snapshot did not match current snapshot: %v", backups.Snapshot.Current) } - backup, err = client.WaitForSnapshotStatus(context.Background(), instance.ID, backup.ID, linodego.SnapshotSuccessful, 360) + backup, err = client.WaitForSnapshotStatus(ctx, instance.ID, backup.ID, linodego.SnapshotSuccessful) if err != nil { t.Errorf("Error waiting for snapshot: %v", err) } @@ -79,20 +81,24 @@ func TestInstanceBackups_List(t *testing.T) { } // wait for instnace to restore - _, err = client.WaitForEventFinished(context.Background(), instance.ID, linodego.EntityLinode, linodego.ActionBackupsRestore, now, 360) + _, err = client.WaitForEventFinished(ctx, instance.ID, linodego.EntityLinode, linodego.ActionBackupsRestore, now) if err != nil { t.Errorf("Error waiting for snapshot to complete: %v", err) } } -func setupInstanceBackup(t *testing.T, fixturesYaml string) (*linodego.Client, *linodego.Instance, *linodego.InstanceSnapshot, func(), error) { +func setupInstanceBackup( + t *testing.T, + ctx context.Context, + fixturesYaml string, +) (*linodego.Client, *linodego.Instance, *linodego.InstanceSnapshot, func(), error) { t.Helper() client, instance, _, fixtureTeardown, err := setupInstanceWithoutDisks(t, fixturesYaml, true) if err != nil { t.Errorf("Error creating instance, got error %v", err) } - client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceOffline, 180) + client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceOffline) createOpts := linodego.InstanceDiskCreateOptions{ Size: 18, Label: "linodego-disk-test", @@ -104,7 +110,7 @@ func setupInstanceBackup(t *testing.T, fixturesYaml string) (*linodego.Client, * } // wait for disk to finish provisioning - event, err := client.WaitForEventFinished(context.Background(), instance.ID, linodego.EntityLinode, linodego.ActionDiskCreate, *disk.Created, 240) + event, err := client.WaitForEventFinished(ctx, instance.ID, linodego.EntityLinode, linodego.ActionDiskCreate, *disk.Created) if err != nil { t.Errorf("Error waiting for instance snapshot: %v", err) } @@ -123,7 +129,7 @@ func setupInstanceBackup(t *testing.T, fixturesYaml string) (*linodego.Client, * t.Errorf("Error creating instance snapshot: %v", err) } - event, err = client.WaitForEventFinished(context.Background(), instance.ID, linodego.EntityLinode, linodego.ActionLinodeSnapshot, *instance.Created, 360) + event, err = client.WaitForEventFinished(ctx, instance.ID, linodego.EntityLinode, linodego.ActionLinodeSnapshot, *instance.Created) if err != nil { t.Errorf("Error waiting for instance snapshot: %v", err) } diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index c525b4779..6efc1ad6b 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" "testing" + "time" "github.com/linode/linodego" "github.com/stretchr/testify/assert" @@ -124,6 +125,8 @@ func TestInstance_GetMonthlyTransfer(t *testing.T) { } func TestInstance_ResetPassword(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, instance, teardown, err := setupInstance( t, "fixtures/TestInstance_ResetPassword", true, @@ -141,10 +144,9 @@ func TestInstance_ResetPassword(t *testing.T) { } instance, err = client.WaitForInstanceStatus( - context.Background(), + ctx, instance.ID, linodego.InstanceOffline, - 180, ) if err != nil { t.Errorf("Error waiting for instance readiness for password reset: %s", err.Error()) @@ -163,6 +165,8 @@ func TestInstance_ResetPassword(t *testing.T) { } func TestInstance_Resize(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, instance, teardown, err := setupInstance( t, "fixtures/TestInstance_Resize", true, @@ -179,10 +183,9 @@ func TestInstance_Resize(t *testing.T) { } instance, err = client.WaitForInstanceStatus( - context.Background(), + ctx, instance.ID, linodego.InstanceRunning, - 180, ) if err != nil { t.Errorf("Error waiting for instance readiness for resize: %s", err.Error()) @@ -202,6 +205,8 @@ func TestInstance_Resize(t *testing.T) { } func TestInstance_Migrate(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, instance, teardown, err := setupInstance( t, "fixtures/TestInstance_Migrate", true, @@ -218,10 +223,9 @@ func TestInstance_Migrate(t *testing.T) { } instance, err = client.WaitForInstanceStatus( - context.Background(), + ctx, instance.ID, linodego.InstanceRunning, - 180, ) if err != nil { t.Errorf("Error waiting for instance readiness for migration: %s", err.Error()) @@ -244,6 +248,8 @@ func TestInstance_Migrate(t *testing.T) { } func TestInstance_MigrateToPG(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, clientTeardown := createTestClient(t, "fixtures/TestInstance_MigrateToPG") defer func() { @@ -282,10 +288,9 @@ func TestInstance_MigrateToPG(t *testing.T) { } instance, err = client.WaitForInstanceStatus( - context.Background(), + ctx, instance.ID, linodego.InstanceRunning, - 180, ) if err != nil { t.Errorf("Error waiting for instance readiness for migration: %s", err.Error()) @@ -393,13 +398,15 @@ func TestInstance_Disks_List_WithEncryption(t *testing.T) { } func TestInstance_Disk_Resize(t *testing.T) { + ctx := waitContext(t, 360*time.Second) + client, instance, _, teardown, err := setupInstanceWithoutDisks(t, "fixtures/TestInstance_Disk_Resize", true) defer teardown() if err != nil { t.Error(err) } - instance, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceOffline, 180) + instance, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceOffline) if err != nil { t.Errorf("Error waiting for instance readiness for resize: %s", err) } @@ -413,7 +420,7 @@ func TestInstance_Disk_Resize(t *testing.T) { t.Errorf("Error creating disk for resize: %s", err) } - disk, err = client.WaitForInstanceDiskStatus(context.Background(), instance.ID, disk.ID, linodego.DiskReady, 180) + disk, err = client.WaitForInstanceDiskStatus(ctx, instance.ID, disk.ID, linodego.DiskReady) if err != nil { t.Errorf("Error waiting for disk readiness for resize: %s", err) } @@ -425,6 +432,8 @@ func TestInstance_Disk_Resize(t *testing.T) { } func TestInstance_Disk_ListMultiple(t *testing.T) { + ctx := waitContext(t, 840*time.Second) + // This is a long running test client, instance1, teardown1, err := setupInstance(t, "fixtures/TestInstance_Disk_ListMultiple_Primary", true) defer teardown1() @@ -435,7 +444,7 @@ func TestInstance_Disk_ListMultiple(t *testing.T) { if err != nil { t.Error(err) } - instance1, err = client.WaitForInstanceStatus(context.Background(), instance1.ID, linodego.InstanceRunning, 180) + instance1, err = client.WaitForInstanceStatus(ctx, instance1.ID, linodego.InstanceRunning) if err != nil { t.Errorf("Error waiting for instance readiness: %s", err) } @@ -445,7 +454,7 @@ func TestInstance_Disk_ListMultiple(t *testing.T) { t.Error(err) } - disk, err := client.WaitForInstanceDiskStatus(context.Background(), instance1.ID, disks[0].ID, linodego.DiskReady, 180) + disk, err := client.WaitForInstanceDiskStatus(ctx, instance1.ID, disks[0].ID, linodego.DiskReady) if err != nil { t.Errorf("Error waiting for disk readiness: %s", err) } @@ -464,12 +473,12 @@ func TestInstance_Disk_ListMultiple(t *testing.T) { if err != nil { t.Error(err) } - instance2, err = client.WaitForInstanceStatus(context.Background(), instance2.ID, linodego.InstanceOffline, 180) + instance2, err = client.WaitForInstanceStatus(ctx, instance2.ID, linodego.InstanceOffline) if err != nil { t.Errorf("Error waiting for instance readiness: %s", err) } - _, err = client.WaitForEventFinished(context.Background(), instance1.ID, linodego.EntityLinode, linodego.ActionDiskImagize, *disk.Created, 300) + _, err = client.WaitForEventFinished(ctx, instance1.ID, linodego.EntityLinode, linodego.ActionDiskImagize, *disk.Created) if err != nil { t.Errorf("Error waiting for imagize event: %s", err) } @@ -502,13 +511,15 @@ func TestInstance_Disk_ListMultiple(t *testing.T) { } func TestInstance_Disk_Clone(t *testing.T) { + ctx := waitContext(t, 540*time.Second) + client, instance, _, teardown, err := setupInstanceWithoutDisks(t, "fixtures/TestInstance_Disk_Clone", true) defer teardown() if err != nil { t.Error(err) } - instance, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceOffline, 180) + instance, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceOffline) if err != nil { t.Errorf("Error waiting for instance readiness for disk clone: %s", err) } @@ -524,11 +535,11 @@ func TestInstance_Disk_Clone(t *testing.T) { t.Errorf("Error creating disk for disk clone: %s", err) } - instance, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceOffline, 180) + instance, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceOffline) if err != nil { t.Errorf("Error waiting for instance readiness after creating disk for disk clone: %s", err) } - disk, err = client.WaitForInstanceDiskStatus(context.Background(), instance.ID, disk.ID, linodego.DiskReady, 180) + disk, err = client.WaitForInstanceDiskStatus(ctx, instance.ID, disk.ID, linodego.DiskReady) if err != nil { t.Errorf("Error waiting for disk readiness for disk clone: %s", err) } @@ -542,13 +553,15 @@ func TestInstance_Disk_Clone(t *testing.T) { } func TestInstance_Disk_ResetPassword(t *testing.T) { + ctx := waitContext(t, 540*time.Second) + client, instance, _, teardown, err := setupInstanceWithoutDisks(t, "fixtures/TestInstance_Disk_ResetPassword", true) defer teardown() if err != nil { t.Error(err) } - instance, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceOffline, 180) + instance, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceOffline) if err != nil { t.Errorf("Error waiting for instance readiness for password reset: %s", err) } @@ -564,11 +577,11 @@ func TestInstance_Disk_ResetPassword(t *testing.T) { t.Errorf("Error creating disk for password reset: %s", err) } - instance, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceOffline, 180) + instance, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceOffline) if err != nil { t.Errorf("Error waiting for instance readiness after creating disk for password reset: %s", err) } - disk, err = client.WaitForInstanceDiskStatus(context.Background(), instance.ID, disk.ID, linodego.DiskReady, 180) + disk, err = client.WaitForInstanceDiskStatus(ctx, instance.ID, disk.ID, linodego.DiskReady) if err != nil { t.Errorf("Error waiting for disk readiness for password reset: %s", err) } @@ -616,6 +629,8 @@ func TestInstance_NodeBalancers_List(t *testing.T) { } func TestInstance_Volumes_List(t *testing.T) { + ctx := waitContext(t, 500*time.Second) + client, instance, config, teardown, err := setupInstanceWithoutDisks(t, "fixtures/TestInstance_Volumes_List_Instance", true) defer teardown() if err != nil { @@ -626,7 +641,7 @@ func TestInstance_Volumes_List(t *testing.T) { options.Region = instance.Region }) - _, err = client.WaitForVolumeStatus(context.Background(), volume.ID, linodego.VolumeActive, 500) + _, err = client.WaitForVolumeStatus(ctx, volume.ID, linodego.VolumeActive) if err != nil { t.Errorf("Error waiting for volume to be active, %s", err) } @@ -684,6 +699,8 @@ func TestInstance_CreateUnderFirewall(t *testing.T) { } func TestInstance_Rebuild(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, instance, _, teardown, err := setupInstanceWithoutDisks( t, "fixtures/TestInstance_Rebuild", true, @@ -697,7 +714,7 @@ func TestInstance_Rebuild(t *testing.T) { t.Error(err) } - _, err = client.WaitForEventFinished(context.Background(), instance.ID, linodego.EntityLinode, linodego.ActionLinodeCreate, *instance.Created, 180) + _, err = client.WaitForEventFinished(ctx, instance.ID, linodego.EntityLinode, linodego.ActionLinodeCreate, *instance.Created) if err != nil { t.Errorf("Error waiting for instance created: %s", err) } @@ -721,6 +738,8 @@ func TestInstance_Rebuild(t *testing.T) { } func TestInstance_RebuildWithEncryption(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, instance, _, teardown, err := setupInstanceWithoutDisks( t, "fixtures/TestInstance_RebuildWithEncryption", @@ -736,7 +755,7 @@ func TestInstance_RebuildWithEncryption(t *testing.T) { t.Error(err) } - _, err = client.WaitForEventFinished(context.Background(), instance.ID, linodego.EntityLinode, linodego.ActionLinodeCreate, *instance.Created, 180) + _, err = client.WaitForEventFinished(ctx, instance.ID, linodego.EntityLinode, linodego.ActionLinodeCreate, *instance.Created) if err != nil { t.Errorf("Error waiting for instance created: %s", err) } @@ -758,6 +777,8 @@ func TestInstance_RebuildWithEncryption(t *testing.T) { } func TestInstance_Clone(t *testing.T) { + ctx := waitContext(t, 420*time.Second) + var targetRegion string client, instance, teardownOriginalLinode, err := setupInstance( @@ -773,12 +794,11 @@ func TestInstance_Clone(t *testing.T) { t.Cleanup(teardownOriginalLinode) _, err = client.WaitForEventFinished( - context.Background(), + ctx, instance.ID, linodego.EntityLinode, linodego.ActionLinodeCreate, *instance.Created, - 180, ) if err != nil { t.Errorf("Error waiting for instance created: %s", err) @@ -806,17 +826,12 @@ func TestInstance_Clone(t *testing.T) { client.DeleteInstance(context.Background(), clonedInstance.ID) }) - if err != nil { - t.Error(err) - } - _, err = client.WaitForEventFinished( - context.Background(), + ctx, instance.ID, linodego.EntityLinode, linodego.ActionLinodeClone, *clonedInstance.Created, - 240, ) if err != nil { t.Fatal(err) @@ -1178,6 +1193,8 @@ func TestExpectedErrorIfFieldsAuthorizedUsersAuthorizedKeysRootPassAreNotSet(t * } func TestCreateLinodeWithKernelAndBootSizeThenAddDiskAndRebuild(t *testing.T) { + ctx := waitContext(t, 360*time.Second) + client, teardown := createTestClient(t, "fixtures/TestInstance_TestCreateLinodeWithKernelAndBootSizeThenAddDiskAndRebuild") defer teardown() @@ -1208,12 +1225,11 @@ func TestCreateLinodeWithKernelAndBootSizeThenAddDiskAndRebuild(t *testing.T) { require.NoError(t, err) assert.Equal(t, "linode/debian12", instance.Image) _, err = client.WaitForEventFinished( - context.Background(), + ctx, instance.ID, linodego.EntityLinode, linodego.ActionLinodeCreate, *instance.Created, - 180, ) require.NoErrorf(t, err, "Error waiting for instance created: %s", err) @@ -1225,7 +1241,7 @@ func TestCreateLinodeWithKernelAndBootSizeThenAddDiskAndRebuild(t *testing.T) { RootPass: randPassword(), }) require.NoError(t, errCreateDisk) - createDiskResponse, err = client.WaitForInstanceDiskStatus(context.Background(), instance.ID, createDiskResponse.ID, linodego.DiskReady, 180) + createDiskResponse, err = client.WaitForInstanceDiskStatus(ctx, instance.ID, createDiskResponse.ID, linodego.DiskReady) require.NoError(t, err) assert.Equal(t, linodego.DiskReady, createDiskResponse.Status) diff --git a/test/integration/integration_suite_test.go b/test/integration/integration_suite_test.go index 404694b81..11df46310 100644 --- a/test/integration/integration_suite_test.go +++ b/test/integration/integration_suite_test.go @@ -171,6 +171,15 @@ func createTestClient(t *testing.T, fixturesYaml string) (*linodego.Client, func return &c, recordStopper } +func waitContext(t *testing.T, timeout time.Duration) context.Context { + t.Helper() + + ctx, cancel := context.WithTimeout(t.Context(), timeout) + t.Cleanup(cancel) + + return ctx +} + // transportRecordWrapper returns a tranport.WrapperFunc which provides the test // recorder as an http.RoundTripper. func transportRecorderWrapper(t *testing.T, fixtureYaml string) (transport.WrapperFunc, func()) { diff --git a/test/integration/lke_clusters_test.go b/test/integration/lke_clusters_test.go index f351221cb..7ad30eb55 100644 --- a/test/integration/lke_clusters_test.go +++ b/test/integration/lke_clusters_test.go @@ -6,6 +6,7 @@ import ( "net/url" "reflect" "testing" + "time" "github.com/linode/linodego" k8scondition "github.com/linode/linodego/k8s/pkg/condition" @@ -30,6 +31,8 @@ func TestLKECluster_GetMissing(t *testing.T) { } func TestLKECluster_WaitForReady(t *testing.T) { + ctx := waitContext(t, 10*60*time.Second) + client, cluster, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { createOpts.Label = "go-lke-test-wait" createOpts.NodePools = []linodego.LKENodePoolCreateOptions{ @@ -41,9 +44,8 @@ func TestLKECluster_WaitForReady(t *testing.T) { wrapper, teardownClusterClient := transportRecorderWrapper(t, "fixtures/TestLKECluster_WaitForReady_Cluster") defer teardownClusterClient() - if err = k8scondition.WaitForLKEClusterReady(context.Background(), *client, cluster.ID, linodego.LKEClusterPollOptions{ + if err = k8scondition.WaitForLKEClusterReady(ctx, *client, cluster.ID, linodego.LKEClusterPollOptions{ Retry: true, - TimeoutSeconds: 10 * 60, TransportWrapper: wrapper, }); err != nil { t.Errorf("Error waiting for the LKE cluster pools to be ready: %s", err) @@ -205,12 +207,14 @@ func TestLKECluster_APIEndpoints_List(t *testing.T) { } func TestLKECluster_Kubeconfig_Get(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, lkeCluster, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { createOpts.Label = "go-lke-test-kube-get" }}, "fixtures/TestLKECluster_Kubeconfig_Get") defer teardown() - _, err = client.WaitForLKEClusterStatus(context.Background(), lkeCluster.ID, linodego.LKEClusterReady, 180) + _, err = client.WaitForLKEClusterStatus(ctx, lkeCluster.ID, linodego.LKEClusterReady) if err != nil { t.Errorf("Error waiting for LKECluster readiness: %s", err) } @@ -224,12 +228,14 @@ func TestLKECluster_Kubeconfig_Get(t *testing.T) { } func TestLKECluster_Kubeconfig_Delete(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, lkeCluster, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { createOpts.Label = "go-lke-test-kube-delete" }}, "fixtures/TestLKECluster_Kubeconfig_Delete") defer teardown() - _, err = client.WaitForLKEClusterStatus(context.Background(), lkeCluster.ID, linodego.LKEClusterReady, 180) + _, err = client.WaitForLKEClusterStatus(ctx, lkeCluster.ID, linodego.LKEClusterReady) if err != nil { t.Errorf("Error waiting for LKECluster readiness: %s", err) } @@ -248,12 +254,14 @@ func TestLKECluster_Kubeconfig_Delete(t *testing.T) { } func TestLKECluster_Dashboard_Get(t *testing.T) { + ctx := waitContext(t, 180*time.Second) + client, lkeCluster, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { createOpts.Label = "go-lke-test-dash" }}, "fixtures/TestLKECluster_Dashboard_Get") defer teardown() - _, err = client.WaitForLKEClusterStatus(context.Background(), lkeCluster.ID, linodego.LKEClusterReady, 180) + _, err = client.WaitForLKEClusterStatus(ctx, lkeCluster.ID, linodego.LKEClusterReady) if err != nil { t.Errorf("Error waiting for LKECluster readiness: %s", err) } diff --git a/test/integration/lke_node_pools_test.go b/test/integration/lke_node_pools_test.go index 0349c4b46..9e4ba3e3f 100644 --- a/test/integration/lke_node_pools_test.go +++ b/test/integration/lke_node_pools_test.go @@ -3,6 +3,7 @@ package integration import ( "context" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/linode/linodego" @@ -41,13 +42,15 @@ func TestLKENodePool_GetMissing(t *testing.T) { } func TestLKENodePool_GetFound(t *testing.T) { + ctx := waitContext(t, 10*time.Minute) + client, lkeCluster, pool, teardown, err := setupLKENodePool(t, "fixtures/TestLKENodePool_GetFound", &testLKENodePoolCreateOpts) if err != nil { t.Error(err) } defer teardown() - i, err := client.GetLKENodePool(context.Background(), lkeCluster.ID, pool.ID) + i, err := client.GetLKENodePool(ctx, lkeCluster.ID, pool.ID) if err != nil { t.Errorf("Error getting LKENodePool, expected struct, got %v and error %v", i, err) } @@ -79,21 +82,20 @@ func TestLKENodePool_GetFound(t *testing.T) { wrapper, teardownClusterClient := transportRecorderWrapper(t, "fixtures/TestLKENodePool_GetFound_k8s") defer teardownClusterClient() - if err := k8scondition.WaitForLKEClusterAndNodesReady(context.TODO(), *client, lkeCluster.ID, linodego.LKEClusterPollOptions{ + if err := k8scondition.WaitForLKEClusterAndNodesReady(ctx, *client, lkeCluster.ID, linodego.LKEClusterPollOptions{ Retry: true, - TimeoutSeconds: 0, TransportWrapper: wrapper, }); err != nil { t.Fatalf("got err waiting for LKE cluster and nodes to be ready, err: %v", err) } - i, err = client.GetLKENodePool(context.TODO(), lkeCluster.ID, pool.ID) + i, err = client.GetLKENodePool(ctx, lkeCluster.ID, pool.ID) if err != nil { t.Fatalf("failed to get lke node pool, got err: %v", err) } for _, node := range i.Linodes { - instance, err := client.GetInstance(context.Background(), node.InstanceID) + instance, err := client.GetInstance(ctx, node.InstanceID) if err != nil { t.Errorf("failed to get Linode, got err: %v", err) } diff --git a/test/integration/monitor_alert_definitions_test.go b/test/integration/monitor_alert_definitions_test.go index eb3f11ba4..f34df07ab 100644 --- a/test/integration/monitor_alert_definitions_test.go +++ b/test/integration/monitor_alert_definitions_test.go @@ -18,6 +18,8 @@ const ( ) func TestMonitorAlertDefinition_smoke(t *testing.T) { + ctx := waitContext(t, 300*time.Second) + client, teardown := createTestClient(t, "fixtures/TestMonitorAlertDefinition") defer teardown() @@ -154,11 +156,10 @@ func TestMonitorAlertDefinition_smoke(t *testing.T) { } // wait for 1 minute before update for create to complete _, err = client.WaitForAlertDefinitionStatus( - context.Background(), + ctx, linodego.AlertDefinitionStatusEnabled, testMonitorAlertDefinitionServiceType, createdAlert.ID, - 300, // timeout in seconds (5 minutes) ) if err != nil { t.Logf("failed to wait for alert definition to be enabled: %s", err) diff --git a/test/integration/monitor_api_service_test.go b/test/integration/monitor_api_service_test.go index e8fa1ac4c..cc4d0ef28 100644 --- a/test/integration/monitor_api_service_test.go +++ b/test/integration/monitor_api_service_test.go @@ -3,12 +3,15 @@ package integration import ( "context" "testing" + "time" "github.com/linode/linodego" ) func TestMonitorAPI_Fetch_Entity_Metrics(t *testing.T) { - mClient, entityIDs, teardown, err := setup(t, "fixtures/TestMonitorAPI_Get_Entity_Metrics") + ctx := waitContext(t, 5400*time.Second) + + mClient, entityIDs, teardown, err := setup(t, ctx, "fixtures/TestMonitorAPI_Get_Entity_Metrics") if err != nil { t.Error(err) } @@ -38,7 +41,7 @@ func TestMonitorAPI_Fetch_Entity_Metrics(t *testing.T) { } } -func setup(t *testing.T, fixturesYaml string) (*linodego.MonitorClient, []any, func(), error) { +func setup(t *testing.T, ctx context.Context, fixturesYaml string) (*linodego.MonitorClient, []any, func(), error) { t.Helper() client, clientFixtureTeardown := createTestClient(t, "fixtures/TestMonitorAPI_Get_Entity_Metrics_ListDB") @@ -51,7 +54,7 @@ func setup(t *testing.T, fixturesYaml string) (*linodego.MonitorClient, []any, f var teardown func() if len(dbs) < 1 { // create a DB entity to generate token - client, _, teardown, err = setupPostgresDatabase(t, nil, "fixtures/TestMonitorAPI_Get_Entity_Metrics_setupPostgres") + client, _, teardown, err = setupPostgresDatabase(t, ctx, nil, "fixtures/TestMonitorAPI_Get_Entity_Metrics_setupPostgres") if err != nil { t.Error(err) } diff --git a/test/integration/monitor_services_token_creation_test.go b/test/integration/monitor_services_token_creation_test.go index 465416c7a..49aec9d8b 100644 --- a/test/integration/monitor_services_token_creation_test.go +++ b/test/integration/monitor_services_token_creation_test.go @@ -3,6 +3,7 @@ package integration import ( "context" "testing" + "time" "github.com/linode/linodego" "github.com/stretchr/testify/assert" @@ -10,7 +11,9 @@ import ( ) func TestMonitorServicesTokenCreation_Get_smoke(t *testing.T) { - client, _, teardown, err := setupPostgresDatabase(t, nil, "fixtures/TestMonitorServicesTokenCreation_Get") + ctx := waitContext(t, 5400*time.Second) + + client, _, teardown, err := setupPostgresDatabase(t, ctx, nil, "fixtures/TestMonitorServicesTokenCreation_Get") if err != nil { t.Error(err) } diff --git a/test/integration/mysql_db_config_test.go b/test/integration/mysql_db_config_test.go index 9ad8f3052..565e74f57 100644 --- a/test/integration/mysql_db_config_test.go +++ b/test/integration/mysql_db_config_test.go @@ -4,6 +4,7 @@ import ( "context" "os" "testing" + "time" "github.com/linode/linodego" "github.com/stretchr/testify/assert" @@ -195,12 +196,15 @@ func TestDatabaseMySQL_EngineConfig_Get(t *testing.T) { } func TestDatabaseMySQL_EngineConfig_Suite(t *testing.T) { + ctx := waitContext(t, 6720*time.Second) + databaseModifiers := []mysqlDatabaseModifier{ createMySQLOptionsModifier(), } client, database, teardown, err := setupMySQLDatabase( t, + ctx, databaseModifiers, "fixtures/TestDatabaseMySQL_EngineConfig_Suite", ) @@ -237,7 +241,7 @@ func TestDatabaseMySQL_EngineConfig_Suite(t *testing.T) { t.Errorf("failed to update db %d: %v", database.ID, err) } - waitForDatabaseUpdated(t, client, updatedDB.ID, linodego.DatabaseEngineTypeMySQL, updatedDB.Created) + waitForDatabaseUpdated(t, ctx, client, updatedDB.ID, linodego.DatabaseEngineTypeMySQL, updatedDB.Created) assertUpdatedSQLFields(t, updatedDB.EngineConfig.MySQL) } diff --git a/test/integration/mysql_test.go b/test/integration/mysql_test.go index d277f577c..df71f24f2 100644 --- a/test/integration/mysql_test.go +++ b/test/integration/mysql_test.go @@ -12,7 +12,9 @@ import ( ) func TestDatabase_MySQL_Suite(t *testing.T) { - client, database, teardown, err := setupMySQLDatabase(t, nil, "fixtures/TestDatabase_MySQL_Suite") + ctx := waitContext(t, 12000*time.Second) + + client, database, teardown, err := setupMySQLDatabase(t, ctx, nil, "fixtures/TestDatabase_MySQL_Suite") if err != nil { t.Error(err) } @@ -64,7 +66,7 @@ func TestDatabase_MySQL_Suite(t *testing.T) { t.Errorf("failed to update db %d: %v", database.ID, err) } - waitForDatabaseUpdated(t, client, db.ID, linodego.DatabaseEngineTypeMySQL, db.Created) + waitForDatabaseUpdated(t, ctx, client, db.ID, linodego.DatabaseEngineTypeMySQL, db.Created) if db.ID != database.ID { t.Errorf("updated db does not match original id") @@ -117,15 +119,15 @@ func TestDatabase_MySQL_Suite(t *testing.T) { // Wait for the DB to enter updating status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypeMySQL, - linodego.DatabaseStatusUpdating, 240); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypeMySQL, + linodego.DatabaseStatusUpdating); err != nil { t.Fatalf("failed to wait for database updating: %s", err) } // Wait for the DB to re-enter active status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypeMySQL, - linodego.DatabaseStatusActive, 2400); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypeMySQL, + linodego.DatabaseStatusActive); err != nil { t.Fatalf("failed to wait for database active: %s", err) } @@ -135,8 +137,8 @@ func TestDatabase_MySQL_Suite(t *testing.T) { // Wait for the DB to enter suspended status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypeMySQL, - linodego.DatabaseStatusSuspended, 240); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypeMySQL, + linodego.DatabaseStatusSuspended); err != nil { t.Fatalf("failed to wait for database suspended: %s", err) } @@ -146,8 +148,8 @@ func TestDatabase_MySQL_Suite(t *testing.T) { // Wait for the DB to re-enter active status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypeMySQL, - linodego.DatabaseStatusActive, 2400); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypeMySQL, + linodego.DatabaseStatusActive); err != nil { t.Fatalf("failed to wait for database active: %s", err) } } @@ -208,7 +210,7 @@ func createMySQLDatabase(t *testing.T, client *linodego.Client, return database, teardown, nil } -func setupMySQLDatabase(t *testing.T, databaseMofidiers []mysqlDatabaseModifier, +func setupMySQLDatabase(t *testing.T, ctx context.Context, databaseMofidiers []mysqlDatabaseModifier, fixturesYaml string, ) (*linodego.Client, *linodego.MySQLDatabase, func(), error) { t.Helper() @@ -219,8 +221,8 @@ func setupMySQLDatabase(t *testing.T, databaseMofidiers []mysqlDatabaseModifier, t.Fatalf("failed to create db: %s", err) } - _, err = client.WaitForEventFinished(context.Background(), database.ID, linodego.EntityDatabase, - linodego.ActionDatabaseCreate, now, 5400) + _, err = client.WaitForEventFinished(ctx, database.ID, linodego.EntityDatabase, + linodego.ActionDatabaseCreate, now) if err != nil { t.Fatalf("failed to wait for db create event: %s", err) } diff --git a/test/integration/postgres_db_config_test.go b/test/integration/postgres_db_config_test.go index a33bbe49e..aea156b43 100644 --- a/test/integration/postgres_db_config_test.go +++ b/test/integration/postgres_db_config_test.go @@ -4,6 +4,7 @@ import ( "context" "os" "testing" + "time" "github.com/linode/linodego" "github.com/stretchr/testify/assert" @@ -273,11 +274,13 @@ func TestDatabasePostgres_EngineConfig_Get(t *testing.T) { } func TestDatabasePostgres_EngineConfig_Suite(t *testing.T) { + ctx := waitContext(t, 6720*time.Second) + databaseModifiers := []postgresDatabaseModifier{ createPostgresOptionsModifier(), } - client, database, teardown, err := setupPostgresDatabase(t, databaseModifiers, "fixtures/TestDatabasePostgres_EngineConfig_Suite") + client, database, teardown, err := setupPostgresDatabase(t, ctx, databaseModifiers, "fixtures/TestDatabasePostgres_EngineConfig_Suite") if err != nil { t.Error(err) } @@ -308,7 +311,7 @@ func TestDatabasePostgres_EngineConfig_Suite(t *testing.T) { t.Errorf("failed to update db %d: %v", database.ID, err) } - waitForDatabaseUpdated(t, client, updatedDB.ID, linodego.DatabaseEngineTypePostgres, updatedDB.Created) + waitForDatabaseUpdated(t, ctx, client, updatedDB.ID, linodego.DatabaseEngineTypePostgres, updatedDB.Created) assertUpdatedPostgresFields(t, updatedDB.EngineConfig.PG) } diff --git a/test/integration/postgres_test.go b/test/integration/postgres_test.go index 9684d3373..b8536818c 100644 --- a/test/integration/postgres_test.go +++ b/test/integration/postgres_test.go @@ -12,7 +12,9 @@ import ( ) func TestDatabase_Postgres_Suite(t *testing.T) { - client, database, teardown, err := setupPostgresDatabase(t, nil, "fixtures/TestDatabase_Postgres_Suite") + ctx := waitContext(t, 14160*time.Second) + + client, database, teardown, err := setupPostgresDatabase(t, ctx, nil, "fixtures/TestDatabase_Postgres_Suite") if err != nil { t.Error(err) } @@ -64,7 +66,7 @@ func TestDatabase_Postgres_Suite(t *testing.T) { t.Errorf("failed to update db %d: %v", database.ID, err) } - waitForDatabaseUpdated(t, client, db.ID, linodego.DatabaseEngineTypePostgres, db.Created) + waitForDatabaseUpdated(t, ctx, client, db.ID, linodego.DatabaseEngineTypePostgres, db.Created) if db.ID != database.ID { t.Errorf("updated db does not match original id") @@ -121,15 +123,15 @@ func TestDatabase_Postgres_Suite(t *testing.T) { // Wait for the DB to enter updating status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypePostgres, - linodego.DatabaseStatusUpdating, 240); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypePostgres, + linodego.DatabaseStatusUpdating); err != nil { t.Fatalf("failed to wait for database updating: %s", err) } // Wait for the DB to re-enter active status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypePostgres, - linodego.DatabaseStatusActive, 2400); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypePostgres, + linodego.DatabaseStatusActive); err != nil { t.Fatalf("failed to wait for database updating: %s", err) } @@ -139,8 +141,8 @@ func TestDatabase_Postgres_Suite(t *testing.T) { // Wait for the DB to enter suspended status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypePostgres, - linodego.DatabaseStatusSuspended, 2400); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypePostgres, + linodego.DatabaseStatusSuspended); err != nil { t.Fatalf("failed to wait for database suspended: %s", err) } @@ -150,8 +152,8 @@ func TestDatabase_Postgres_Suite(t *testing.T) { // Wait for the DB to re-enter active status if err := client.WaitForDatabaseStatus( - context.Background(), database.ID, linodego.DatabaseEngineTypePostgres, - linodego.DatabaseStatusActive, 2400); err != nil { + ctx, database.ID, linodego.DatabaseEngineTypePostgres, + linodego.DatabaseStatusActive); err != nil { t.Fatalf("failed to wait for database active: %s", err) } } @@ -211,7 +213,7 @@ func createPostgresDatabase(t *testing.T, client *linodego.Client, return database, teardown, nil } -func setupPostgresDatabase(t *testing.T, databaseMofidiers []postgresDatabaseModifier, +func setupPostgresDatabase(t *testing.T, ctx context.Context, databaseMofidiers []postgresDatabaseModifier, fixturesYaml string, ) (*linodego.Client, *linodego.PostgresDatabase, func(), error) { t.Helper() @@ -222,8 +224,8 @@ func setupPostgresDatabase(t *testing.T, databaseMofidiers []postgresDatabaseMod t.Fatalf("failed to create db: %s", err) } - _, err = client.WaitForEventFinished(context.Background(), database.ID, linodego.EntityDatabase, - linodego.ActionDatabaseCreate, now, 5400) + _, err = client.WaitForEventFinished(ctx, database.ID, linodego.EntityDatabase, + linodego.ActionDatabaseCreate, now) if err != nil { t.Fatalf("failed to wait for db create event: %s", err) } diff --git a/test/integration/vlans_test.go b/test/integration/vlans_test.go index a861d5d7c..22c3e1b16 100644 --- a/test/integration/vlans_test.go +++ b/test/integration/vlans_test.go @@ -5,11 +5,14 @@ import ( "fmt" "regexp" "testing" + "time" "github.com/linode/linodego" ) func TestVLANs_List_smoke(t *testing.T) { + ctx := waitContext(t, 240*time.Second) + vlanName := "go-vlan-test-list" instancePrefix := "go-ins-test-list" @@ -28,7 +31,7 @@ func TestVLANs_List_smoke(t *testing.T) { } for _, instance := range instances { - if _, err := client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceRunning, 240); err != nil { + if _, err := client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceRunning); err != nil { t.Error(err) } } @@ -52,6 +55,8 @@ func TestVLANs_List_smoke(t *testing.T) { } func TestVLANs_GetIPAMAddress(t *testing.T) { + ctx := waitContext(t, 240*time.Second) + vlanName := "go-vlan-test-ipam" instancePrefix := "go-ins-test-ipam" @@ -64,7 +69,7 @@ func TestVLANs_GetIPAMAddress(t *testing.T) { } defer instanceTeardown() - _, err = client.WaitForInstanceStatus(context.Background(), instance.ID, linodego.InstanceRunning, 240) + _, err = client.WaitForInstanceStatus(ctx, instance.ID, linodego.InstanceRunning) if err != nil { t.Error(err) } diff --git a/test/integration/volumes_test.go b/test/integration/volumes_test.go index 85a218714..df998d269 100644 --- a/test/integration/volumes_test.go +++ b/test/integration/volumes_test.go @@ -67,6 +67,8 @@ func TestVolume_Create_withEncryption(t *testing.T) { } func TestVolume_Resize(t *testing.T) { + ctx := waitContext(t, 500*time.Second) + client, volume, teardown, err := setupVolume(t, "fixtures/TestVolume_Resize") defer teardown() @@ -74,7 +76,7 @@ func TestVolume_Resize(t *testing.T) { t.Errorf("Error setting up volume test, %s", err) } - _, err = client.WaitForVolumeStatus(context.Background(), volume.ID, linodego.VolumeActive, 500) + _, err = client.WaitForVolumeStatus(ctx, volume.ID, linodego.VolumeActive) if err != nil { t.Errorf("Error waiting for volume to be active, %s", err) } @@ -171,19 +173,23 @@ func TestVolume_Get_withEncryption(t *testing.T) { } func TestVolume_WaitForLinodeID_nil(t *testing.T) { + ctx := waitContext(t, 20*time.Second) + client, volume, teardown, err := setupVolume(t, "fixtures/TestVolume_WaitForLinodeID_nil") defer teardown() if err != nil { t.Errorf("Error setting up volume test, %s", err) } - _, err = client.WaitForVolumeLinodeID(context.Background(), volume.ID, nil, 20) + _, err = client.WaitForVolumeLinodeID(ctx, volume.ID, nil) if err != nil { t.Errorf("Error getting volume %d, expected *LinodeVolume, got error %v", volume.ID, err) } } func TestVolume_WaitForLinodeID(t *testing.T) { + ctx := waitContext(t, 40*time.Second) + client, instance, teardownInstance, errInstance := setupInstance(t, "fixtures/TestVolume_WaitForLinodeID_linode", true) if errInstance != nil { t.Errorf("Error setting up instance for volume test, %s", errInstance) @@ -213,7 +219,7 @@ func TestVolume_WaitForLinodeID(t *testing.T) { t.Errorf("Could not attach test volume to test instance") } - _, errWait := client.WaitForVolumeLinodeID(context.Background(), volume.ID, nil, 20) + _, errWait := client.WaitForVolumeLinodeID(ctx, volume.ID, nil) if errWait == nil { t.Errorf("Expected to timeout waiting for nil LinodeID on volume %d : %s", volume.ID, errWait) } @@ -221,7 +227,7 @@ func TestVolume_WaitForLinodeID(t *testing.T) { client, teardownWait := createTestClient(t, "fixtures/TestVolume_WaitForLinodeID_waiting") defer teardownWait() - v, errWait := client.WaitForVolumeLinodeID(context.Background(), volume.ID, &instance.ID, 20) + v, errWait := client.WaitForVolumeLinodeID(ctx, volume.ID, &instance.ID) if errWait != nil { t.Errorf("Error waiting for volume %d to attach to instance %d: %s", volume.ID, instance.ID, errWait) } diff --git a/test/integration/waitfor_test.go b/test/integration/waitfor_test.go index df388e52e..6d54f53bf 100644 --- a/test/integration/waitfor_test.go +++ b/test/integration/waitfor_test.go @@ -4,11 +4,14 @@ import ( "context" "fmt" "testing" + "time" "github.com/linode/linodego" ) func TestEventPoller_InstancePower(t *testing.T) { + ctx := waitContext(t, 520*time.Second) + client, fixtureTeardown := createTestClient(t, "fixtures/TestEventPoller_InstancePower") t.Cleanup(fixtureTeardown) @@ -37,7 +40,7 @@ func TestEventPoller_InstancePower(t *testing.T) { p.EntityID = instance.ID - if _, err := p.WaitForFinished(context.Background(), 120); err != nil { + if _, err := p.WaitForFinished(ctx); err != nil { t.Fatal(err) } @@ -52,7 +55,7 @@ func TestEventPoller_InstancePower(t *testing.T) { t.Fatal(err) } - event, err := p.WaitForFinished(context.Background(), 200) + event, err := p.WaitForFinished(ctx) if err != nil { t.Fatal(err) } @@ -77,7 +80,7 @@ func TestEventPoller_InstancePower(t *testing.T) { t.Fatal(err) } - event, err = p.WaitForFinished(context.Background(), 200) + event, err = p.WaitForFinished(ctx) if err != nil { t.Fatal(err) } @@ -97,6 +100,8 @@ func TestEventPoller_InstancePower(t *testing.T) { } func TestWaitForResourceFree(t *testing.T) { + ctx := waitContext(t, 240*time.Second) + client, fixtureTeardown := createTestClient(t, "fixtures/TestWaitForResourceFree") t.Cleanup(fixtureTeardown) @@ -119,7 +124,7 @@ func TestWaitForResourceFree(t *testing.T) { }) // Wait for the instance to be done with all events - err = client.WaitForResourceFree(context.Background(), linodego.EntityLinode, instance.ID, 240) + err = client.WaitForResourceFree(ctx, linodego.EntityLinode, instance.ID) if err != nil { t.Fatal(err) } @@ -136,6 +141,8 @@ func TestWaitForResourceFree(t *testing.T) { } func TestEventPoller_Secondary(t *testing.T) { + ctx := waitContext(t, 240*time.Second) + client, fixtureTeardown := createTestClient(t, "fixtures/TestEventPoller_Secondary") defer fixtureTeardown() @@ -162,7 +169,7 @@ func TestEventPoller_Secondary(t *testing.T) { createPoller.EntityID = instance.ID - if _, err := createPoller.WaitForFinished(context.Background(), 120); err != nil { + if _, err := createPoller.WaitForFinished(ctx); err != nil { t.Fatal(err) } @@ -211,7 +218,7 @@ func TestEventPoller_Secondary(t *testing.T) { } // Wait for the first disk to be deleted - deleteEvent, err := diskPoller.WaitForFinished(context.Background(), 60) + deleteEvent, err := diskPoller.WaitForFinished(ctx) if err != nil { t.Fatal(err) } @@ -219,7 +226,7 @@ func TestEventPoller_Secondary(t *testing.T) { // Poll for the second disk to be deleted. // This is necessary to cover an edge case that triggers a panic // when other deletion events with a null SecondaryEntity are discovered. - if _, err := diskPoller2.WaitForFinished(context.Background(), 60); err != nil { + if _, err := diskPoller2.WaitForFinished(ctx); err != nil { t.Fatal(err) } diff --git a/test/unit/waitfor_test.go b/test/unit/waitfor_test.go new file mode 100644 index 000000000..c0058ee08 --- /dev/null +++ b/test/unit/waitfor_test.go @@ -0,0 +1,144 @@ +package unit + +import ( + "context" + "net/http" + "regexp" + "testing" + "time" + + "github.com/jarcoal/httpmock" + "github.com/linode/linodego" +) + +func TestWaitForInstanceStatusUsesContextDeadline(t *testing.T) { + client := createMockClient(t) + client.SetPollDelay(time.Millisecond) + + httpmock.RegisterRegexpResponder("GET", mockRequestURL(t, "linode/instances/123"), + func(_ *http.Request) (*http.Response, error) { + return httpmock.NewJsonResponse(http.StatusOK, linodego.Instance{ID: 123, Status: linodego.InstanceProvisioning}) + }) + + _, err := client.WaitForInstanceStatus(waitTestContext(t, 5*time.Millisecond), 123, linodego.InstanceRunning) + if err == nil { + t.Fatal("expected deadline error") + } +} + +func TestWaitForVolumeStatusSuccess(t *testing.T) { + client := createMockClient(t) + client.SetPollDelay(time.Millisecond) + + step := 0 + httpmock.RegisterRegexpResponder("GET", mockRequestURL(t, "volumes/123"), + func(_ *http.Request) (*http.Response, error) { + step++ + + status := linodego.VolumeCreating + if step == 2 { + status = linodego.VolumeActive + } + + return httpmock.NewJsonResponse(http.StatusOK, linodego.Volume{ID: 123, Status: status}) + }) + + volume, err := client.WaitForVolumeStatus(waitTestContext(t, time.Second), 123, linodego.VolumeActive) + if err != nil { + t.Fatal(err) + } + + if volume.Status != linodego.VolumeActive { + t.Fatalf("expected volume to be active, got %s", volume.Status) + } + + if step != 2 { + t.Fatalf("expected 2 polls, got %d", step) + } +} + +func TestWaitForVolumeLinodeIDNil(t *testing.T) { + client := createMockClient(t) + client.SetPollDelay(time.Millisecond) + + httpmock.RegisterRegexpResponder("GET", mockRequestURL(t, "volumes/123"), + func(_ *http.Request) (*http.Response, error) { + return httpmock.NewJsonResponse(http.StatusOK, linodego.Volume{ID: 123, LinodeID: nil}) + }) + + volume, err := client.WaitForVolumeLinodeID(waitTestContext(t, time.Second), 123, nil) + if err != nil { + t.Fatal(err) + } + + if volume.LinodeID != nil { + t.Fatalf("expected nil LinodeID, got %v", volume.LinodeID) + } +} + +func TestEventPollerWaitForFinished(t *testing.T) { + client := createMockClient(t) + client.SetPollDelay(time.Millisecond) + + listEventsCount := 0 + httpmock.RegisterRegexpResponder("GET", regexp.MustCompile(`/[a-zA-Z0-9]+/account/events(\?.*)?$`), + func(_ *http.Request) (*http.Response, error) { + listEventsCount++ + + events := []linodego.Event{{ + ID: 111, + Status: linodego.EventFinished, + Action: linodego.ActionLinodeBoot, + Entity: &linodego.EventEntity{ID: 123, Type: linodego.EntityLinode}, + }} + + if listEventsCount > 1 { + events = append(events, linodego.Event{ + ID: 456, + Status: linodego.EventStarted, + Action: linodego.ActionLinodeBoot, + Entity: &linodego.EventEntity{ID: 123, Type: linodego.EntityLinode}, + }) + } + + return httpmock.NewJsonResponse(http.StatusOK, map[string]any{ + "data": events, + "page": 1, + "pages": 1, + "results": len(events), + }) + }) + + poller, err := client.NewEventPoller( + context.Background(), + 123, + linodego.EntityLinode, + linodego.ActionLinodeBoot, + ) + if err != nil { + t.Fatal(err) + } + + httpmock.RegisterRegexpResponder("GET", regexp.MustCompile(`/[a-zA-Z0-9]+/account/events/456$`), + func(_ *http.Request) (*http.Response, error) { + return httpmock.NewJsonResponse(http.StatusOK, linodego.Event{ID: 456, Status: linodego.EventFinished}) + }) + + event, err := poller.WaitForFinished(waitTestContext(t, time.Second)) + if err != nil { + t.Fatal(err) + } + + if event.Status != linodego.EventFinished { + t.Fatalf("expected event to be finished, got %s", event.Status) + } +} + +func waitTestContext(t *testing.T, timeout time.Duration) context.Context { + t.Helper() + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + t.Cleanup(cancel) + + return ctx +} diff --git a/waitfor.go b/waitfor.go index d40d47e1c..9a5d9a97f 100644 --- a/waitfor.go +++ b/waitfor.go @@ -15,6 +15,7 @@ import ( var englishTitle = cases.Title(language.English) +// EventPoller waits for events associated with a given entity and action. type EventPoller struct { EntityID any EntityType EntityType @@ -30,189 +31,137 @@ type EventPoller struct { } // WaitForInstanceStatus waits for the Linode instance to reach the desired state -// before returning. It will timeout with an error after timeoutSeconds. -func (client Client) WaitForInstanceStatus(ctx context.Context, instanceID int, status InstanceStatus, timeoutSeconds int) (*Instance, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: +// before returning. +func (client Client) WaitForInstanceStatus(ctx context.Context, instanceID int, status InstanceStatus) (*Instance, error) { + return poll(ctx, &client, + func(ctx context.Context) (*Instance, bool, error) { instance, err := client.GetInstance(ctx, instanceID) if err != nil { - return instance, err + return instance, false, err } - complete := (instance.Status == status) - - if complete { - return instance, nil - } - case <-ctx.Done(): - return nil, fmt.Errorf("Error waiting for Instance %d status %s: %w", instanceID, status, ctx.Err()) - } - } + return instance, instance.Status == status, nil + }, + func() error { + return fmt.Errorf("Error waiting for Instance %d status %s: %w", instanceID, status, ctx.Err()) + }, + ) } // WaitForInstanceDiskStatus waits for the Linode instance disk to reach the desired state -// before returning. It will timeout with an error after timeoutSeconds. -func (client Client) WaitForInstanceDiskStatus(ctx context.Context, instanceID int, diskID int, status DiskStatus, timeoutSeconds int) (*InstanceDisk, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - // GetInstanceDisk will 404 on newly created disks. use List instead. - // disk, err := client.GetInstanceDisk(ctx, instanceID, diskID) +// before returning. +func (client Client) WaitForInstanceDiskStatus(ctx context.Context, instanceID int, diskID int, status DiskStatus) (*InstanceDisk, error) { + return poll(ctx, &client, + func(ctx context.Context) (*InstanceDisk, bool, error) { + // GetInstanceDisk will 404 on newly created disks. Use List instead. disks, err := client.ListInstanceDisks(ctx, instanceID, nil) if err != nil { - return nil, err + return nil, false, err } for _, disk := range disks { if disk.ID == diskID { - complete := (disk.Status == status) - if complete { - return &disk, nil + if disk.Status == status { + return &disk, true, nil } break } } - case <-ctx.Done(): - return nil, fmt.Errorf("Error waiting for Instance %d Disk %d status %s: %w", instanceID, diskID, status, ctx.Err()) - } - } + + return nil, false, nil + }, + func() error { + return fmt.Errorf("Error waiting for Instance %d Disk %d status %s: %w", instanceID, diskID, status, ctx.Err()) + }, + ) } // WaitForVolumeStatus waits for the Volume to reach the desired state -// before returning. It will timeout with an error after timeoutSeconds. -func (client Client) WaitForVolumeStatus(ctx context.Context, volumeID int, status VolumeStatus, timeoutSeconds int) (*Volume, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: +// before returning. +func (client Client) WaitForVolumeStatus(ctx context.Context, volumeID int, status VolumeStatus) (*Volume, error) { + return poll(ctx, &client, + func(ctx context.Context) (*Volume, bool, error) { volume, err := client.GetVolume(ctx, volumeID) if err != nil { - return volume, err + return volume, false, err } - complete := (volume.Status == status) - - if complete { - return volume, nil - } - case <-ctx.Done(): - return nil, fmt.Errorf("Error waiting for Volume %d status %s: %w", volumeID, status, ctx.Err()) - } - } + return volume, volume.Status == status, nil + }, + func() error { + return fmt.Errorf("Error waiting for Volume %d status %s: %w", volumeID, status, ctx.Err()) + }, + ) } // WaitForSnapshotStatus waits for the Snapshot to reach the desired state -// before returning. It will timeout with an error after timeoutSeconds. +// before returning. func (client Client) WaitForSnapshotStatus( ctx context.Context, instanceID int, snapshotID int, status InstanceSnapshotStatus, - timeoutSeconds int, ) (*InstanceSnapshot, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: + return poll(ctx, &client, + func(ctx context.Context) (*InstanceSnapshot, bool, error) { snapshot, err := client.GetInstanceSnapshot(ctx, instanceID, snapshotID) if err != nil { - return snapshot, err + return snapshot, false, err } - complete := (snapshot.Status == status) - - if complete { - return snapshot, nil - } - case <-ctx.Done(): - return nil, fmt.Errorf("Error waiting for Instance %d Snapshot %d status %s: %w", instanceID, snapshotID, status, ctx.Err()) - } - } + return snapshot, snapshot.Status == status, nil + }, + func() error { + return fmt.Errorf("Error waiting for Instance %d Snapshot %d status %s: %w", instanceID, snapshotID, status, ctx.Err()) + }, + ) } // WaitForVolumeLinodeID waits for the Volume to match the desired LinodeID // before returning. An active Instance will not immediately attach or detach a volume, so // the LinodeID must be polled to determine volume readiness from the API. -// WaitForVolumeLinodeID will timeout with an error after timeoutSeconds. -func (client Client) WaitForVolumeLinodeID(ctx context.Context, volumeID int, linodeID *int, timeoutSeconds int) (*Volume, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: +func (client Client) WaitForVolumeLinodeID(ctx context.Context, volumeID int, linodeID *int) (*Volume, error) { + return poll(ctx, &client, + func(ctx context.Context) (*Volume, bool, error) { volume, err := client.GetVolume(ctx, volumeID) if err != nil { - return volume, err + return volume, false, err } switch { case linodeID == nil && volume.LinodeID == nil: - return volume, nil + return volume, true, nil case linodeID == nil || volume.LinodeID == nil: - // continue waiting + // Continue waiting. case *volume.LinodeID == *linodeID: - return volume, nil + return volume, true, nil } - case <-ctx.Done(): - return nil, fmt.Errorf("Error waiting for Volume %d to have Instance %v: %w", volumeID, linodeID, ctx.Err()) - } - } + + return volume, false, nil + }, + func() error { + return fmt.Errorf("Error waiting for Volume %d to have Instance %v: %w", volumeID, linodeID, ctx.Err()) + }, + ) } // WaitForLKEClusterStatus waits for the LKECluster to reach the desired state -// before returning. It will timeout with an error after timeoutSeconds. -func (client Client) WaitForLKEClusterStatus(ctx context.Context, clusterID int, status LKEClusterStatus, timeoutSeconds int) (*LKECluster, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: +// before returning. +func (client Client) WaitForLKEClusterStatus(ctx context.Context, clusterID int, status LKEClusterStatus) (*LKECluster, error) { + return poll(ctx, &client, + func(ctx context.Context) (*LKECluster, bool, error) { cluster, err := client.GetLKECluster(ctx, clusterID) if err != nil { - return cluster, err + return cluster, false, err } - complete := (cluster.Status == status) - - if complete { - return cluster, nil - } - case <-ctx.Done(): - return nil, fmt.Errorf("Error waiting for Cluster %d status %s: %w", clusterID, status, ctx.Err()) - } - } + return cluster, cluster.Status == status, nil + }, + func() error { + return fmt.Errorf("Error waiting for Cluster %d status %s: %w", clusterID, status, ctx.Err()) + }, + ) } // LKEClusterPollOptions configures polls against LKE Clusters. @@ -220,15 +169,12 @@ type LKEClusterPollOptions struct { // Retry will cause the Poll to ignore interimittent errors Retry bool - // TimeoutSeconds is the number of Seconds to wait for the poll to succeed - // before exiting. - TimeoutSeconds int - // TansportWrapper allows adding a transport middleware function that will // wrap the LKE Cluster client's underlying http.RoundTripper. TransportWrapper func(http.RoundTripper) http.RoundTripper } +// ClusterConditionOptions configures LKE cluster condition checks. type ClusterConditionOptions struct { LKEClusterKubeconfig *LKEClusterKubeconfig TransportWrapper func(http.RoundTripper) http.RoundTripper @@ -245,18 +191,12 @@ func (client Client) WaitForLKEClusterConditions( options LKEClusterPollOptions, conditions ...ClusterConditionFunc, ) error { - ctx, cancel := context.WithCancel(ctx) - if options.TimeoutSeconds != 0 { - ctx, cancel = context.WithTimeout(ctx, time.Duration(options.TimeoutSeconds)*time.Second) - } - defer cancel() - lkeKubeConfig, err := client.GetLKEClusterKubeconfig(ctx, clusterID) if err != nil { return fmt.Errorf("failed to get Kubeconfig for LKE cluster %d: %w", clusterID, err) } - ticker := time.NewTicker(client.pollInterval) + ticker := newTicker(&client) defer ticker.Stop() conditionOptions := ClusterConditionOptions{LKEClusterKubeconfig: lkeKubeConfig, TransportWrapper: options.TransportWrapper} @@ -289,7 +229,7 @@ func (client Client) WaitForLKEClusterConditions( } // WaitForEventFinished waits for an entity action to reach the 'finished' state -// before returning. It will timeout with an error after timeoutSeconds. +// before returning. // If the event indicates a failure both the failed event and the error will be returned. // nolint func (client Client) WaitForEventFinished( @@ -298,7 +238,6 @@ func (client Client) WaitForEventFinished( entityType EntityType, action EventAction, minStart time.Time, - timeoutSeconds int, ) (*Event, error) { titledEntityType := englishTitle.String(string(entityType)) filter := Filter{ @@ -326,15 +265,11 @@ func (client Client) WaitForEventFinished( filter.AddField(Eq, "entity.type", entityType) } - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - if deadline, ok := ctx.Deadline(); ok { - duration := time.Until(deadline) - log.Printf("[INFO] Waiting %d seconds for %s events since %v for %s %v", int(duration.Seconds()), action, minStart, titledEntityType, id) + log.Printf("[INFO] Waiting %d seconds for %s events since %v for %s %v", int(time.Until(deadline).Seconds()), action, minStart, titledEntityType, id) } - ticker := time.NewTicker(client.pollInterval) + ticker := newTicker(&client) // avoid repeating log messages nextLog := "" @@ -363,8 +298,6 @@ func (client Client) WaitForEventFinished( // If there are events for this instance + action, inspect them for _, event := range events { - event := event - if event.Entity == nil || event.Entity.Type != entityType { // log.Println("type mismatch", event.Entity.Type, entityType) continue @@ -382,6 +315,7 @@ func (client Client) WaitForEventFinished( } var findID string + switch id := id.(type) { case float64, float32: findID = fmt.Sprintf("%.f", id) @@ -428,45 +362,31 @@ func (client Client) WaitForEventFinished( } // WaitForImageStatus waits for the Image to reach the desired state -// before returning. It will timeout with an error after timeoutSeconds. -func (client Client) WaitForImageStatus(ctx context.Context, imageID string, status ImageStatus, timeoutSeconds int) (*Image, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: +// before returning. +func (client Client) WaitForImageStatus(ctx context.Context, imageID string, status ImageStatus) (*Image, error) { + return poll(ctx, &client, + func(ctx context.Context) (*Image, bool, error) { image, err := client.GetImage(ctx, imageID) if err != nil { - return image, err + return image, false, err } - complete := image.Status == status - - if complete { - return image, nil - } - case <-ctx.Done(): - return nil, fmt.Errorf("failed to wait for Image %s status %s: %w", imageID, status, ctx.Err()) - } - } + return image, image.Status == status, nil + }, + func() error { + return fmt.Errorf("failed to wait for Image %s status %s: %w", imageID, status, ctx.Err()) + }, + ) } // WaitForImageRegionStatus waits for an Image's replica to reach the desired state // before returning. func (client Client) WaitForImageRegionStatus(ctx context.Context, imageID, region string, status ImageRegionStatus) (*Image, error) { - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: + return poll(ctx, &client, + func(ctx context.Context) (*Image, bool, error) { image, err := client.GetImage(ctx, imageID) if err != nil { - return image, err + return image, false, err } replicaIdx := slices.IndexFunc( @@ -476,17 +396,16 @@ func (client Client) WaitForImageRegionStatus(ctx context.Context, imageID, regi }, ) - // If no replica was found or the status doesn't match, try again if replicaIdx < 0 || image.Regions[replicaIdx].Status != status { - continue + return image, false, nil } - return image, nil - - case <-ctx.Done(): - return nil, fmt.Errorf("failed to wait for Image %s status %s: %w", imageID, status, ctx.Err()) - } - } + return image, true, nil + }, + func() error { + return fmt.Errorf("failed to wait for Image %s status %s: %w", imageID, status, ctx.Err()) + }, + ) } type databaseStatusFunc func(ctx context.Context, client Client, dbID int) (DatabaseStatus, error) @@ -512,34 +431,28 @@ var databaseStatusHandlers = map[DatabaseEngineType]databaseStatusFunc{ // WaitForDatabaseStatus waits for the provided database to have the given status. func (client Client) WaitForDatabaseStatus( - ctx context.Context, dbID int, dbEngine DatabaseEngineType, status DatabaseStatus, timeoutSeconds int, + ctx context.Context, dbID int, dbEngine DatabaseEngineType, status DatabaseStatus, ) error { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: + _, err := poll(ctx, &client, + func(ctx context.Context) (struct{}, bool, error) { statusHandler, ok := databaseStatusHandlers[dbEngine] if !ok { - return fmt.Errorf("invalid db engine: %s", dbEngine) + return struct{}{}, false, fmt.Errorf("invalid db engine: %s", dbEngine) } currentStatus, err := statusHandler(ctx, client, dbID) if err != nil { - return fmt.Errorf("failed to get db status: %w", err) + return struct{}{}, false, fmt.Errorf("failed to get db status: %w", err) } - if currentStatus == status { - return nil - } - case <-ctx.Done(): + return struct{}{}, currentStatus == status, nil + }, + func() error { return fmt.Errorf("failed to wait for database %d status: %w", dbID, ctx.Err()) - } - } + }, + ) + + return err } // NewEventPoller initializes a new Linode event poller. This should be run before the event is triggered as it stores @@ -555,7 +468,7 @@ func (client Client) NewEventPoller( client: client, } - if err := result.PreTask(ctx); err != nil { + if err := result.preTask(ctx); err != nil { return nil, fmt.Errorf("failed to run pretask: %w", err) } @@ -597,42 +510,9 @@ func (client Client) NewEventPollerWithoutEntity(entityType EntityType, action E return &result, nil } -// PreTask stores all current events for the given entity to prevent them from being -// processed on subsequent runs. -func (p *EventPoller) PreTask(ctx context.Context) error { - f := Filter{ - OrderBy: "created", - Order: Descending, - } - f.AddField(Eq, "entity.type", p.EntityType) - f.AddField(Eq, "entity.id", p.EntityID) - f.AddField(Eq, "action", p.Action) - - fBytes, err := f.MarshalJSON() - if err != nil { - return err - } - - events, err := p.client.ListEvents(ctx, &ListOptions{ - Filter: string(fBytes), - PageOptions: &PageOptions{Page: 1}, - }) - if err != nil { - return fmt.Errorf("failed to list events: %w", err) - } - - eventIDs := make(map[int]bool, len(events)) - for _, event := range events { - eventIDs[event.ID] = true - } - - p.previousEvents = eventIDs - - return nil -} - +// WaitForLatestUnknownEvent waits for the next event not observed by this poller. func (p *EventPoller) WaitForLatestUnknownEvent(ctx context.Context) (*Event, error) { - ticker := time.NewTicker(p.client.pollInterval) + ticker := newTicker(&p.client) defer ticker.Stop() f := Filter{ @@ -681,13 +561,8 @@ func (p *EventPoller) WaitForLatestUnknownEvent(ctx context.Context) (*Event, er } // WaitForFinished waits for a new event to be finished. -func (p *EventPoller) WaitForFinished( - ctx context.Context, timeoutSeconds int, -) (*Event, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(p.client.pollInterval) +func (p *EventPoller) WaitForFinished(ctx context.Context) (*Event, error) { + ticker := newTicker(&p.client) defer ticker.Stop() event, err := p.WaitForLatestUnknownEvent(ctx) @@ -719,7 +594,7 @@ func (p *EventPoller) WaitForFinished( // WaitForResourceFree waits for a resource to have no running events. func (client Client) WaitForResourceFree( - ctx context.Context, entityType EntityType, entityID any, timeoutSeconds int, + ctx context.Context, entityType EntityType, entityID any, ) error { apiFilter := Filter{ Order: Descending, @@ -733,10 +608,7 @@ func (client Client) WaitForResourceFree( return fmt.Errorf("failed to create filter: %s", err) } - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) + ticker := newTicker(&client) defer ticker.Stop() // A helper function to determine whether a resource is busy @@ -796,29 +668,20 @@ func (client Client) WaitForAlertDefinitionStatus( status AlertDefinitionStatus, serviceType string, alertID int, - timeoutSeconds int, ) (*AlertDefinition, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() - - ticker := time.NewTicker(client.pollInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: + return poll(ctx, &client, + func(ctx context.Context) (*AlertDefinition, bool, error) { alertDef, err := client.GetMonitorAlertDefinition(ctx, serviceType, alertID) if err != nil { - return alertDef, err + return alertDef, false, err } - if alertDef.Status == status { - return alertDef, nil - } - case <-ctx.Done(): - return nil, fmt.Errorf("failed to wait for AlertDefinition %d status %s: %w", alertID, status, ctx.Err()) - } - } + return alertDef, alertDef.Status == status, nil + }, + func() error { + return fmt.Errorf("failed to wait for AlertDefinition %d status %s: %w", alertID, status, ctx.Err()) + }, + ) } // WaitForVolumeIOReadyStatus waits for the io_ready status to verify whether the volume is @@ -827,28 +690,86 @@ func (client Client) WaitForVolumeIOReadyStatus( ctx context.Context, volumeID int, status bool, - timeoutSeconds int, ) (*Volume, error) { - ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) - defer cancel() + return poll(ctx, &client, + func(ctx context.Context) (*Volume, bool, error) { + volume, err := client.GetVolume(ctx, volumeID) + if err != nil { + return volume, false, fmt.Errorf("failed to get volume: %w", err) + } - ticker := time.NewTicker(client.pollInterval) + return volume, volume.IOReady == status, nil + }, + func() error { + return fmt.Errorf("failed to wait for Volume %d IO Ready status %t: %w", volumeID, status, ctx.Err()) + }, + ) +} + +// preTask stores all current events for the given entity to prevent them from being +// processed on subsequent runs. +func (p *EventPoller) preTask(ctx context.Context) error { + f := Filter{ + OrderBy: "created", + Order: Descending, + } + f.AddField(Eq, "entity.type", p.EntityType) + f.AddField(Eq, "entity.id", p.EntityID) + f.AddField(Eq, "action", p.Action) + + fBytes, err := f.MarshalJSON() + if err != nil { + return err + } + + events, err := p.client.ListEvents(ctx, &ListOptions{ + Filter: string(fBytes), + PageOptions: &PageOptions{Page: 1}, + }) + if err != nil { + return fmt.Errorf("failed to list events: %w", err) + } + + eventIDs := make(map[int]bool, len(events)) + for _, event := range events { + eventIDs[event.ID] = true + } + + p.previousEvents = eventIDs + + return nil +} + +// poll runs check on each tick until check reports done, returns an error, or ctx is canceled. +// +//nolint:ireturn // false positive: returning a generic concrete type, not an interface +func poll[T any]( + ctx context.Context, + client *Client, + check func(context.Context) (T, bool, error), + timeoutErr func() error, +) (T, error) { + ticker := newTicker(client) defer ticker.Stop() for { select { case <-ticker.C: - volume, err := client.GetVolume(ctx, volumeID) + result, done, err := check(ctx) if err != nil { - return volume, err + return result, err } - if volume.IOReady == status { - return volume, nil + if done { + return result, nil } - case <-ctx.Done(): - return nil, fmt.Errorf("failed to wait for Volume %d IO Ready status %t: %w", volumeID, status, ctx.Err()) + var zero T + return zero, timeoutErr() } } } + +func newTicker(client *Client) *time.Ticker { + return time.NewTicker(client.GetPollDelay()) +} From 2a91d1ec7147965bc7b52749460bcdc875c59088 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Thu, 14 May 2026 13:32:11 -0400 Subject: [PATCH 08/17] TPT-4422: Added options structs for POST/PUT endpoints that were missing them (#968) * Added options structs for POST/PUT endpoints that were missing them * Address PR comments * Address PR comments --- account_oauth_client.go | 2 +- instance_disks.go | 26 +++++++++---------- instance_ips.go | 15 ++++++----- instance_snapshots.go | 8 +++--- instances.go | 24 +++++++---------- request_helpers.go | 10 +++++++ .../integration/example_nodebalancers_test.go | 5 +++- test/integration/iam_io_ready_test.go | 6 +++-- test/integration/instance_snapshots_test.go | 4 ++- test/integration/instances_test.go | 21 ++++++++++----- test/integration/network_ips_test.go | 10 +++++-- .../nodebalancer_config_nodes_test.go | 5 +++- test/integration/volumes_test.go | 5 +++- test/integration/waitfor_test.go | 5 +++- test/unit/instance_backup_test.go | 4 ++- test/unit/instance_disks_test.go | 12 +++++---- test/unit/instance_ip_test.go | 4 ++- test/unit/instance_test.go | 8 ++++-- test/unit/volume_test.go | 4 ++- volumes.go | 20 +++++++------- 20 files changed, 125 insertions(+), 73 deletions(-) diff --git a/account_oauth_client.go b/account_oauth_client.go index 7b0e7795a..c330bc9b2 100644 --- a/account_oauth_client.go +++ b/account_oauth_client.go @@ -111,5 +111,5 @@ func (c *Client) DeleteOAuthClient(ctx context.Context, clientID string) error { // ResetOAuthClientSecret resets the OAuth Client secret for a client with a specified id func (c *Client) ResetOAuthClientSecret(ctx context.Context, clientID string) (*OAuthClient, error) { e := formatAPIPath("account/oauth-clients/%s/reset-secret", clientID) - return doPOSTRequest[OAuthClient, any](ctx, c, e) + return doPOSTRequestNoRequestBody[OAuthClient](ctx, c, e) } diff --git a/instance_disks.go b/instance_disks.go index 375dd8ca6..380c2c652 100644 --- a/instance_disks.go +++ b/instance_disks.go @@ -63,7 +63,15 @@ type InstanceDiskUpdateOptions struct { Label string `json:"label"` } -type InstanceDiskCloneOptions struct{} +// InstanceDiskResizeOptions are InstanceDisk settings that can be used in resizes +type InstanceDiskResizeOptions struct { + Size int `json:"size"` +} + +// InstanceDiskPasswordResetOptions are InstanceDisk settings that can be used in password resets +type InstanceDiskPasswordResetOptions struct { + Password string `json:"password"` +} // ListInstanceDisks lists InstanceDisks func (c *Client) ListInstanceDisks(ctx context.Context, linodeID int, opts *ListOptions) ([]InstanceDisk, error) { @@ -117,22 +125,14 @@ func (c *Client) RenameInstanceDisk(ctx context.Context, linodeID int, diskID in } // ResizeInstanceDisk resizes the size of the Instance disk -func (c *Client) ResizeInstanceDisk(ctx context.Context, linodeID int, diskID int, size int) error { - opts := map[string]any{ - "size": size, - } - +func (c *Client) ResizeInstanceDisk(ctx context.Context, linodeID int, diskID int, opts InstanceDiskResizeOptions) error { e := formatAPIPath("linode/instances/%d/disks/%d/resize", linodeID, diskID) return doPOSTRequestNoResponseBody(ctx, c, e, opts) } // PasswordResetInstanceDisk resets the "root" account password on the Instance disk -func (c *Client) PasswordResetInstanceDisk(ctx context.Context, linodeID int, diskID int, password string) error { - opts := map[string]any{ - "password": password, - } - +func (c *Client) PasswordResetInstanceDisk(ctx context.Context, linodeID int, diskID int, opts InstanceDiskPasswordResetOptions) error { e := formatAPIPath("linode/instances/%d/disks/%d/password", linodeID, diskID) return doPOSTRequestNoResponseBody(ctx, c, e, opts) @@ -145,7 +145,7 @@ func (c *Client) DeleteInstanceDisk(ctx context.Context, linodeID int, diskID in } // CloneInstanceDisk clones the given InstanceDisk for the given Instance -func (c *Client) CloneInstanceDisk(ctx context.Context, linodeID, diskID int, opts InstanceDiskCloneOptions) (*InstanceDisk, error) { +func (c *Client) CloneInstanceDisk(ctx context.Context, linodeID, diskID int) (*InstanceDisk, error) { e := formatAPIPath("linode/instances/%d/disks/%d/clone", linodeID, diskID) - return doPOSTRequest[InstanceDisk](ctx, c, e, opts) + return doPOSTRequestNoRequestBody[InstanceDisk](ctx, c, e) } diff --git a/instance_ips.go b/instance_ips.go index 05724238b..281fb9574 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -35,6 +35,11 @@ type InstanceIP struct { Reserved bool `json:"reserved"` } +type InstanceIPAddOptions struct { + Type string `json:"type"` + Public bool `json:"public"` +} + type InstanceIPAddressUpdateOptions struct { RDNS **string `json:"rdns,omitzero"` } @@ -131,15 +136,11 @@ func (c *Client) GetInstanceIPAddress(ctx context.Context, linodeID int, ipaddre } // AddInstanceIPAddress adds a public or private IP to a Linode instance -func (c *Client) AddInstanceIPAddress(ctx context.Context, linodeID int, public bool) (*InstanceIP, error) { - instanceipRequest := struct { - Type string `json:"type"` - Public bool `json:"public"` - }{"ipv4", public} - +func (c *Client) AddInstanceIPAddress(ctx context.Context, linodeID int, opts InstanceIPAddOptions) (*InstanceIP, error) { + opts.Type = "ipv4" e := formatAPIPath("linode/instances/%d/ips", linodeID) - return doPOSTRequest[InstanceIP](ctx, c, e, instanceipRequest) + return doPOSTRequest[InstanceIP](ctx, c, e, opts) } // UpdateInstanceIPAddress updates the IPAddress with the specified instance id and IP address diff --git a/instance_snapshots.go b/instance_snapshots.go index a2eedc9cf..241bd3267 100644 --- a/instance_snapshots.go +++ b/instance_snapshots.go @@ -20,6 +20,10 @@ type InstanceBackupSnapshotResponse struct { InProgress *InstanceSnapshot `json:"in_progress"` } +type InstanceSnapshotCreateOptions struct { + Label string `json:"label"` +} + // RestoreInstanceOptions fields are those accepted by InstanceRestore type RestoreInstanceOptions struct { LinodeID int `json:"linode_id"` @@ -93,9 +97,7 @@ func (c *Client) GetInstanceSnapshot(ctx context.Context, linodeID int, snapshot } // CreateInstanceSnapshot Creates or Replaces the snapshot Backup of a Linode. If a previous snapshot exists for this Linode, it will be deleted. -func (c *Client) CreateInstanceSnapshot(ctx context.Context, linodeID int, label string) (*InstanceSnapshot, error) { - opts := map[string]string{"label": label} - +func (c *Client) CreateInstanceSnapshot(ctx context.Context, linodeID int, opts InstanceSnapshotCreateOptions) (*InstanceSnapshot, error) { e := formatAPIPath("linode/instances/%d/backups", linodeID) return doPOSTRequest[InstanceSnapshot](ctx, c, e, opts) diff --git a/instances.go b/instances.go index b0a602d2e..7a1a1eae1 100644 --- a/instances.go +++ b/instances.go @@ -380,6 +380,14 @@ type InstanceResizeOptions struct { AllowAutoDiskResize *bool `json:"allow_auto_disk_resize,omitzero"` } +type InstanceBootOptions struct { + ConfigID *int `json:"config_id,omitzero"` +} + +type InstanceRebootOptions struct { + ConfigID *int `json:"config_id,omitzero"` +} + // InstanceMigrateOptions is an options struct used when migrating an instance type InstanceMigrateOptions struct { Type InstanceMigrationType `json:"type,omitzero"` @@ -436,13 +444,7 @@ func (c *Client) DeleteInstance(ctx context.Context, linodeID int) error { // BootInstance will boot a Linode instance // A configID of 0 will cause Linode to choose the last/best config -func (c *Client) BootInstance(ctx context.Context, linodeID int, configID int) error { - opts := make(map[string]int) - - if configID != 0 { - opts = map[string]int{"config_id": configID} - } - +func (c *Client) BootInstance(ctx context.Context, linodeID int, opts InstanceBootOptions) error { e := formatAPIPath("linode/instances/%d/boot", linodeID) return doPOSTRequestNoResponseBody(ctx, c, e, opts) @@ -462,13 +464,7 @@ func (c *Client) ResetInstancePassword(ctx context.Context, linodeID int, opts I // RebootInstance reboots a Linode instance // A configID of 0 will cause Linode to choose the last/best config -func (c *Client) RebootInstance(ctx context.Context, linodeID int, configID int) error { - opts := make(map[string]int) - - if configID != 0 { - opts = map[string]int{"config_id": configID} - } - +func (c *Client) RebootInstance(ctx context.Context, linodeID int, opts InstanceRebootOptions) error { e := formatAPIPath("linode/instances/%d/reboot", linodeID) return doPOSTRequestNoResponseBody(ctx, c, e, opts) diff --git a/request_helpers.go b/request_helpers.go index 3efdeca3b..970c22d14 100644 --- a/request_helpers.go +++ b/request_helpers.go @@ -213,6 +213,16 @@ func doPOSTRequest[T, O any]( return &resultType, nil } +// doPOSTRequestNoRequestBody runs a POST request using the given client and API endpoint. +// It does not expect a request body but does expect a response from the endpoint. +func doPOSTRequestNoRequestBody[T any]( + ctx context.Context, + client *Client, + endpoint string, +) (*T, error) { + return doPOSTRequest[T, any](ctx, client, endpoint) +} + // doPOSTRequestNoResponseBody runs a POST request using the given client, API endpoint, // and options/body. It expects only empty response from the endpoint. func doPOSTRequestNoResponseBody[T any]( diff --git a/test/integration/example_nodebalancers_test.go b/test/integration/example_nodebalancers_test.go index ecb3eb81d..ed8f6217d 100644 --- a/test/integration/example_nodebalancers_test.go +++ b/test/integration/example_nodebalancers_test.go @@ -167,7 +167,10 @@ func ExampleClient_CreateNodeBalancerNode() { log.Fatal(err) } - ip, err := linodeClient.AddInstanceIPAddress(context.Background(), instance.ID, false) + opts := linodego.InstanceIPAddOptions{ + Public: false, + } + ip, err := linodeClient.AddInstanceIPAddress(context.Background(), instance.ID, opts) if err != nil { log.Fatal(err) } diff --git a/test/integration/iam_io_ready_test.go b/test/integration/iam_io_ready_test.go index 7be336a6f..b86219549 100644 --- a/test/integration/iam_io_ready_test.go +++ b/test/integration/iam_io_ready_test.go @@ -201,7 +201,8 @@ func TestIAM_GetIOReadyForClonedVolume(t *testing.T) { requireSingleAttachedInstanceVolume(t, client, instance) labelCloned := volume.Label + "-cloned" - volumeCloned, err := client.CloneVolume(context.Background(), volume.ID, labelCloned) + opts := linodego.VolumeCloneOptions{Label: labelCloned} + volumeCloned, err := client.CloneVolume(context.Background(), volume.ID, opts) t.Cleanup(func() { if err = client.DeleteVolume(context.Background(), volumeCloned.ID); err != nil { t.Errorf("Error deleting cloned volume: %v", err) @@ -234,7 +235,8 @@ func TestIAM_GetIOReadyForResizedVolume(t *testing.T) { newSize := volume.Size + 10 - err := client.ResizeVolume(context.Background(), volume.ID, newSize) + opts := linodego.VolumeResizeOptions{Size: newSize} + err := client.ResizeVolume(context.Background(), volume.ID, opts) require.NoErrorf(t, err, "Error resizing volume: %v", err) _, err = client.WaitForVolumeStatus(ctx, volume.ID, linodego.VolumeActive) diff --git a/test/integration/instance_snapshots_test.go b/test/integration/instance_snapshots_test.go index d28ddc2c4..b4cd20caa 100644 --- a/test/integration/instance_snapshots_test.go +++ b/test/integration/instance_snapshots_test.go @@ -124,7 +124,9 @@ func setupInstanceBackup( t.Errorf("Error enabling Instance Backups: %v", err) } - snapshot, err := client.CreateInstanceSnapshot(context.Background(), instance.ID, testSnapshotLabel) + opts := linodego.InstanceSnapshotCreateOptions{Label: testSnapshotLabel} + + snapshot, err := client.CreateInstanceSnapshot(context.Background(), instance.ID, opts) if err != nil { t.Errorf("Error creating instance snapshot: %v", err) } diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index 6efc1ad6b..eac574901 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -425,7 +425,11 @@ func TestInstance_Disk_Resize(t *testing.T) { t.Errorf("Error waiting for disk readiness for resize: %s", err) } - err = client.ResizeInstanceDisk(context.Background(), instance.ID, disk.ID, 4000) + opts := linodego.InstanceDiskResizeOptions{ + Size: 4000, + } + + err = client.ResizeInstanceDisk(context.Background(), instance.ID, disk.ID, opts) if err != nil { t.Errorf("Error resizing instance disk: %s", err) } @@ -440,7 +444,11 @@ func TestInstance_Disk_ListMultiple(t *testing.T) { if err != nil { t.Error(err) } - err = client.BootInstance(context.Background(), instance1.ID, 0) + + opts := linodego.InstanceBootOptions{ + ConfigID: linodego.Pointer(0), + } + err = client.BootInstance(context.Background(), instance1.ID, opts) if err != nil { t.Error(err) } @@ -544,9 +552,7 @@ func TestInstance_Disk_Clone(t *testing.T) { t.Errorf("Error waiting for disk readiness for disk clone: %s", err) } - opts := linodego.InstanceDiskCloneOptions{} - - _, err = client.CloneInstanceDisk(context.Background(), instance.ID, disk.ID, opts) + _, err = client.CloneInstanceDisk(context.Background(), instance.ID, disk.ID) if err != nil { t.Errorf("Error cloning instance disk: %s", err) } @@ -586,7 +592,10 @@ func TestInstance_Disk_ResetPassword(t *testing.T) { t.Errorf("Error waiting for disk readiness for password reset: %s", err) } - err = client.PasswordResetInstanceDisk(context.Background(), instance.ID, disk.ID, "r34!_b4d_p455") + opts := linodego.InstanceDiskPasswordResetOptions{ + Password: "r34!_b4d_p455", + } + err = client.PasswordResetInstanceDisk(context.Background(), instance.ID, disk.ID, opts) if err != nil { t.Errorf("Error reseting password on instance disk: %s", err) } diff --git a/test/integration/network_ips_test.go b/test/integration/network_ips_test.go index b96308d09..7954eb488 100644 --- a/test/integration/network_ips_test.go +++ b/test/integration/network_ips_test.go @@ -378,7 +378,10 @@ func TestIPAddress_Instance_Delete(t *testing.T) { t.Error(err) } - ip, err := client.AddInstanceIPAddress(context.TODO(), instance.ID, true) + opts := linodego.InstanceIPAddOptions{ + Public: true, + } + ip, err := client.AddInstanceIPAddress(context.TODO(), instance.ID, opts) if err != nil { t.Fatalf("failed to allocate public IPv4 for instance (%d): %s", instance.ID, err) } @@ -487,7 +490,10 @@ func TestIPAddress_Instance_Share(t *testing.T) { t.Error(err) } - ip, err := client.AddInstanceIPAddress(context.Background(), newInstance.ID, true) + opts := linodego.InstanceIPAddOptions{ + Public: true, + } + ip, err := client.AddInstanceIPAddress(context.Background(), newInstance.ID, opts) if err != nil { t.Error(err) } diff --git a/test/integration/nodebalancer_config_nodes_test.go b/test/integration/nodebalancer_config_nodes_test.go index 9948a285f..587ec3f02 100644 --- a/test/integration/nodebalancer_config_nodes_test.go +++ b/test/integration/nodebalancer_config_nodes_test.go @@ -361,7 +361,10 @@ func setupNodeBalancerNode( t.Errorf("failed to create test instance: %s", err) } - instanceIP, err := client.AddInstanceIPAddress(context.Background(), instance.ID, false) + opts := linodego.InstanceIPAddOptions{ + Public: false, + } + instanceIP, err := client.AddInstanceIPAddress(context.Background(), instance.ID, opts) if err != nil { t.Fatal(err) } diff --git a/test/integration/volumes_test.go b/test/integration/volumes_test.go index df998d269..0bd3d975b 100644 --- a/test/integration/volumes_test.go +++ b/test/integration/volumes_test.go @@ -81,7 +81,10 @@ func TestVolume_Resize(t *testing.T) { t.Errorf("Error waiting for volume to be active, %s", err) } - if err := client.ResizeVolume(context.Background(), volume.ID, volume.Size+1); err != nil { + opts := linodego.VolumeResizeOptions{ + Size: volume.Size + 1, + } + if err := client.ResizeVolume(context.Background(), volume.ID, opts); err != nil { t.Errorf("Error resizing volume, %s", err) } } diff --git a/test/integration/waitfor_test.go b/test/integration/waitfor_test.go index 6d54f53bf..31d2fa82f 100644 --- a/test/integration/waitfor_test.go +++ b/test/integration/waitfor_test.go @@ -51,7 +51,10 @@ func TestEventPoller_InstancePower(t *testing.T) { t.Fatal(err) } - if err := client.BootInstance(context.Background(), instance.ID, 0); err != nil { + opts := linodego.InstanceBootOptions{ + ConfigID: linodego.Pointer(0), + } + if err := client.BootInstance(context.Background(), instance.ID, opts); err != nil { t.Fatal(err) } diff --git a/test/unit/instance_backup_test.go b/test/unit/instance_backup_test.go index 827d3c3c9..04f47c236 100644 --- a/test/unit/instance_backup_test.go +++ b/test/unit/instance_backup_test.go @@ -37,7 +37,9 @@ func TestInstanceSnapshot_Create(t *testing.T) { base.MockPost("linode/instances/123/backups", fixtureData) - snapshot, err := base.Client.CreateInstanceSnapshot(context.Background(), 123, "new-snapshot") + opts := linodego.InstanceSnapshotCreateOptions{Label: "new-snapshot"} + + snapshot, err := base.Client.CreateInstanceSnapshot(context.Background(), 123, opts) assert.NoError(t, err) assert.Equal(t, "new-snapshot", snapshot.Label) assert.Equal(t, linodego.SnapshotPending, snapshot.Status) diff --git a/test/unit/instance_disks_test.go b/test/unit/instance_disks_test.go index 01a9f3d19..c6bd44ba7 100644 --- a/test/unit/instance_disks_test.go +++ b/test/unit/instance_disks_test.go @@ -19,9 +19,7 @@ func TestInstance_Disks_Clone(t *testing.T) { base.MockPost("linode/instances/12345/disks/123/clone", fixtureData) - opts := linodego.InstanceDiskCloneOptions{} - - disk, err := base.Client.CloneInstanceDisk(context.Background(), 12345, 123, opts) + disk, err := base.Client.CloneInstanceDisk(context.Background(), 12345, 123) assert.NoError(t, err) assert.Equal(t, linodego.DiskFilesystem("ext4"), disk.Filesystem) @@ -151,7 +149,9 @@ func TestInstanceDisk_Resize(t *testing.T) { base.MockPost("linode/instances/123/disks/1/resize", nil) - err := base.Client.ResizeInstanceDisk(context.Background(), 123, 1, 40960) + opts := linodego.InstanceDiskResizeOptions{Size: 40960} + + err := base.Client.ResizeInstanceDisk(context.Background(), 123, 1, opts) assert.NoError(t, err) } @@ -162,6 +162,8 @@ func TestInstanceDisk_PasswordReset(t *testing.T) { base.MockPost("linode/instances/123/disks/1/password", nil) - err := base.Client.PasswordResetInstanceDisk(context.Background(), 123, 1, "new-password") + opts := linodego.InstanceDiskPasswordResetOptions{Password: "new-password"} + + err := base.Client.PasswordResetInstanceDisk(context.Background(), 123, 1, opts) assert.NoError(t, err) } diff --git a/test/unit/instance_ip_test.go b/test/unit/instance_ip_test.go index 6e035ff7f..87356c535 100644 --- a/test/unit/instance_ip_test.go +++ b/test/unit/instance_ip_test.go @@ -66,7 +66,9 @@ func TestInstanceIPAddress_Add(t *testing.T) { base.MockPost("linode/instances/123/ips", fixtureData) - ip, err := base.Client.AddInstanceIPAddress(context.Background(), 123, true) + opts := linodego.InstanceIPAddOptions{Public: true} + + ip, err := base.Client.AddInstanceIPAddress(context.Background(), 123, opts) assert.NoError(t, err) assert.NotNil(t, ip) assert.Equal(t, "198.51.100.1", ip.Address) diff --git a/test/unit/instance_test.go b/test/unit/instance_test.go index 3975a6d02..761f607f0 100644 --- a/test/unit/instance_test.go +++ b/test/unit/instance_test.go @@ -213,7 +213,9 @@ func TestInstance_Boot(t *testing.T) { base.MockPost("linode/instances/123/boot", nil) - err := base.Client.BootInstance(context.Background(), 123, 0) + opts := linodego.InstanceBootOptions{ConfigID: linodego.Pointer(0)} + + err := base.Client.BootInstance(context.Background(), 123, opts) assert.NoError(t, err) } @@ -224,7 +226,9 @@ func TestInstance_Reboot(t *testing.T) { base.MockPost("linode/instances/123/reboot", nil) - err := base.Client.RebootInstance(context.Background(), 123, 0) + opts := linodego.InstanceRebootOptions{ConfigID: linodego.Pointer(0)} + + err := base.Client.RebootInstance(context.Background(), 123, opts) assert.NoError(t, err) } diff --git a/test/unit/volume_test.go b/test/unit/volume_test.go index a882bd18d..601f4c2b7 100644 --- a/test/unit/volume_test.go +++ b/test/unit/volume_test.go @@ -175,6 +175,8 @@ func TestResizeVolume(t *testing.T) { volumeID := 123 base.MockPost(fmt.Sprintf("volumes/%d/resize", volumeID), nil) - err := base.Client.ResizeVolume(context.Background(), volumeID, 50) + opts := linodego.VolumeResizeOptions{Size: 50} + + err := base.Client.ResizeVolume(context.Background(), volumeID, opts) assert.NoError(t, err, "Expected no error when resizing volume") } diff --git a/volumes.go b/volumes.go index cd83e696c..fc6495ee6 100644 --- a/volumes.go +++ b/volumes.go @@ -63,6 +63,14 @@ type VolumeUpdateOptions struct { Tags []string `json:"tags,omitzero"` } +type VolumeCloneOptions struct { + Label string `json:"label"` +} + +type VolumeResizeOptions struct { + Size int `json:"size"` +} + // VolumeAttachOptions fields are those accepted by AttachVolume type VolumeAttachOptions struct { LinodeID int `json:"linode_id"` @@ -144,11 +152,7 @@ func (c *Client) UpdateVolume(ctx context.Context, volumeID int, opts VolumeUpda } // CloneVolume clones a Linode volume -func (c *Client) CloneVolume(ctx context.Context, volumeID int, label string) (*Volume, error) { - opts := map[string]any{ - "label": label, - } - +func (c *Client) CloneVolume(ctx context.Context, volumeID int, opts VolumeCloneOptions) (*Volume, error) { e := formatAPIPath("volumes/%d/clone", volumeID) return doPOSTRequest[Volume](ctx, c, e, opts) @@ -161,11 +165,7 @@ func (c *Client) DetachVolume(ctx context.Context, volumeID int) error { } // ResizeVolume resizes an instance to new Linode type -func (c *Client) ResizeVolume(ctx context.Context, volumeID int, size int) error { - opts := map[string]int{ - "size": size, - } - +func (c *Client) ResizeVolume(ctx context.Context, volumeID int, opts VolumeResizeOptions) error { e := formatAPIPath("volumes/%d/resize", volumeID) return doPOSTRequestNoResponseBody(ctx, c, e, opts) From b86aeb38f14d8cdd9a0288b6984afca8b5ebc928 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Thu, 14 May 2026 14:34:56 -0400 Subject: [PATCH 09/17] TPT-3483: Update NewClient method to return an error rather than just logging errors (#967) * refactor: update NewClient and related functions to handle errors properly * refactor: update SetRootCertificate to return errors and enhance logging * update NewClient instantiation to handle errors --- README.md | 5 +- client.go | 27 ++--- client_monitor.go | 21 ++-- client_test.go | 115 ++++++++++++++++----- config_test.go | 6 +- errors_test.go | 6 +- internal/testutil/mock.go | 26 +++++ request_helpers_test.go | 16 +-- test/integration/integration_suite_test.go | 7 +- test/unit/base.go | 2 +- test/unit/util_test.go | 2 +- 11 files changed, 171 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 0875968bf..7e0f1840f 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,10 @@ func main() { }, } - linodeClient := linodego.NewClient(oauth2Client) + linodeClient, err := linodego.NewClient(oauth2Client) + if err != nil { + log.Fatal(err) + } linodeClient.SetDebug(true) res, err := linodeClient.GetInstance(context.Background(), 4090913) diff --git a/client.go b/client.go index b96d1abee..bb94093e3 100644 --- a/client.go +++ b/client.go @@ -154,9 +154,9 @@ func init() { } } -// NewClient factory to create new Client struct +// NewClient factory to create new Client struct. // nolint:funlen -func NewClient(hc *http.Client) (client Client) { +func NewClient(hc *http.Client) (client Client, err error) { if hc != nil { client.httpClient = hc } else { @@ -199,7 +199,9 @@ func NewClient(hc *http.Client) (client Client) { certPath, certPathExists := os.LookupEnv(APIHostCert) if certPathExists { - client.SetRootCertificate(certPath) + if err := client.SetRootCertificate(certPath); err != nil { + return Client{}, err + } if envDebug { log.Printf("[DEBUG] Set API root certificate to %s\n", certPath) @@ -214,13 +216,16 @@ func NewClient(hc *http.Client) (client Client) { SetDebug(envDebug). enableLogSanitization() - return client + return client, nil } // NewClientFromEnv creates a Client and initializes it with values // from the LINODE_CONFIG file and the LINODE_TOKEN environment variable. func NewClientFromEnv(hc *http.Client) (*Client, error) { - client := NewClient(hc) + client, err := NewClient(hc) + if err != nil { + return nil, err + } // Users are expected to chain NewClient(...) and LoadConfig(...) to customize these options configPath, err := resolveValidConfigPath() @@ -283,12 +288,11 @@ func (c *Client) ErrorAndLogf(format string, args ...any) error { return fmt.Errorf(format, args...) } -// SetRootCertificate adds a root certificate to the underlying TLS client config -func (c *Client) SetRootCertificate(certPath string) *Client { +// SetRootCertificate adds a root certificate to the underlying TLS client config. +func (c *Client) SetRootCertificate(certPath string) error { config, err := c.tlsConfig() if err != nil { - log.Println("[WARN] Custom transport is not allowed with a custom root CA") - return c + return fmt.Errorf("custom transport is not allowed with a custom root CA: %w", err) } if config.RootCAs == nil { @@ -297,13 +301,12 @@ func (c *Client) SetRootCertificate(certPath string) *Client { pem, err := os.ReadFile(filepath.Clean(certPath)) if err != nil { - log.Printf("[ERROR] Failed to read root certificate at %s: %s\n", certPath, err.Error()) - return c + return fmt.Errorf("failed to read root certificate at %s: %w", certPath, err) } config.RootCAs.AppendCertsFromPEM(pem) - return c + return nil } // SetToken sets the API token for all requests from this client diff --git a/client_monitor.go b/client_monitor.go index 3cb959854..336c28a6b 100644 --- a/client_monitor.go +++ b/client_monitor.go @@ -128,12 +128,16 @@ func (mc *MonitorClient) SetAPIVersion(apiVersion string) *MonitorClient { return mc } -// SetRootCertificate adds a root certificate to the underlying TLS client config -func (mc *MonitorClient) SetRootCertificate(certPath string) *MonitorClient { +// SetRootCertificate adds a root certificate to the underlying TLS client config. +func (mc *MonitorClient) SetRootCertificate(certPath string) error { transport, ok := mc.httpClient.Transport.(*http.Transport) if !ok { - mc.logger.Errorf("current transport is not an *http.Transport instance") - return mc + err := fmt.Errorf("current transport is not an *http.Transport instance") + if mc.logger != nil { + mc.logger.Errorf("%s", err) + } + + return err } if transport.TLSClientConfig == nil { @@ -148,13 +152,16 @@ func (mc *MonitorClient) SetRootCertificate(certPath string) *MonitorClient { pem, err := os.ReadFile(filepath.Clean(certPath)) if err != nil { - mc.logger.Errorf("Failed to read root certificate at %s: %s", certPath, err.Error()) - return mc + if mc.logger != nil { + mc.logger.Errorf("Failed to read root certificate at %s: %s", certPath, err.Error()) + } + + return fmt.Errorf("failed to read root certificate at %s: %w", certPath, err) } transport.TLSClientConfig.RootCAs.AppendCertsFromPEM(pem) - return mc + return nil } // SetToken sets the API token for all requests from this client diff --git a/client_test.go b/client_test.go index da4997c17..4c48f25ff 100644 --- a/client_test.go +++ b/client_test.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "log" "net/http" "net/http/httptest" "os" @@ -20,6 +19,14 @@ import ( "github.com/stretchr/testify/require" ) +func newTestClient(t *testing.T, hc *http.Client) Client { + t.Helper() + + client, err := NewClient(hc) + require.NoError(t, err) + return client +} + func TestClient_SetAPIVersion(t *testing.T) { defaultURL := "https://api.linode.com/v4" @@ -35,7 +42,7 @@ func TestClient_SetAPIVersion(t *testing.T) { protocolAPIVersion := "v4_http" protocolExpectedHost := fmt.Sprintf("%s/%s", protocolBaseURL, protocolAPIVersion) - client := NewClient(nil) + client := newTestClient(t, nil) if client.hostURL != defaultURL { t.Fatal(cmp.Diff(client.hostURL, defaultURL)) @@ -152,7 +159,7 @@ func TestClient_UseURL(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - client := NewClient(nil) + client := newTestClient(t, nil) _, err := client.UseURL(tt.inputURL) @@ -203,7 +210,7 @@ func TestDebugLogSanitization(t *testing.T) { plainTextToken := "NOTANAPIKEY" - mockClient := testutil.CreateMockClient(t, NewClient) + mockClient := testutil.CreateMockClientWithError(t, NewClient) logger := testutil.CreateLogger() mockClient.SetLogger(logger) logger.L.SetOutput(&lgr) @@ -253,7 +260,7 @@ func TestDoRequest_Success(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := NewClient(server.Client()) + client := newTestClient(t, server.Client()) client.SetBaseURL(server.URL) params := requestParams{ @@ -273,7 +280,7 @@ func TestDoRequest_Success(t *testing.T) { } func TestDoRequest_FailedCreateRequest(t *testing.T) { - client := NewClient(nil) + client := newTestClient(t, nil) // Create a request with an invalid method to simulate a request creation failure err := client.doRequest(context.Background(), "bad method", "/foo/bar", requestParams{}, nil) @@ -290,7 +297,7 @@ func TestDoRequest_Non2xxStatusCode(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := NewClient(server.Client()) + client := newTestClient(t, server.Client()) client.SetBaseURL(server.URL) err := client.doRequest(context.Background(), http.MethodGet, "/foo/bar", requestParams{}, nil) @@ -321,7 +328,7 @@ func TestDoRequest_FailedDecodeResponse(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := NewClient(server.Client()) + client := newTestClient(t, server.Client()) client.SetBaseURL(server.URL) params := requestParams{ @@ -348,7 +355,7 @@ func TestDoRequest_BeforeRequestSuccess(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := NewClient(server.Client()) + client := newTestClient(t, server.Client()) client.SetBaseURL(server.URL) mutator := func(req *http.Request) error { @@ -377,7 +384,7 @@ func TestDoRequest_BeforeRequestError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := NewClient(server.Client()) + client := newTestClient(t, server.Client()) client.SetBaseURL(server.URL) mutator := func(req *http.Request) error { @@ -407,7 +414,7 @@ func TestDoRequest_AfterResponseSuccess(t *testing.T) { tr := &testRoundTripper{ Transport: server.Client().Transport, } - client := NewClient(&http.Client{Transport: tr}) + client := newTestClient(t, &http.Client{Transport: tr}) client.SetBaseURL(server.URL) mutator := func(resp *http.Response) error { @@ -436,7 +443,7 @@ func TestDoRequest_AfterResponseError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() - client := NewClient(server.Client()) + client := newTestClient(t, server.Client()) client.SetBaseURL(server.URL) mutator := func(resp *http.Response) error { @@ -457,7 +464,7 @@ func TestDoRequestLogging_Success(t *testing.T) { logger := createLogger() logger.l.SetOutput(&logBuffer) // Redirect log output to buffer - client := NewClient(nil) + client := newTestClient(t, nil) client.SetDebug(true) client.SetLogger(logger) @@ -515,7 +522,7 @@ func TestDoRequestLogging_Error(t *testing.T) { logger := createLogger() logger.l.SetOutput(&logBuffer) // Redirect log output to buffer - client := NewClient(nil) + client := newTestClient(t, nil) client.SetDebug(true) client.SetLogger(logger) @@ -586,18 +593,15 @@ func TestClient_CustomRootCAWithCustomRoundTripper(t *testing.T) { Transport: server.Client().Transport, } - buf := new(strings.Builder) - log.SetOutput(buf) - - NewClient(&http.Client{Transport: tr}) + _, err = NewClient(&http.Client{Transport: tr}) + require.ErrorContains(t, err, "custom transport is not allowed with a custom root CA") +} - expectedLog := "Custom transport is not allowed with a custom root CA" +func TestClient_CustomRootCAWithMissingFile(t *testing.T) { + t.Setenv(APIHostCert, "/does/not/exist.pem") - if !strings.Contains(buf.String(), expectedLog) { - t.Fatalf("expected log %q not found in logs", expectedLog) - } - - log.SetOutput(os.Stderr) + _, err := NewClient(nil) + require.ErrorContains(t, err, "failed to read root certificate") } func TestClient_CustomRootCAWithoutCustomRoundTripper(t *testing.T) { @@ -624,7 +628,7 @@ func TestClient_CustomRootCAWithoutCustomRoundTripper(t *testing.T) { t.Setenv(APIHostCert, caFile.Name()) } - client := NewClient(test.httpClient) + client := newTestClient(t, test.httpClient) transport, ok := client.httpClient.Transport.(*http.Transport) if !ok { t.Fatal("expected *http.Transport") @@ -692,6 +696,65 @@ func TestMonitorClient_SetAPIBasics(t *testing.T) { } } +func TestMonitorClient_SetRootCertificateWithCustomRoundTripper(t *testing.T) { + caFile, err := os.CreateTemp(t.TempDir(), "linodego_test_ca_*") + if err != nil { + t.Fatalf("Failed to create temp ca file: %s", err) + } + defer os.Remove(caFile.Name()) + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + tr := &testRoundTripper{Transport: server.Client().Transport} + client := NewMonitorClient(&http.Client{Transport: tr}) + + err = client.SetRootCertificate(caFile.Name()) + require.ErrorContains(t, err, "current transport is not an *http.Transport instance") +} + +func TestMonitorClient_SetRootCertificateWithMissingFile(t *testing.T) { + client := NewMonitorClient(nil) + + err := client.SetRootCertificate("/does/not/exist.pem") + require.ErrorContains(t, err, "failed to read root certificate") +} + +func TestMonitorClient_SetRootCertificateWithoutCustomRoundTripper(t *testing.T) { + caFile, err := os.CreateTemp(t.TempDir(), "linodego_test_ca_*") + if err != nil { + t.Fatalf("Failed to create temp ca file: %s", err) + } + defer os.Remove(caFile.Name()) + + tests := []struct { + name string + httpClient *http.Client + }{ + {"default http client", nil}, + {"timeout http client", &http.Client{Timeout: time.Second}}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + client := NewMonitorClient(test.httpClient) + + err := client.SetRootCertificate(caFile.Name()) + require.NoError(t, err) + + transport, ok := client.httpClient.Transport.(*http.Transport) + if !ok { + t.Fatal("expected *http.Transport") + } + if transport.TLSClientConfig == nil || transport.TLSClientConfig.RootCAs == nil { + t.Error("expected root CAs to be set") + } + }) + } +} + func TestRedactHeaders(t *testing.T) { tests := []struct { name string @@ -758,7 +821,7 @@ func TestRedactHeaders(t *testing.T) { } func TestEnableLogSanitization(t *testing.T) { - mockClient := testutil.CreateMockClient(t, NewClient) + mockClient := testutil.CreateMockClientWithError(t, NewClient) mockClient.SetDebug(true) plainTextToken := "supersecrettoken" diff --git a/config_test.go b/config_test.go index 628cc1415..252f496c2 100644 --- a/config_test.go +++ b/config_test.go @@ -7,7 +7,7 @@ import ( ) func TestConfig_LoadWithDefaults(t *testing.T) { - client := NewClient(nil) + client := newTestClient(t, nil) file := createTestConfig(t, configLoadWithDefault) @@ -52,7 +52,7 @@ func TestConfig_LoadWithDefaults(t *testing.T) { } func TestConfig_OverrideDefaults(t *testing.T) { - client := NewClient(nil) + client := newTestClient(t, nil) file := createTestConfig(t, configOverrideDefaults) @@ -98,7 +98,7 @@ func TestConfig_OverrideDefaults(t *testing.T) { } func TestConfig_NoDefaults(t *testing.T) { - client := NewClient(nil) + client := newTestClient(t, nil) file := createTestConfig(t, configNoDefaults) diff --git a/errors_test.go b/errors_test.go index 4a182c36e..429670100 100644 --- a/errors_test.go +++ b/errors_test.go @@ -98,7 +98,9 @@ func TestNewError(t *testing.T) { } } -func createTestServer(method, route, contentType, body string, statusCode int) (*httptest.Server, *Client) { +func createTestServer(t *testing.T, method, route, contentType, body string, statusCode int) (*httptest.Server, *Client) { + t.Helper() + h := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { if r.Method == method && r.URL.Path == route { rw.Header().Add("Content-Type", contentType) @@ -110,7 +112,7 @@ func createTestServer(method, route, contentType, body string, statusCode int) ( }) ts := httptest.NewServer(h) - client := NewClient(nil) + client := newTestClient(t, nil) client.SetBaseURL(ts.URL) return ts, &client } diff --git a/internal/testutil/mock.go b/internal/testutil/mock.go index 752b27f9f..9f65253a8 100644 --- a/internal/testutil/mock.go +++ b/internal/testutil/mock.go @@ -98,6 +98,32 @@ func CreateMockClient[T any](t *testing.T, createFunc func(*http.Client) T) *T { return &result } +// CreateMockClientWithError is generic because importing the linodego package +// will result in a cyclic dependency. This pattern isn't ideal but works for now. +func CreateMockClientWithError[T any](t *testing.T, createFunc func(*http.Client) (T, error)) *T { + t.Helper() + + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: validTestAPIKey}) + + client := &http.Client{ + Transport: &oauth2.Transport{ + Source: tokenSource, + }, + } + httpmock.ActivateNonDefault(client) + + t.Cleanup(func() { + httpmock.DeactivateAndReset() + }) + + result, err := createFunc(client) + if err != nil { + t.Fatal(err) + } + + return &result +} + type Logger interface { Errorf(format string, v ...any) Warnf(format string, v ...any) diff --git a/request_helpers_test.go b/request_helpers_test.go index 033c86628..47d1da8cd 100644 --- a/request_helpers_test.go +++ b/request_helpers_test.go @@ -37,7 +37,7 @@ var testResponse = testResultType{ } func TestRequestHelpers_get(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) httpmock.RegisterRegexpResponder("GET", testutil.MockRequestURL("/foo/bar"), httpmock.NewJsonResponderOrPanic(200, &testResponse)) @@ -57,7 +57,7 @@ func TestRequestHelpers_get(t *testing.T) { } func TestRequestHelpers_post(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) httpmock.RegisterRegexpResponder("POST", testutil.MockRequestURL("/foo/bar"), testutil.MockRequestBodyValidate(t, testResponse, testResponse)) @@ -78,7 +78,7 @@ func TestRequestHelpers_post(t *testing.T) { } func TestRequestHelpers_postNoOptions(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) httpmock.RegisterRegexpResponder("POST", testutil.MockRequestURL("/foo/bar"), testutil.MockRequestBodyValidateNoBody(t, testResponse)) @@ -98,7 +98,7 @@ func TestRequestHelpers_postNoOptions(t *testing.T) { } func TestRequestHelpers_put(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) httpmock.RegisterRegexpResponder("PUT", testutil.MockRequestURL("/foo/bar"), testutil.MockRequestBodyValidate(t, testResponse, testResponse)) @@ -119,7 +119,7 @@ func TestRequestHelpers_put(t *testing.T) { } func TestRequestHelpers_putNoOptions(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) httpmock.RegisterRegexpResponder("PUT", testutil.MockRequestURL("/foo/bar"), testutil.MockRequestBodyValidateNoBody(t, testResponse)) @@ -139,7 +139,7 @@ func TestRequestHelpers_putNoOptions(t *testing.T) { } func TestRequestHelpers_delete(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) httpmock.RegisterRegexpResponder("DELETE", testutil.MockRequestURL("/foo/bar/foo%20bar"), httpmock.NewStringResponder(200, "{}")) @@ -156,7 +156,7 @@ func TestRequestHelpers_delete(t *testing.T) { func TestRequestHelpers_paginateAll(t *testing.T) { const totalResults = 4123 - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) numRequests := 0 @@ -186,7 +186,7 @@ func TestRequestHelpers_paginateAll(t *testing.T) { } func TestRequestHelpers_paginateSingle(t *testing.T) { - client := testutil.CreateMockClient(t, NewClient) + client := testutil.CreateMockClientWithError(t, NewClient) numRequests := 0 diff --git a/test/integration/integration_suite_test.go b/test/integration/integration_suite_test.go index 11df46310..a77faee4f 100644 --- a/test/integration/integration_suite_test.go +++ b/test/integration/integration_suite_test.go @@ -163,7 +163,12 @@ func createTestClient(t *testing.T, fixturesYaml string) (*linodego.Client, func }, } - c = linodego.NewClient(oc) + client, err := linodego.NewClient(oc) + if err != nil { + t.Fatal(err) + } + + c = client c.SetDebug(debugAPI). SetPollDelay(testingPollDuration). SetRetryMaxWaitTime(testingMaxRetryTime) diff --git a/test/unit/base.go b/test/unit/base.go index f3977e0f9..765c68639 100644 --- a/test/unit/base.go +++ b/test/unit/base.go @@ -27,7 +27,7 @@ type ClientBaseCase struct { // SetUp initializes the Linode client using the mock HTTP client func (c *ClientBaseCase) SetUp(t *testing.T) { c.Mock = &mock.Mock{} - c.Client = testutil.CreateMockClient(t, linodego.NewClient) + c.Client = testutil.CreateMockClientWithError(t, linodego.NewClient) baseURL := "https://" + linodego.APIHost if hostOverride, ok := os.LookupEnv(linodego.APIHostVar); ok && hostOverride != "" { diff --git a/test/unit/util_test.go b/test/unit/util_test.go index ae6b655f4..1ac974157 100644 --- a/test/unit/util_test.go +++ b/test/unit/util_test.go @@ -20,7 +20,7 @@ func mockRequestURL(t *testing.T, path string) *regexp.Regexp { } func createMockClient(t *testing.T) *linodego.Client { - return testutil.CreateMockClient(t, linodego.NewClient) + return testutil.CreateMockClientWithError(t, linodego.NewClient) } func formatMockAPIPath(format string, args ...any) string { From bebb4634df079c73f462775e7509f402ff636a0b Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Fri, 15 May 2026 12:49:21 -0400 Subject: [PATCH 10/17] Export PaginatedResponse type in request_helpers (#970) --- request_helpers.go | 6 +++--- request_helpers_test.go | 2 +- test/unit/nodebalancer_types_test.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/request_helpers.go b/request_helpers.go index 970c22d14..ca2acd60a 100644 --- a/request_helpers.go +++ b/request_helpers.go @@ -10,9 +10,9 @@ import ( "reflect" ) -// paginatedResponse represents a single response from a paginated +// PaginatedResponse represents a single response from a paginated // endpoint. -type paginatedResponse[T any] struct { +type PaginatedResponse[T any] struct { Page int `json:"page"` Pages int `json:"pages"` Results int `json:"results"` @@ -60,7 +60,7 @@ func handlePaginatedResults[T any, O any]( // Makes a request to a particular page and appends the response to the result handlePage := func(page int) error { - var resultType paginatedResponse[T] + var resultType PaginatedResponse[T] // Override the page to be applied in createListOptionsToRequestMutator(...) opts.Page = page diff --git a/request_helpers_test.go b/request_helpers_test.go index 47d1da8cd..57a0fe105 100644 --- a/request_helpers_test.go +++ b/request_helpers_test.go @@ -268,7 +268,7 @@ func mockPaginatedResponse( return httpmock.NewJsonResponse( 200, - paginatedResponse[testResultType]{ + PaginatedResponse[testResultType]{ Page: page, Pages: int(math.Ceil(float64(len(entries)) / float64(pageSize))), Results: pageSize, diff --git a/test/unit/nodebalancer_types_test.go b/test/unit/nodebalancer_types_test.go index 014ce76fd..50aeddf87 100644 --- a/test/unit/nodebalancer_types_test.go +++ b/test/unit/nodebalancer_types_test.go @@ -16,7 +16,7 @@ func TestNodeBalancerTypes_List(t *testing.T) { base.SetUp(t) defer base.TearDown(t) - // Mock the GET request for the node balancer types endpoint (mock as an array instead of paginatedResponse) + // Mock the GET request for the node balancer types endpoint (mock as an array instead of PaginatedResponse) base.MockGet("nodebalancers/types", fixtureData) // Call the ListNodeBalancerTypes method From 3a3dded5ba8ab94c3697f0c30abff9e02c0a5a42 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 19 May 2026 17:00:14 -0400 Subject: [PATCH 11/17] TPT-3388: Separated GET and POST/PUT options structs where needed (#969) * Separated GET and POST/PUT options structs where needed * Separated additional structs that were reused for options and response * More struct fixes * Fix lint * Rename FirewallRule structs * integration test fixes * Addressed PR comments * FirewallRuleSetRule options; test updates; fixture refreshed * Address more PR comments --------- Co-authored-by: Zhiwei Liang --- firewall_rules.go | 100 +++++++++++++----- firewall_rulesets.go | 91 ++++++++++------ firewall_templates.go | 4 +- firewalls.go | 17 ++- instance_config_interfaces.go | 20 +++- interfaces.go | 31 ++++-- object_storage_keys.go | 13 ++- test/integration/firewall_rules_test.go | 24 +++-- test/integration/firewall_rulesets_test.go | 8 +- test/integration/firewalls_test.go | 13 ++- .../fixtures/TestFirewallRuleSets_CRUD.yaml | 32 +++--- test/integration/instance_config_test.go | 10 +- test/integration/main_test.go | 10 +- test/integration/nodebalancer_configs_test.go | 2 +- test/integration/object_storage_keys_test.go | 35 ++++-- test/unit/firewall_rules_test.go | 21 ++-- test/unit/firewall_rulesets_test.go | 43 ++++---- test/unit/firewalls_test.go | 6 +- test/unit/instance_config_interfaces_test.go | 4 +- test/unit/interface_test.go | 4 +- 20 files changed, 317 insertions(+), 171 deletions(-) diff --git a/firewall_rules.go b/firewall_rules.go index 548a9aa6c..c917549f7 100644 --- a/firewall_rules.go +++ b/firewall_rules.go @@ -22,10 +22,7 @@ type NetworkAddresses struct { IPv6 []string `json:"ipv6,omitzero"` } -// A FirewallRule is a whitelist of ports, protocols, and addresses for which traffic should be allowed. -// The ipv4/ipv6 address lists may contain Prefix List tokens (for example, "pl::..." or "pl:system:...") -// in addition to literal IP addresses. -type FirewallRule struct { +type FirewallRuleInbound struct { Action string `json:"action"` Label string `json:"label"` Description string `json:"description,omitzero"` @@ -33,16 +30,61 @@ type FirewallRule struct { Protocol NetworkProtocol `json:"protocol"` Addresses NetworkAddresses `json:"addresses"` - // FirewallRule references one `Rule Set` by ID. When provided, this entry + // FirewallRuleInbound references one `Rule Set` by ID. When provided, this entry // represents a reference and should be mutually exclusive with ordinary // rule fields according to the API contract. RuleSet int `json:"ruleset,omitzero"` } -// MarshalJSON ensures that when a rule references a Rule Set (RuleSet != 0), +type FirewallRuleOutbound struct { + Action string `json:"action"` + Label string `json:"label"` + Description string `json:"description,omitzero"` + Ports string `json:"ports,omitzero"` + Protocol NetworkProtocol `json:"protocol"` + Addresses NetworkAddresses `json:"addresses"` + + // FirewallRuleOutbound references one `Rule Set` by ID. When provided, this entry + // represents a reference and should be mutually exclusive with ordinary + // rule fields according to the API contract. + RuleSet int `json:"ruleset,omitzero"` +} + +// MarshalJSON ensures that when a rule references a Rule Set (FirewallRuleSet != 0), +// only the reference shape { "ruleset": } is emitted. Otherwise, the +// ordinary rule fields are emitted without the ruleset key. +func (r FirewallRuleInbound) MarshalJSON() ([]byte, error) { + if r.RuleSet != 0 { + type rulesetOnly struct { + RuleSet int `json:"ruleset"` + } + + return json.Marshal(rulesetOnly{RuleSet: r.RuleSet}) + } + + type normal struct { + Action string `json:"action"` + Label string `json:"label"` + Description string `json:"description,omitzero"` + Ports string `json:"ports,omitzero"` + Protocol NetworkProtocol `json:"protocol"` + Addresses NetworkAddresses `json:"addresses"` + } + + return json.Marshal(normal{ + Action: r.Action, + Label: r.Label, + Description: r.Description, + Ports: r.Ports, + Protocol: r.Protocol, + Addresses: r.Addresses, + }) +} + +// MarshalJSON ensures that when a rule references a Rule Set (FirewallRuleSet != 0), // only the reference shape { "ruleset": } is emitted. Otherwise, the // ordinary rule fields are emitted without the ruleset key. -func (r FirewallRule) MarshalJSON() ([]byte, error) { +func (r FirewallRuleOutbound) MarshalJSON() ([]byte, error) { if r.RuleSet != 0 { type rulesetOnly struct { RuleSet int `json:"ruleset"` @@ -70,34 +112,36 @@ func (r FirewallRule) MarshalJSON() ([]byte, error) { }) } -// FirewallRuleSet is a pair of inbound and outbound rules that specify what network traffic should be allowed. -type FirewallRuleSet struct { - Inbound []FirewallRule `json:"inbound"` - InboundPolicy string `json:"inbound_policy"` - Outbound []FirewallRule `json:"outbound"` - OutboundPolicy string `json:"outbound_policy"` - - // TODO: separate request and response types in linodego v2 - // read-only, can't be used in creating or updating a Firewall - Version int `json:"version,omitzero"` - // read-only, can't be used in creating or updating a Firewall - Fingerprint string `json:"fingerprint,omitzero"` +// FirewallRules is a pair of inbound and outbound rules that specify what network traffic should be allowed. +type FirewallRules struct { + Inbound []FirewallRuleInbound `json:"inbound"` + InboundPolicy string `json:"inbound_policy"` + Outbound []FirewallRuleOutbound `json:"outbound"` + OutboundPolicy string `json:"outbound_policy"` + Version int `json:"version,omitzero"` + Fingerprint string `json:"fingerprint,omitzero"` +} +type FirewallRulesUpdateOptions struct { + Inbound []FirewallRuleInbound `json:"inbound"` + InboundPolicy string `json:"inbound_policy"` + Outbound []FirewallRuleOutbound `json:"outbound"` + OutboundPolicy string `json:"outbound_policy"` } -// GetFirewallRules gets the FirewallRuleSet for the given Firewall. -func (c *Client) GetFirewallRules(ctx context.Context, firewallID int) (*FirewallRuleSet, error) { +// GetFirewallRules gets the FirewallRules for the given Firewall. +func (c *Client) GetFirewallRules(ctx context.Context, firewallID int) (*FirewallRules, error) { e := formatAPIPath("networking/firewalls/%d/rules", firewallID) - return doGETRequest[FirewallRuleSet](ctx, c, e) + return doGETRequest[FirewallRules](ctx, c, e) } -// GetFirewallRulesExpansion gets the expanded FirewallRuleSet for the given Firewall. -func (c *Client) GetFirewallRulesExpansion(ctx context.Context, firewallID int) (*FirewallRuleSet, error) { +// GetFirewallRulesExpansion gets the expanded FirewallRules for the given Firewall. +func (c *Client) GetFirewallRulesExpansion(ctx context.Context, firewallID int) (*FirewallRules, error) { e := formatAPIPath("networking/firewalls/%d/rules/expansion", firewallID) - return doGETRequest[FirewallRuleSet](ctx, c, e) + return doGETRequest[FirewallRules](ctx, c, e) } -// UpdateFirewallRules updates the FirewallRuleSet for the given Firewall -func (c *Client) UpdateFirewallRules(ctx context.Context, firewallID int, rules FirewallRuleSet) (*FirewallRuleSet, error) { +// UpdateFirewallRules updates the FirewallRules for the given Firewall +func (c *Client) UpdateFirewallRules(ctx context.Context, firewallID int, rules FirewallRulesUpdateOptions) (*FirewallRules, error) { e := formatAPIPath("networking/firewalls/%d/rules", firewallID) - return doPUTRequest[FirewallRuleSet](ctx, c, e, rules) + return doPUTRequest[FirewallRules](ctx, c, e, rules) } diff --git a/firewall_rulesets.go b/firewall_rulesets.go index 97d5182f9..f6277025b 100644 --- a/firewall_rulesets.go +++ b/firewall_rulesets.go @@ -17,25 +17,54 @@ const ( FirewallRuleSetTypeOutbound FirewallRuleSetType = "outbound" ) -// RuleSet represents the Rule Set resource. +// FirewallRuleSet represents the Rule Set resource. // Note: created/updated/deleted are parsed via UnmarshalJSON into time.Time pointers. -type RuleSet struct { - ID int `json:"id"` - Label string `json:"label"` - Description string `json:"description,omitzero"` - Type FirewallRuleSetType `json:"type"` - Rules []FirewallRule `json:"rules"` - IsServiceDefined bool `json:"is_service_defined"` - Version int `json:"version"` +type FirewallRuleSet struct { + ID int `json:"id"` + Label string `json:"label"` + Description string `json:"description,omitzero"` + Type FirewallRuleSetType `json:"type"` + Rules []FirewallRuleSetRule `json:"rules"` + IsServiceDefined bool `json:"is_service_defined"` + Version int `json:"version"` Created *time.Time `json:"-"` Updated *time.Time `json:"-"` Deleted *time.Time `json:"-"` } -// UnmarshalJSON implements custom timestamp parsing for RuleSet. -func (r *RuleSet) UnmarshalJSON(b []byte) error { - type Mask RuleSet +// A FirewallRuleSetRule is a whitelist of ports, protocols, and addresses for which traffic should be allowed. +// The ipv4/ipv6 address lists may contain Prefix List tokens (for example, "pl::..." or "pl:system:...") +// in addition to literal IP addresses. +type FirewallRuleSetRule struct { + Action string `json:"action"` + Label string `json:"label"` + Ports string `json:"ports,omitzero"` + Protocol NetworkProtocol `json:"protocol"` + Addresses NetworkAddresses `json:"addresses"` +} + +// FirewallRuleSetRuleCreateOptions fields accepted in Firewall Rule Set create payloads. +type FirewallRuleSetRuleCreateOptions struct { + Action string `json:"action"` + Label string `json:"label"` + Ports string `json:"ports,omitzero"` + Protocol NetworkProtocol `json:"protocol"` + Addresses NetworkAddresses `json:"addresses"` +} + +// FirewallRuleSetRuleUpdateOptions fields accepted in Firewall Rule Set update payloads. +type FirewallRuleSetRuleUpdateOptions struct { + Action string `json:"action"` + Label string `json:"label"` + Ports string `json:"ports,omitzero"` + Protocol NetworkProtocol `json:"protocol"` + Addresses NetworkAddresses `json:"addresses"` +} + +// UnmarshalJSON implements custom timestamp parsing for FirewallRuleSet. +func (r *FirewallRuleSet) UnmarshalJSON(b []byte) error { + type Mask FirewallRuleSet aux := struct { *Mask @@ -66,44 +95,44 @@ func (r *RuleSet) UnmarshalJSON(b []byte) error { return nil } -// RuleSetCreateOptions fields accepted by CreateRuleSet. -type RuleSetCreateOptions struct { - Label string `json:"label"` - Description string `json:"description,omitzero"` - Type FirewallRuleSetType `json:"type"` - Rules []FirewallRule `json:"rules"` +// FirewallRuleSetCreateOptions fields accepted by CreateRuleSet. +type FirewallRuleSetCreateOptions struct { + Label string `json:"label"` + Description string `json:"description,omitzero"` + Type FirewallRuleSetType `json:"type"` + Rules []FirewallRuleSetRuleCreateOptions `json:"rules"` } -// RuleSetUpdateOptions fields accepted by UpdateRuleSet. +// FirewallRuleSetUpdateOptions fields accepted by UpdateRuleSet. // Omit a top-level field to leave it unchanged. If Rules is provided, it // replaces the entire ordered rules array. -type RuleSetUpdateOptions struct { - Label *string `json:"label,omitzero"` - Description *string `json:"description,omitzero"` - Rules []FirewallRule `json:"rules,omitzero"` +type FirewallRuleSetUpdateOptions struct { + Label *string `json:"label,omitzero"` + Description *string `json:"description,omitzero"` + Rules []FirewallRuleSetRuleUpdateOptions `json:"rules,omitzero"` } // ListFirewallRuleSets returns a paginated list of Rule Sets. // Supports filtering (e.g., by label) via ListOptions.Filter. -func (c *Client) ListFirewallRuleSets(ctx context.Context, opts *ListOptions) ([]RuleSet, error) { - return getPaginatedResults[RuleSet](ctx, c, "networking/firewalls/rulesets", opts) +func (c *Client) ListFirewallRuleSets(ctx context.Context, opts *ListOptions) ([]FirewallRuleSet, error) { + return getPaginatedResults[FirewallRuleSet](ctx, c, "networking/firewalls/rulesets", opts) } // CreateFirewallRuleSet creates a new Rule Set. -func (c *Client) CreateFirewallRuleSet(ctx context.Context, opts RuleSetCreateOptions) (*RuleSet, error) { - return doPOSTRequest[RuleSet](ctx, c, "networking/firewalls/rulesets", opts) +func (c *Client) CreateFirewallRuleSet(ctx context.Context, opts FirewallRuleSetCreateOptions) (*FirewallRuleSet, error) { + return doPOSTRequest[FirewallRuleSet](ctx, c, "networking/firewalls/rulesets", opts) } // GetFirewallRuleSet fetches a Rule Set by ID. -func (c *Client) GetFirewallRuleSet(ctx context.Context, rulesetID int) (*RuleSet, error) { +func (c *Client) GetFirewallRuleSet(ctx context.Context, rulesetID int) (*FirewallRuleSet, error) { e := formatAPIPath("networking/firewalls/rulesets/%d", rulesetID) - return doGETRequest[RuleSet](ctx, c, e) + return doGETRequest[FirewallRuleSet](ctx, c, e) } // UpdateFirewallRuleSet updates a Rule Set by ID. -func (c *Client) UpdateFirewallRuleSet(ctx context.Context, rulesetID int, opts RuleSetUpdateOptions) (*RuleSet, error) { +func (c *Client) UpdateFirewallRuleSet(ctx context.Context, rulesetID int, opts FirewallRuleSetUpdateOptions) (*FirewallRuleSet, error) { e := formatAPIPath("networking/firewalls/rulesets/%d", rulesetID) - return doPUTRequest[RuleSet](ctx, c, e, opts) + return doPUTRequest[FirewallRuleSet](ctx, c, e, opts) } // DeleteFirewallRuleSet deletes a Rule Set by ID. diff --git a/firewall_templates.go b/firewall_templates.go index e2f5f6702..d1ba584db 100644 --- a/firewall_templates.go +++ b/firewall_templates.go @@ -5,8 +5,8 @@ import ( ) type FirewallTemplate struct { - Slug string `json:"slug"` - Rules FirewallRuleSet `json:"rules"` + Slug string `json:"slug"` + Rules FirewallRules `json:"rules"` } // GetFirewallTemplate gets a FirewallTemplate given a slug. diff --git a/firewalls.go b/firewalls.go index 02cbd9799..8b3ec2699 100644 --- a/firewalls.go +++ b/firewalls.go @@ -24,7 +24,7 @@ type Firewall struct { Label string `json:"label"` Status FirewallStatus `json:"status"` Tags []string `json:"tags"` - Rules FirewallRuleSet `json:"rules"` + Rules FirewallRules `json:"rules"` Entities []FirewallDeviceEntity `json:"entities"` Created *time.Time `json:"-"` Updated *time.Time `json:"-"` @@ -39,10 +39,17 @@ type DevicesCreationOptions struct { // FirewallCreateOptions fields are those accepted by CreateFirewall type FirewallCreateOptions struct { - Label string `json:"label,omitzero"` - Rules FirewallRuleSet `json:"rules"` - Tags []string `json:"tags,omitzero"` - Devices DevicesCreationOptions `json:"devices,omitzero"` + Label string `json:"label,omitzero"` + Rules FirewallRulesCreateOptions `json:"rules"` + Tags []string `json:"tags,omitzero"` + Devices DevicesCreationOptions `json:"devices,omitzero"` +} + +type FirewallRulesCreateOptions struct { + Inbound []FirewallRuleInbound `json:"inbound"` + InboundPolicy string `json:"inbound_policy"` + Outbound []FirewallRuleOutbound `json:"outbound"` + OutboundPolicy string `json:"outbound_policy"` } // FirewallUpdateOptions is an options struct used when Updating a Firewall diff --git a/instance_config_interfaces.go b/instance_config_interfaces.go index d9dd06764..b6711f5bd 100644 --- a/instance_config_interfaces.go +++ b/instance_config_interfaces.go @@ -49,13 +49,23 @@ type VPCIPv4 struct { NAT1To1 *string `json:"nat_1_1,omitzero"` } +type VPCIPv4CreateOptions struct { + VPC string `json:"vpc,omitzero"` + NAT1To1 *string `json:"nat_1_1,omitzero"` +} + +type VPCIPv4UpdateOptions struct { + VPC string `json:"vpc,omitzero"` + NAT1To1 *string `json:"nat_1_1,omitzero"` +} + type InstanceConfigInterfaceCreateOptions struct { IPAMAddress string `json:"ipam_address,omitzero"` Label string `json:"label,omitzero"` Purpose ConfigInterfacePurpose `json:"purpose,omitzero"` Primary bool `json:"primary,omitzero"` SubnetID *int `json:"subnet_id,omitzero"` - IPv4 *VPCIPv4 `json:"ipv4,omitzero"` + IPv4 *VPCIPv4CreateOptions `json:"ipv4,omitzero"` // NOTE: IPv6 interfaces may not currently be available to all users. IPv6 *InstanceConfigInterfaceCreateOptionsIPv6 `json:"ipv6,omitzero"` @@ -87,8 +97,8 @@ type InstanceConfigInterfaceCreateOptionsIPv6Range struct { } type InstanceConfigInterfaceUpdateOptions struct { - Primary bool `json:"primary,omitzero"` - IPv4 *VPCIPv4 `json:"ipv4,omitzero"` + Primary bool `json:"primary,omitzero"` + IPv4 *VPCIPv4UpdateOptions `json:"ipv4,omitzero"` // NOTE: IPv6 interfaces may not currently be available to all users. IPv6 *InstanceConfigInterfaceUpdateOptionsIPv6 `json:"ipv6,omitzero"` @@ -147,7 +157,7 @@ func (i InstanceConfigInterface) GetCreateOptions() InstanceConfigInterfaceCreat } if i.IPv4 != nil { - opts.IPv4 = &VPCIPv4{ + opts.IPv4 = &VPCIPv4CreateOptions{ VPC: i.IPv4.VPC, NAT1To1: i.IPv4.NAT1To1, } @@ -189,7 +199,7 @@ func (i InstanceConfigInterface) GetUpdateOptions() InstanceConfigInterfaceUpdat if i.Purpose == InterfacePurposeVPC { if i.IPv4 != nil { - opts.IPv4 = &VPCIPv4{ + opts.IPv4 = &VPCIPv4UpdateOptions{ VPC: i.IPv4.VPC, NAT1To1: i.IPv4.NAT1To1, } diff --git a/interfaces.go b/interfaces.go index 7d812c820..8dc7b179e 100644 --- a/interfaces.go +++ b/interfaces.go @@ -25,6 +25,16 @@ type InterfaceDefaultRoute struct { IPv6 *bool `json:"ipv6,omitzero"` } +type InterfaceDefaultRouteCreateOptions struct { + IPv4 *bool `json:"ipv4,omitzero"` + IPv6 *bool `json:"ipv6,omitzero"` +} + +type InterfaceDefaultRouteUpdateOptions struct { + IPv4 *bool `json:"ipv4,omitzero"` + IPv6 *bool `json:"ipv6,omitzero"` +} + type PublicInterface struct { IPv4 *PublicInterfaceIPv4 `json:"ipv4"` IPv6 *PublicInterfaceIPv6 `json:"ipv6"` @@ -111,18 +121,23 @@ type VLANInterface struct { IPAMAddress *string `json:"ipam_address,omitzero"` } +type VLANInterfaceCreateOptions struct { + VLANLabel string `json:"vlan_label"` + IPAMAddress *string `json:"ipam_address,omitzero"` +} + type LinodeInterfaceCreateOptions struct { - FirewallID *int `json:"firewall_id,omitzero"` - DefaultRoute *InterfaceDefaultRoute `json:"default_route,omitzero"` - Public *PublicInterfaceCreateOptions `json:"public,omitzero"` - VPC *VPCInterfaceCreateOptions `json:"vpc,omitzero"` - VLAN *VLANInterface `json:"vlan,omitzero"` + FirewallID *int `json:"firewall_id,omitzero"` + DefaultRoute *InterfaceDefaultRouteCreateOptions `json:"default_route,omitzero"` + Public *PublicInterfaceCreateOptions `json:"public,omitzero"` + VPC *VPCInterfaceCreateOptions `json:"vpc,omitzero"` + VLAN *VLANInterfaceCreateOptions `json:"vlan,omitzero"` } type LinodeInterfaceUpdateOptions struct { - DefaultRoute *InterfaceDefaultRoute `json:"default_route,omitzero"` - Public *PublicInterfaceCreateOptions `json:"public,omitzero"` - VPC *VPCInterfaceUpdateOptions `json:"vpc,omitzero"` + DefaultRoute *InterfaceDefaultRouteUpdateOptions `json:"default_route,omitzero"` + Public *PublicInterfaceCreateOptions `json:"public,omitzero"` + VPC *VPCInterfaceUpdateOptions `json:"vpc,omitzero"` } type PublicInterfaceCreateOptions struct { diff --git a/object_storage_keys.go b/object_storage_keys.go index b372bb3bf..3da396c9a 100644 --- a/object_storage_keys.go +++ b/object_storage_keys.go @@ -29,11 +29,18 @@ type ObjectStorageKeyBucketAccess struct { Permissions string `json:"permissions"` } +type ObjectStorageKeyBucketAccessCreateOptions struct { + Region string `json:"region,omitzero"` + + BucketName string `json:"bucket_name"` + Permissions string `json:"permissions"` +} + // ObjectStorageKeyCreateOptions fields are those accepted by CreateObjectStorageKey type ObjectStorageKeyCreateOptions struct { - Label string `json:"label"` - BucketAccess []ObjectStorageKeyBucketAccess `json:"bucket_access,omitzero"` - Regions []string `json:"regions,omitzero"` + Label string `json:"label"` + BucketAccess []ObjectStorageKeyBucketAccessCreateOptions `json:"bucket_access,omitzero"` + Regions []string `json:"regions,omitzero"` } // ObjectStorageKeyUpdateOptions fields are those accepted by UpdateObjectStorageKey diff --git a/test/integration/firewall_rules_test.go b/test/integration/firewall_rules_test.go index dda91056e..28818731d 100644 --- a/test/integration/firewall_rules_test.go +++ b/test/integration/firewall_rules_test.go @@ -9,7 +9,17 @@ import ( ) var ( - testFirewallRule = linodego.FirewallRule{ + testFirewallRuleInbound = linodego.FirewallRuleInbound{ + Label: "go-fwrule-test", + Action: "ACCEPT", + Ports: "22", + Protocol: "TCP", + Addresses: linodego.NetworkAddresses{ + IPv4: []string{"0.0.0.0/0"}, + IPv6: []string{"::0/0"}, + }, + } + testFirewallRuleOutbound = linodego.FirewallRuleOutbound{ Label: "go-fwrule-test", Action: "ACCEPT", Ports: "22", @@ -20,10 +30,10 @@ var ( }, } - testFirewallRuleSet = linodego.FirewallRuleSet{ - Inbound: []linodego.FirewallRule{testFirewallRule}, + testFirewallRuleSet = linodego.FirewallRulesCreateOptions{ + Inbound: []linodego.FirewallRuleInbound{testFirewallRuleInbound}, InboundPolicy: "ACCEPT", - Outbound: []linodego.FirewallRule{testFirewallRule}, + Outbound: []linodego.FirewallRuleOutbound{testFirewallRuleOutbound}, OutboundPolicy: "ACCEPT", } ) @@ -74,10 +84,10 @@ func TestFirewallRules_Update(t *testing.T) { } defer teardown() - newRules := linodego.FirewallRuleSet{ - Inbound: []linodego.FirewallRule{ + newRules := linodego.FirewallRulesUpdateOptions{ + Inbound: []linodego.FirewallRuleInbound{ { - Label: testFirewallRule.Label + "_r", + Label: testFirewallRuleInbound.Label + "_r", Action: "DROP", Ports: "22", Protocol: "TCP", diff --git a/test/integration/firewall_rulesets_test.go b/test/integration/firewall_rulesets_test.go index 4bb1c2398..91c959556 100644 --- a/test/integration/firewall_rulesets_test.go +++ b/test/integration/firewall_rulesets_test.go @@ -14,11 +14,11 @@ func TestFirewallRuleSets_CRUD(t *testing.T) { ctx := context.Background() label := "rs-51452000" - createOpts := linodego.RuleSetCreateOptions{ + createOpts := linodego.FirewallRuleSetCreateOptions{ Label: label, Description: "Allow inbound HTTP", Type: linodego.FirewallRuleSetTypeInbound, - Rules: []linodego.FirewallRule{ + Rules: []linodego.FirewallRuleSetRuleCreateOptions{ { Label: "allow-http", Action: "ACCEPT", @@ -64,7 +64,7 @@ func TestFirewallRuleSets_CRUD(t *testing.T) { updatedLabel := label + "-updated" updatedDescription := "Updated description" - updatedRules := []linodego.FirewallRule{ + updatedRules := []linodego.FirewallRuleSetRuleUpdateOptions{ { Label: "allow-https", Action: "ACCEPT", @@ -76,7 +76,7 @@ func TestFirewallRuleSets_CRUD(t *testing.T) { }, } - updateOpts := linodego.RuleSetUpdateOptions{ + updateOpts := linodego.FirewallRuleSetUpdateOptions{ Label: &updatedLabel, Description: &updatedDescription, Rules: updatedRules, diff --git a/test/integration/firewalls_test.go b/test/integration/firewalls_test.go index 3b8b01333..ca8a4aaa1 100644 --- a/test/integration/firewalls_test.go +++ b/test/integration/firewalls_test.go @@ -18,7 +18,10 @@ var testFirewallCreateOpts = linodego.FirewallCreateOptions{ // ignoreNetworkAddresses negates comparing IP addresses. Because of fixture sanitization, // these addresses will be changed to bogus values when running tests. -var ignoreNetworkAddresses = cmpopts.IgnoreFields(linodego.FirewallRule{}, "Addresses") +var ignoreNetworkAddresses = cmp.Options{ + cmpopts.IgnoreFields(linodego.FirewallRuleInbound{}, "Addresses"), + cmpopts.IgnoreFields(linodego.FirewallRuleOutbound{}, "Addresses"), +} // ignoreFirewallTimestamps negates comparing created and updated timestamps. Because of // fixture sanitization, these addresses will be changed to bogus values when running tests. @@ -46,8 +49,8 @@ func TestFirewalls_List_smoke(t *testing.T) { } func TestFirewall_Get(t *testing.T) { - rules := linodego.FirewallRuleSet{ - Inbound: []linodego.FirewallRule{ + rules := linodego.FirewallRulesCreateOptions{ + Inbound: []linodego.FirewallRuleInbound{ { Label: "linodego-fwrule-test", Action: "DROP", @@ -87,9 +90,9 @@ func TestFirewall_Get(t *testing.T) { } func TestFirewall_Update(t *testing.T) { - rules := linodego.FirewallRuleSet{ + rules := linodego.FirewallRulesCreateOptions{ InboundPolicy: "ACCEPT", - Inbound: []linodego.FirewallRule{ + Inbound: []linodego.FirewallRuleInbound{ { Label: "linodego-fwrule-test", Action: "DROP", diff --git a/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml b/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml index dfef91138..4ad963898 100644 --- a/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml +++ b/test/integration/fixtures/TestFirewallRuleSets_CRUD.yaml @@ -14,7 +14,7 @@ interactions: url: https://api.linode.com/v4beta/networking/firewalls/rulesets method: POST response: - body: '{"id": 66319, "version": 1, "label": "rs-51452000", "description": "Allow + body: '{"id": 76228, "version": 1, "label": "rs-51452000", "description": "Allow inbound HTTP", "type": "inbound", "is_service_defined": false, "rules": [{"action": "ACCEPT", "label": "allow-http", "ports": "80", "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", @@ -43,7 +43,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 05 May 2026 23:45:09 GMT + - Tue, 19 May 2026 19:46:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -76,10 +76,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/rulesets/66319 + url: https://api.linode.com/v4beta/networking/firewalls/rulesets/76228 method: GET response: - body: '{"id": 66319, "version": 1, "label": "rs-51452000", "description": "Allow + body: '{"id": 76228, "version": 1, "label": "rs-51452000", "description": "Allow inbound HTTP", "type": "inbound", "is_service_defined": false, "rules": [{"label": "allow-http", "ports": "80", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv4": ["0.0.0.0/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", @@ -108,7 +108,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 05 May 2026 23:45:09 GMT + - Tue, 19 May 2026 19:46:09 GMT Pragma: - no-cache Strict-Transport-Security: @@ -142,10 +142,10 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/rulesets/66319 + url: https://api.linode.com/v4beta/networking/firewalls/rulesets/76228 method: PUT response: - body: '{"id": 66319, "version": 2, "label": "rs-51452000-updated", "description": + body: '{"id": 76228, "version": 2, "label": "rs-51452000-updated", "description": "Updated description", "type": "inbound", "is_service_defined": false, "rules": [{"label": "allow-https", "ports": "443", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"]}}], "created": "2018-01-02T03:04:05", "updated": @@ -174,7 +174,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 05 May 2026 23:45:09 GMT + - Tue, 19 May 2026 19:46:10 GMT Pragma: - no-cache Strict-Transport-Security: @@ -219,7 +219,12 @@ interactions: "inbound", "is_service_defined": false, "rules": [{"label": "allow-https", "ports": "443", "action": "ACCEPT", "protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"]}}], "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "deleted": - null}], "page": 1, "pages": 1, "results": 2}' + "2018-01-02T03:04:05"}, {"id": 76228, "version": 2, "label": "rs-51452000-updated", + "description": "Updated description", "type": "inbound", "is_service_defined": + false, "rules": [{"label": "allow-https", "ports": "443", "action": "ACCEPT", + "protocol": "TCP", "addresses": {"ipv6": ["1234::5678/0"]}}], "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "deleted": null}], "page": 1, "pages": 1, + "results": 3}' headers: Access-Control-Allow-Credentials: - "true" @@ -237,14 +242,12 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "778" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Tue, 05 May 2026 23:45:10 GMT + - Tue, 19 May 2026 19:46:10 GMT Pragma: - no-cache Strict-Transport-Security: @@ -252,6 +255,7 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - firewall:read_only X-Content-Type-Options: @@ -278,7 +282,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/networking/firewalls/rulesets/66319 + url: https://api.linode.com/v4beta/networking/firewalls/rulesets/76228 method: DELETE response: body: '{}' @@ -306,7 +310,7 @@ interactions: Content-Type: - application/json Expires: - - Tue, 05 May 2026 23:45:11 GMT + - Tue, 19 May 2026 19:46:10 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/instance_config_test.go b/test/integration/instance_config_test.go index 5b93ca820..b0e0a68dd 100644 --- a/test/integration/instance_config_test.go +++ b/test/integration/instance_config_test.go @@ -89,7 +89,7 @@ func setupInstanceWithVPCAndNATOneToOne(t *testing.T, fixturesYaml string) ( { Purpose: InterfacePurposeVPC, SubnetID: &vpcSubnet.ID, - IPv4: &VPCIPv4{ + IPv4: &VPCIPv4CreateOptions{ NAT1To1: &NAT1To1Any, }, }, @@ -183,7 +183,7 @@ func setupInstanceWithDualStackVPCAndNAT11(t *testing.T, fixturesYaml string) ( { Purpose: InterfacePurposeVPC, SubnetID: &vpcSubnet.ID, - IPv4: &VPCIPv4{ + IPv4: &VPCIPv4CreateOptions{ NAT1To1: &NAT1To1Any, }, IPv6: &InstanceConfigInterfaceCreateOptionsIPv6{ @@ -244,7 +244,7 @@ func setupInstanceWith3Interfaces(t *testing.T, fixturesYaml string) ( { Purpose: InterfacePurposeVPC, SubnetID: &vpcSubnet.ID, - IPv4: &VPCIPv4{ + IPv4: &VPCIPv4CreateOptions{ NAT1To1: &NAT1To1Any, }, }, @@ -490,7 +490,7 @@ func TestInstance_ConfigInterfaces_Update(t *testing.T) { { Purpose: InterfacePurposeVPC, SubnetID: &vpcSubnet.ID, - IPv4: &VPCIPv4{ + IPv4: &VPCIPv4CreateOptions{ VPC: "192.168.0.87", }, }, @@ -590,7 +590,7 @@ func TestInstance_ConfigInterface_Update(t *testing.T) { } NAT1To1Any := "any" - updateOpts.IPv4 = &VPCIPv4{ + updateOpts.IPv4 = &VPCIPv4UpdateOptions{ VPC: "192.168.0.10", NAT1To1: &NAT1To1Any, } diff --git a/test/integration/main_test.go b/test/integration/main_test.go index 979f34da5..fb5d2c457 100644 --- a/test/integration/main_test.go +++ b/test/integration/main_test.go @@ -76,8 +76,8 @@ func deleteCloudFirewall() { } } -func getDefaultFirewallRuleSet(publicIPv4 string) linodego.FirewallRuleSet { - cloudFirewallRule := linodego.FirewallRule{ +func getDefaultFirewallRuleSet(publicIPv4 string) linodego.FirewallRulesCreateOptions { + cloudFirewallRuleInbound := linodego.FirewallRuleInbound{ Label: "ssh-inbound-accept-local", Action: "ACCEPT", Ports: "22", @@ -85,10 +85,10 @@ func getDefaultFirewallRuleSet(publicIPv4 string) linodego.FirewallRuleSet { Addresses: linodego.NetworkAddresses{IPv4: []string{publicIPv4}}, } - return linodego.FirewallRuleSet{ - Inbound: []linodego.FirewallRule{cloudFirewallRule}, + return linodego.FirewallRulesCreateOptions{ + Inbound: []linodego.FirewallRuleInbound{cloudFirewallRuleInbound}, InboundPolicy: "DROP", - Outbound: []linodego.FirewallRule{}, + Outbound: []linodego.FirewallRuleOutbound{}, OutboundPolicy: "ACCEPT", } } diff --git a/test/integration/nodebalancer_configs_test.go b/test/integration/nodebalancer_configs_test.go index f318371da..9cbe2203b 100644 --- a/test/integration/nodebalancer_configs_test.go +++ b/test/integration/nodebalancer_configs_test.go @@ -284,7 +284,7 @@ func setupNodeBalancerWithVPCAndInstance( { Purpose: "vpc", SubnetID: &subnet.ID, - IPv4: &linodego.VPCIPv4{ + IPv4: &linodego.VPCIPv4CreateOptions{ NAT1To1: &NAT1To1Any, }, }, diff --git a/test/integration/object_storage_keys_test.go b/test/integration/object_storage_keys_test.go index 7ce548d89..5a38b66c1 100644 --- a/test/integration/object_storage_keys_test.go +++ b/test/integration/object_storage_keys_test.go @@ -6,7 +6,6 @@ import ( "strings" "testing" - "github.com/google/go-cmp/cmp" "github.com/linode/linodego" . "github.com/linode/linodego" ) @@ -113,8 +112,12 @@ func TestObjectStorageKeys_Limited(t *testing.T) { ) defer teardown() + if err != nil { + t.Fatal(err) + } + createOpts := testBasicObjectStorageKeyCreateOpts - createOpts.BucketAccess = []ObjectStorageKeyBucketAccess{ + createOpts.BucketAccess = []ObjectStorageKeyBucketAccessCreateOptions{ { Region: "us-east", BucketName: bucket.Label, @@ -132,12 +135,24 @@ func TestObjectStorageKeys_Limited(t *testing.T) { if err != nil { t.Error(err) } - if !objectStorageKey.Limited || !cmp.Equal(*objectStorageKey.BucketAccess, createOpts.BucketAccess) { - t.Errorf( - "objectStorageKey returned (%v) does not match objectStorageKey creation request (%v)", - *objectStorageKey.BucketAccess, - createOpts.BucketAccess, - ) + if !objectStorageKey.Limited { + t.Errorf("expected key to be limited") + } + + if objectStorageKey.BucketAccess == nil { + t.Fatalf("expected BucketAccess to be set on returned key") + } + + // Compare values field-by-field to avoid relying on concrete types. + got := *objectStorageKey.BucketAccess + if len(got) != len(createOpts.BucketAccess) { + t.Fatalf("bucket access length mismatch: got %d, want %d", len(got), len(createOpts.BucketAccess)) + } + for i := range got { + want := createOpts.BucketAccess[i] + if got[i].Region != want.Region || got[i].BucketName != want.BucketName || got[i].Permissions != want.Permissions { + t.Errorf("bucket access mismatch at index %d: got %+v, want %+v", i, got[i], want) + } } } @@ -145,7 +160,7 @@ func TestObjectStorageKeys_Limited_NoAccess(t *testing.T) { t.Skip("skipping test due to unexpected API behavior with limited object storage keys") createOpts := testBasicObjectStorageKeyCreateOpts - createOpts.BucketAccess = []ObjectStorageKeyBucketAccess{} + createOpts.BucketAccess = []ObjectStorageKeyBucketAccessCreateOptions{} _, objectStorageKey, teardown, err := setupObjectStorageKey(t, createOpts, "fixtures/TestObjectStorageKeys_Limited_NoAccess", nil, nil) defer teardown() @@ -178,7 +193,7 @@ func TestObjectStorageKeys_Regional_Limited(t *testing.T) { } createOpts := testBasicObjectStorageKeyCreateOpts - createOpts.BucketAccess = []ObjectStorageKeyBucketAccess{ + createOpts.BucketAccess = []ObjectStorageKeyBucketAccessCreateOptions{ { Region: region, BucketName: bucket.Label, diff --git a/test/unit/firewall_rules_test.go b/test/unit/firewall_rules_test.go index ded63bf89..10a25c281 100644 --- a/test/unit/firewall_rules_test.go +++ b/test/unit/firewall_rules_test.go @@ -49,13 +49,8 @@ func TestFirewallRule_Get(t *testing.T) { } func TestFirewallRule_MarshalJSON(t *testing.T) { - ruleWithRuleset := linodego.FirewallRule{RuleSet: 51} - data, err := json.Marshal(ruleWithRuleset) - assert.NoError(t, err) - assert.JSONEq(t, `{"ruleset":51}`, string(data)) - ipv4 := []string{"pl::vpcs:123"} - ruleWithoutRuleset := linodego.FirewallRule{ + ruleWithoutRuleset := linodego.FirewallRuleSetRuleCreateOptions{ Action: "ACCEPT", Label: "allow-vpc", Ports: "443", @@ -64,7 +59,7 @@ func TestFirewallRule_MarshalJSON(t *testing.T) { IPv4: ipv4, }, } - data, err = json.Marshal(ruleWithoutRuleset) + data, err := json.Marshal(ruleWithoutRuleset) assert.NoError(t, err) assert.JSONEq(t, `{ "action":"ACCEPT", @@ -86,8 +81,8 @@ func TestFirewallRule_Update(t *testing.T) { firewallID := 123 base.MockPut(formatMockAPIPath("networking/firewalls/%d/rules", firewallID), fixtureData) - requestData := linodego.FirewallRuleSet{ - Inbound: []linodego.FirewallRule{ + requestData := linodego.FirewallRulesUpdateOptions{ + Inbound: []linodego.FirewallRuleInbound{ { Action: "ACCEPT", Label: "firewallrule123", @@ -101,7 +96,7 @@ func TestFirewallRule_Update(t *testing.T) { }, }, InboundPolicy: "DROP", - Outbound: []linodego.FirewallRule{ + Outbound: []linodego.FirewallRuleOutbound{ { Action: "ACCEPT", Label: "firewallrule123", @@ -151,8 +146,8 @@ func TestFirewallRule_GetExpansion(t *testing.T) { outboundIPv4 := []string{"pl::vpcs:1234"} outboundIPv6 := []string{"pl::vpcs:"} - mockResponse := linodego.FirewallRuleSet{ - Inbound: []linodego.FirewallRule{ + mockResponse := linodego.FirewallRules{ + Inbound: []linodego.FirewallRuleInbound{ { Action: "ACCEPT", Label: "accept-inbound-ssh", @@ -166,7 +161,7 @@ func TestFirewallRule_GetExpansion(t *testing.T) { }, }, InboundPolicy: "DROP", - Outbound: []linodego.FirewallRule{ + Outbound: []linodego.FirewallRuleOutbound{ { Action: "ACCEPT", Label: "accept-outbound-ssh", diff --git a/test/unit/firewall_rulesets_test.go b/test/unit/firewall_rulesets_test.go index 5c069f900..8a4f7f3ee 100644 --- a/test/unit/firewall_rulesets_test.go +++ b/test/unit/firewall_rulesets_test.go @@ -31,10 +31,9 @@ func TestFirewallRuleSets_List(t *testing.T) { "ipv4": []string{"pl::vpcs:primary"}, "ipv6": []string{"pl::vpcs:primary"}, }, - "label": "ssh", - "ports": "22", - "protocol": "TCP", - "description": "Allow inbound SSH", + "label": "ssh", + "ports": "22", + "protocol": "TCP", }, }, "version": 3, @@ -93,7 +92,13 @@ func TestFirewallRuleSets_Get(t *testing.T) { "type": "outbound", "rules": []map[string]any{ { - "ruleset": 77, + "action": "ACCEPT", + "addresses": map[string]any{ + "ipv4": []string{"0.0.0.0/0"}, + }, + "label": "egress", + "ports": "443", + "protocol": "TCP", }, }, "version": 4, @@ -110,9 +115,7 @@ func TestFirewallRuleSets_Get(t *testing.T) { assert.Equal(t, ruleSetID, rs.ID) assert.Equal(t, linodego.FirewallRuleSetTypeOutbound, rs.Type) assert.True(t, rs.IsServiceDefined) - if assert.Len(t, rs.Rules, 1) { - assert.Equal(t, 77, rs.Rules[0].RuleSet) - } + assert.Len(t, rs.Rules, 1) if assert.NotNil(t, rs.Created) { assert.Equal(t, time.Date(2024, time.February, 1, 1, 1, 1, 0, time.UTC), rs.Created.UTC()) } @@ -124,11 +127,11 @@ func TestFirewallRuleSets_Get(t *testing.T) { func TestFirewallRuleSets_Create(t *testing.T) { client := createMockClient(t) - req := linodego.RuleSetCreateOptions{ + req := linodego.FirewallRuleSetCreateOptions{ Label: "allow-vpc", Description: "Allow VPC ingress", Type: linodego.FirewallRuleSetTypeInbound, - Rules: []linodego.FirewallRule{ + Rules: []linodego.FirewallRuleSetRuleCreateOptions{ { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ @@ -177,7 +180,7 @@ func TestFirewallRuleSets_Update(t *testing.T) { ruleSetID := 404 label := "updated-egress" description := "Updated description" - rules := []linodego.FirewallRule{ + rules := []linodego.FirewallRuleSetRuleUpdateOptions{ { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ @@ -189,7 +192,7 @@ func TestFirewallRuleSets_Update(t *testing.T) { }, } - req := linodego.RuleSetUpdateOptions{ + req := linodego.FirewallRuleSetUpdateOptions{ Label: &label, Description: &description, Rules: rules, @@ -236,7 +239,7 @@ func TestFirewallRuleSets_Delete(t *testing.T) { } func TestRuleSet_UnmarshalJSON(t *testing.T) { - var rs linodego.RuleSet + var rs linodego.FirewallRuleSet raw := []byte(`{ "id": 42, @@ -244,7 +247,13 @@ func TestRuleSet_UnmarshalJSON(t *testing.T) { "type": "inbound", "description": "Combined rule set", "rules": [ - {"ruleset": 12} + { + "action": "ACCEPT", + "label": "combined-rule", + "ports": "443", + "protocol": "TCP", + "addresses": {"ipv4": ["0.0.0.0/0"]} + } ], "version": 2, "is_service_defined": false, @@ -264,13 +273,11 @@ func TestRuleSet_UnmarshalJSON(t *testing.T) { if assert.NotNil(t, rs.Deleted) { assert.Equal(t, time.Date(2023, time.May, 5, 5, 5, 5, 0, time.UTC), rs.Deleted.UTC()) } - if assert.Len(t, rs.Rules, 1) { - assert.Equal(t, 12, rs.Rules[0].RuleSet) - } + assert.Len(t, rs.Rules, 1) } func TestRuleSet_UnmarshalJSONServiceDefined(t *testing.T) { - var rs linodego.RuleSet + var rs linodego.FirewallRuleSet raw := []byte(`{ "id": 99, diff --git a/test/unit/firewalls_test.go b/test/unit/firewalls_test.go index e312334f4..aff145b37 100644 --- a/test/unit/firewalls_test.go +++ b/test/unit/firewalls_test.go @@ -67,10 +67,10 @@ func TestFirewall_Create(t *testing.T) { requestData := linodego.FirewallCreateOptions{ Label: "firewall123", - Rules: linodego.FirewallRuleSet{ + Rules: linodego.FirewallRulesCreateOptions{ InboundPolicy: "DROP", OutboundPolicy: "DROP", - Inbound: []linodego.FirewallRule{ + Inbound: []linodego.FirewallRuleInbound{ { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ @@ -83,7 +83,7 @@ func TestFirewall_Create(t *testing.T) { Protocol: "TCP", }, }, - Outbound: []linodego.FirewallRule{ + Outbound: []linodego.FirewallRuleOutbound{ { Action: "ACCEPT", Addresses: linodego.NetworkAddresses{ diff --git a/test/unit/instance_config_interfaces_test.go b/test/unit/instance_config_interfaces_test.go index 3a70384ae..68353c6b1 100644 --- a/test/unit/instance_config_interfaces_test.go +++ b/test/unit/instance_config_interfaces_test.go @@ -75,7 +75,7 @@ func TestInstanceConfigInterface_Create(t *testing.T) { Purpose: linodego.InterfacePurposeVPC, Primary: true, SubnetID: &subnetID, - IPv4: &linodego.VPCIPv4{ + IPv4: &linodego.VPCIPv4CreateOptions{ NAT1To1: &nat1to1, }, IPRanges: []string{"192.168.1.0/24"}, @@ -111,7 +111,7 @@ func TestInstanceConfigInterface_Update(t *testing.T) { updateOptions := linodego.InstanceConfigInterfaceUpdateOptions{ Primary: true, - IPv4: &linodego.VPCIPv4{ + IPv4: &linodego.VPCIPv4UpdateOptions{ NAT1To1: &nat1to1, }, IPRanges: ipRanges, diff --git a/test/unit/interface_test.go b/test/unit/interface_test.go index 7a2f61b2e..8432e8206 100644 --- a/test/unit/interface_test.go +++ b/test/unit/interface_test.go @@ -191,7 +191,7 @@ func TestInterface_UpdateVLAN(t *testing.T) { base.MockPut("linode/instances/123/interfaces/123", fixtureData) opts := linodego.LinodeInterfaceUpdateOptions{ - DefaultRoute: &linodego.InterfaceDefaultRoute{ + DefaultRoute: &linodego.InterfaceDefaultRouteUpdateOptions{ IPv6: linodego.Pointer(true), }, } @@ -221,7 +221,7 @@ func TestInterface_UpdateVPC(t *testing.T) { base.MockPut("linode/instances/123/interfaces/456", fixtureData) opts := linodego.LinodeInterfaceUpdateOptions{ - DefaultRoute: &linodego.InterfaceDefaultRoute{ + DefaultRoute: &linodego.InterfaceDefaultRouteUpdateOptions{ IPv4: linodego.Pointer(true), IPv6: linodego.Pointer(true), }, From 3e91ded2403febdf4579713ae7d5235eebfd2982 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Wed, 20 May 2026 11:35:40 -0400 Subject: [PATCH 12/17] TPT-4464: Update FirewallDeviceEntity Label field to be a pointer (#971) * Update FirewallDeviceEntity Label field to be a pointer and adjust tests accordingly * Fix unit tests * fmt * Fix another unit test --- firewall_devices.go | 2 +- test/integration/firewalls_devices_test.go | 4 ++-- test/unit/firewall_devices_test.go | 18 ++++++++++++------ test/unit/firewalls_test.go | 4 +++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/firewall_devices.go b/firewall_devices.go index 93ce2220c..2af2f909e 100644 --- a/firewall_devices.go +++ b/firewall_devices.go @@ -59,7 +59,7 @@ func (device *FirewallDevice) UnmarshalJSON(b []byte) error { type FirewallDeviceEntity struct { ID int `json:"id"` Type FirewallDeviceType `json:"type"` - Label string `json:"label"` + Label *string `json:"label"` URL string `json:"url"` ParentEntity *FirewallDeviceEntity `json:"parent_entity"` } diff --git a/test/integration/firewalls_devices_test.go b/test/integration/firewalls_devices_test.go index 93f4f30c9..e51d55a3d 100644 --- a/test/integration/firewalls_devices_test.go +++ b/test/integration/firewalls_devices_test.go @@ -56,7 +56,7 @@ func TestFirewallDevices_List_smoke(t *testing.T) { if firewallDevices[0].Entity.ID != instance.ID { t.Errorf("expected device entity id %d, got %d", instance.ID, firewallDevices[0].Entity.ID) } - if firewallDevices[0].Entity.Label == "" { + if firewallDevices[0].Entity.Label == nil || *firewallDevices[0].Entity.Label == "" { t.Error("expected non-empty device entity label") } if firewallDevices[0].Entity.ParentEntity != nil { @@ -91,7 +91,7 @@ func TestFirewallDevice_Get(t *testing.T) { } else if !cmp.Equal(device, firewallDevice) { t.Errorf("expected device to match create result but got diffs: %s", cmp.Diff(device, firewallDevice)) } else { - if device.Entity.Label == "" { + if device.Entity.Label == nil || *device.Entity.Label == "" { t.Error("expected non-empty device entity label") } if device.Entity.ParentEntity != nil { diff --git a/test/unit/firewall_devices_test.go b/test/unit/firewall_devices_test.go index a547b1a3f..8462b2fdc 100644 --- a/test/unit/firewall_devices_test.go +++ b/test/unit/firewall_devices_test.go @@ -8,6 +8,7 @@ import ( "github.com/jarcoal/httpmock" "github.com/linode/linodego" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFirewallDevice_List(t *testing.T) { @@ -37,12 +38,14 @@ func TestFirewallDevice_List(t *testing.T) { switch device.Entity.Type { case "linode": assert.Equal(t, 123, device.Entity.ID) - assert.Equal(t, "my-linode", device.Entity.Label) + require.NotNil(t, device.Entity.Label) + assert.Equal(t, "my-linode", *device.Entity.Label) assert.Equal(t, "/v4/linode/instances/123", device.Entity.URL) assert.Nil(t, device.Entity.ParentEntity) case "nodebalancer": assert.Equal(t, 321, device.Entity.ID) - assert.Equal(t, "my-nodebalancer", device.Entity.Label) + require.NotNil(t, device.Entity.Label) + assert.Equal(t, "my-nodebalancer", *device.Entity.Label) assert.Equal(t, "/v4/nodebalancers/123", device.Entity.URL) assert.Nil(t, device.Entity.ParentEntity) default: @@ -73,7 +76,8 @@ func TestFirewallDevice_Get(t *testing.T) { assert.NotNil(t, firewallDevice.Entity) assert.Equal(t, 123, firewallDevice.Entity.ID) - assert.Equal(t, "my-linode", firewallDevice.Entity.Label) + require.NotNil(t, firewallDevice.Entity.Label) + assert.Equal(t, "my-linode", *firewallDevice.Entity.Label) assert.Equal(t, linodego.FirewallDeviceType("linode"), firewallDevice.Entity.Type) assert.Equal(t, "/v4/linode/instances/123", firewallDevice.Entity.URL) assert.Nil(t, firewallDevice.Entity.ParentEntity) @@ -106,7 +110,8 @@ func TestFirewallDevice_Create(t *testing.T) { assert.NotNil(t, firewallDevice.Entity) assert.Equal(t, 123, firewallDevice.Entity.ID) - assert.Equal(t, "my-linode", firewallDevice.Entity.Label) + require.NotNil(t, firewallDevice.Entity.Label) + assert.Equal(t, "my-linode", *firewallDevice.Entity.Label) assert.Equal(t, linodego.FirewallDeviceType("linode"), firewallDevice.Entity.Type) assert.Equal(t, "/v4/linode/instances/123", firewallDevice.Entity.URL) assert.Nil(t, firewallDevice.Entity.ParentEntity) @@ -163,12 +168,13 @@ func TestFirewallDevice_Get_WithParentEntity(t *testing.T) { assert.NotNil(t, device) assert.Equal(t, linodego.FirewallDeviceLinodeInterface, device.Entity.Type) - assert.Equal(t, device.Entity.Label, "") + assert.Nil(t, device.Entity.Label, nil) if assert.NotNil(t, device.Entity.ParentEntity) { assert.Equal(t, 123, device.Entity.ParentEntity.ID) assert.Equal(t, linodego.FirewallDeviceLinode, device.Entity.ParentEntity.Type) - assert.Equal(t, "my-linode", device.Entity.ParentEntity.Label) + require.NotNil(t, device.Entity.ParentEntity.Label) + assert.Equal(t, "my-linode", *device.Entity.ParentEntity.Label) assert.Equal(t, "/v4/linode/instances/123", device.Entity.ParentEntity.URL) } } diff --git a/test/unit/firewalls_test.go b/test/unit/firewalls_test.go index aff145b37..eadf70311 100644 --- a/test/unit/firewalls_test.go +++ b/test/unit/firewalls_test.go @@ -9,6 +9,7 @@ import ( "github.com/jarcoal/httpmock" "github.com/linode/linodego" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFirewall_List(t *testing.T) { @@ -149,7 +150,8 @@ func TestFirewall_Create(t *testing.T) { assert.NotNil(t, entity.ParentEntity) assert.Equal(t, 92759172, entity.ParentEntity.ID) assert.Equal(t, linodego.FirewallDeviceLinode, entity.ParentEntity.Type) - assert.Equal(t, "test-01", entity.ParentEntity.Label) + require.NotNil(t, entity.ParentEntity.Label) + assert.Equal(t, "test-01", *entity.ParentEntity.Label) assert.Equal(t, "/v4/linode/instances/92759172", entity.ParentEntity.URL) assert.Nil(t, entity.ParentEntity.ParentEntity) } From 9faa4d30a0044caf0c5e703e814b7a4f4605d95e Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Wed, 20 May 2026 17:17:14 -0400 Subject: [PATCH 13/17] Change `[]*T` to `[]T` in all structs (#972) --- instance_ips.go | 10 +- instance_snapshots.go | 22 +- instances.go | 2 +- nodebalancer.go | 12 +- .../fixtures/TestEventPoller_Secondary.yaml | 1252 ++++++++++++----- test/integration/fixtures/TestVLANs_List.yaml | 1117 +++++++++------ test/integration/vlans_test.go | 4 +- test/integration/waitfor_test.go | 4 +- test/unit/nodebalancers_test.go | 2 +- 9 files changed, 1656 insertions(+), 769 deletions(-) diff --git a/instance_ips.go b/instance_ips.go index 281fb9574..eaf4fb24d 100644 --- a/instance_ips.go +++ b/instance_ips.go @@ -12,11 +12,11 @@ type InstanceIPAddressResponse struct { // InstanceIPv4Response contains the details of all IPv4 addresses associated with an Instance type InstanceIPv4Response struct { - Public []*InstanceIP `json:"public"` - Private []*InstanceIP `json:"private"` - Shared []*InstanceIP `json:"shared"` - Reserved []*InstanceIP `json:"reserved"` - VPC []*VPCIP `json:"vpc"` + Public []InstanceIP `json:"public"` + Private []InstanceIP `json:"private"` + Shared []InstanceIP `json:"shared"` + Reserved []InstanceIP `json:"reserved"` + VPC []VPCIP `json:"vpc"` } // InstanceIP represents an Instance IP with additional DNS and networking details diff --git a/instance_snapshots.go b/instance_snapshots.go index 241bd3267..b085297c3 100644 --- a/instance_snapshots.go +++ b/instance_snapshots.go @@ -10,7 +10,7 @@ import ( // InstanceBackupsResponse response struct for backup snapshot type InstanceBackupsResponse struct { - Automatic []*InstanceSnapshot `json:"automatic"` + Automatic []InstanceSnapshot `json:"automatic"` Snapshot *InstanceBackupSnapshotResponse `json:"snapshot"` } @@ -32,16 +32,16 @@ type RestoreInstanceOptions struct { // InstanceSnapshot represents a linode backup snapshot type InstanceSnapshot struct { - ID int `json:"id"` - Label string `json:"label"` - Status InstanceSnapshotStatus `json:"status"` - Type string `json:"type"` - Created *time.Time `json:"-"` - Updated *time.Time `json:"-"` - Finished *time.Time `json:"-"` - Configs []string `json:"configs"` - Disks []*InstanceSnapshotDisk `json:"disks"` - Available bool `json:"available"` + ID int `json:"id"` + Label string `json:"label"` + Status InstanceSnapshotStatus `json:"status"` + Type string `json:"type"` + Created *time.Time `json:"-"` + Updated *time.Time `json:"-"` + Finished *time.Time `json:"-"` + Configs []string `json:"configs"` + Disks []InstanceSnapshotDisk `json:"disks"` + Available bool `json:"available"` } // InstanceSnapshotDisk fields represent the source disk of a Snapshot diff --git a/instances.go b/instances.go index 7a1a1eae1..6eb4d4c19 100644 --- a/instances.go +++ b/instances.go @@ -57,7 +57,7 @@ type Instance struct { Backups *InstanceBackup `json:"backups"` Image string `json:"image"` Group string `json:"group"` - IPv4 []*net.IP `json:"ipv4"` + IPv4 []net.IP `json:"ipv4"` IPv6 string `json:"ipv6"` Label string `json:"label"` Type string `json:"type"` diff --git a/nodebalancer.go b/nodebalancer.go index b1877ec4f..a3492db90 100644 --- a/nodebalancer.go +++ b/nodebalancer.go @@ -72,12 +72,12 @@ type NodeBalancerCreateOptions struct { // NOTE: ClientUDPSessThrottle may not currently be available to all users. ClientUDPSessThrottle *int `json:"client_udp_sess_throttle,omitzero"` - Configs []*NodeBalancerConfigCreateOptions `json:"configs,omitzero"` - Tags []string `json:"tags"` - FirewallID int `json:"firewall_id,omitzero"` - Type NodeBalancerPlanType `json:"type,omitzero"` - VPCs []NodeBalancerVPCOptions `json:"vpcs,omitzero"` - IPv4 *string `json:"ipv4,omitzero"` + Configs []NodeBalancerConfigCreateOptions `json:"configs,omitzero"` + Tags []string `json:"tags"` + FirewallID int `json:"firewall_id,omitzero"` + Type NodeBalancerPlanType `json:"type,omitzero"` + VPCs []NodeBalancerVPCOptions `json:"vpcs,omitzero"` + IPv4 *string `json:"ipv4,omitzero"` } // NodeBalancerUpdateOptions are the options permitted for UpdateNodeBalancer diff --git a/test/integration/fixtures/TestEventPoller_Secondary.yaml b/test/integration/fixtures/TestEventPoller_Secondary.yaml index 71d425eb1..615aaae10 100644 --- a/test/integration/fixtures/TestEventPoller_Secondary.yaml +++ b/test/integration/fixtures/TestEventPoller_Secondary.yaml @@ -14,194 +14,449 @@ interactions: url: https://api.linode.com/v4beta/regions?page=1 method: GET response: - body: '{"data": [{"id": "ap-west", "label": "Mumbai, IN", "country": "in", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud - Firewall", "Vlans", "Block Storage Migrations", "Managed Databases"], "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"}}, {"id": "ca-central", "label": "Toronto, CA", - "country": "ca", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases"], "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"}}, {"id": "ap-southeast", - "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "NodeBalancers", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Cloud Firewall", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "", "ipv6": ""}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": + "core"}, {"id": "co-bog-2", "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "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"}}, - {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": - ["Linodes", "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"}}, - {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "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"}}, - {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "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"}}, - {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "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"}}, {"id": "br-gru", "label": "Sao Paulo, BR", - "country": "br", "capabilities": ["Linodes", "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"}}, {"id": "nl-ams", - "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "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"}}, {"id": "se-sto", "label": "Stockholm, SE", - "country": "se", "capabilities": ["Linodes", "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"}}, - {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", - "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"}}, {"id": "in-maa", "label": "Chennai, IN", - "country": "in", "capabilities": ["Linodes", "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"}}, {"id": "jp-osa", - "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "NodeBalancers", - "Block Storage", "Object Storage", "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"}}, {"id": "it-mil", "label": "Milan, IT", "country": - "it", "capabilities": ["Linodes", "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"}}, - {"id": "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Premium Plans"], "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"}}, {"id": "id-cgk", "label": "Jakarta, ID", - "country": "id", "capabilities": ["Linodes", "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"}}, - {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": - ["Linodes", "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"}}, {"id": "us-central", - "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "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"}}, {"id": "us-west", "label": "Fremont, CA", "country": "us", - "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", - "Cloud Firewall", "Block Storage Migrations", "Managed Databases"], "status": + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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"}}, {"id": - "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases"], - "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"}}, - {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Bare Metal", "Vlans", "Block Storage Migrations", "Managed - Databases"], "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"}}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases"], "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"}}, - {"id": "ap-south", "label": "Singapore, SG", "country": "sg", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", - "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases"], "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"}}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", - "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "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"}}, {"id": "ap-northeast", "label": "Tokyo, JP", - "country": "jp", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Block Storage Migrations", "Managed Databases"], - "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"}}], - "page": 1, "pages": 1, "results": 25}' + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}, "placement_group_limits": + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -213,6 +468,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: @@ -222,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:04 GMT + - Wed, 20 May 2026 18:36:31 GMT Pragma: - no-cache Strict-Transport-Security: @@ -241,14 +498,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-ins-poll-test","booted":false}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-ins-poll-test","booted":false}' form: {} headers: Accept: @@ -260,15 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 53282734, "label": "go-ins-poll-test", "group": "", "status": "provisioning", + body: '{"id": 97900566, "label": "go-ins-poll-test", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "type": - "g6-nanode-1", "ipv4": ["45.79.123.17"], "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": + "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": null, "region": "au-mel", "site_type": "core", "specs": {"disk": 25600, + "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": - "926f6f61bf1247b3667bd94b88cd5ac7c8d33901", "has_user_data": false}' + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -280,24 +541,25 @@ 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: - - "720" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:04 GMT + - Wed, 20 May 2026 18:36:32 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: @@ -308,7 +570,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "10" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -325,16 +587,16 @@ interactions: User-Agent: - linodego/dev https://github.com/linode/linodego X-Filter: - - '{"+order":"desc","+order_by":"created","action":"linode_create","entity.id":53282734,"entity.type":"linode"}' + - '{"+order":"desc","+order_by":"created","action":"linode_create","entity.id":97900566,"entity.type":"linode"}' url: https://api.linode.com/v4beta/account/events?page=1 method: GET response: - body: '{"data": [{"id": 615701235, "created": "2018-01-02T03:04:05", "seen": false, - "read": false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": - 14.0, "action": "linode_create", "username": "lgarber-dev", "entity": {"label": - "go-ins-poll-test", "id": 53282734, "type": "linode", "url": "/v4/linode/instances/53282734"}, - "status": "finished", "secondary_entity": null, "message": ""}], "page": 1, - "pages": 1, "results": 1}' + body: '{"data": [{"id": 1586399760, "created": "2018-01-02T03:04:05", "seen": + false, "read": false, "percent_complete": 100, "time_remaining": null, "rate": + null, "duration": 8.0, "action": "linode_create", "username": "zliang27", "entity": + {"label": "go-ins-poll-test", "id": 97900566, "type": "linode", "url": "/v4/linode/instances/97900566"}, + "status": "finished", "secondary_entity": null, "message": "", "details": {}}], + "page": 1, "pages": 1, "results": 1}' headers: Access-Control-Allow-Credentials: - "true" @@ -346,18 +608,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: - - "440" + - "455" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:19 GMT + - Wed, 20 May 2026 18:36:47 GMT Pragma: - no-cache Strict-Transport-Security: @@ -375,7 +639,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -391,14 +655,14 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/account/events/615701235 + url: https://api.linode.com/v4beta/account/events/1586399760 method: GET response: - body: '{"id": 615701235, "created": "2018-01-02T03:04:05", "seen": false, "read": - false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": - 14.0, "action": "linode_create", "username": "lgarber-dev", "entity": {"label": - "go-ins-poll-test", "id": 53282734, "type": "linode", "url": "/v4/linode/instances/53282734"}, - "status": "finished", "secondary_entity": null, "message": ""}' + body: '{"id": 1586399760, "created": "2018-01-02T03:04:05", "seen": false, "read": + false, "percent_complete": 100, "time_remaining": null, "rate": null, "duration": + 8.0, "action": "linode_create", "username": "zliang27", "entity": {"label": + "go-ins-poll-test", "id": 97900566, "type": "linode", "url": "/v4/linode/instances/97900566"}, + "status": "finished", "secondary_entity": null, "message": "", "details": {}}' headers: Access-Control-Allow-Credentials: - "true" @@ -410,18 +674,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: - - "391" + - "406" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:19 GMT + - Wed, 20 May 2026 18:36:47 GMT Pragma: - no-cache Strict-Transport-Security: @@ -439,14 +705,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"deleteEvent-0","size":512}' + body: '{"label":"test-disk-0","size":512}' form: {} headers: Accept: @@ -455,12 +721,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks + url: https://api.linode.com/v4beta/linode/instances/97900566/disks method: POST response: - body: '{"id": 105633086, "status": "not ready", "label": "deleteEvent-0", "created": + body: '{"id": 184471993, "status": "not ready", "label": "test-disk-0", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": "ext4", - "size": 512}' + "size": 512, "disk_encryption": "enabled"}' headers: Access-Control-Allow-Credentials: - "true" @@ -472,18 +738,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: - - "169" + - "197" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:19 GMT + - Wed, 20 May 2026 18:36:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -500,14 +768,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"label":"deleteEvent-1","size":512}' + body: '{"label":"test-disk-1","size":512}' form: {} headers: Accept: @@ -516,7 +784,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks + url: https://api.linode.com/v4beta/linode/instances/97900566/disks method: POST response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -527,6 +795,8 @@ 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: @@ -534,9 +804,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:20 GMT + - Wed, 20 May 2026 18:36:48 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -544,12 +816,12 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" - request: - body: '{"label":"deleteEvent-1","size":512}' + body: '{"label":"test-disk-1","size":512}' form: {} headers: Accept: @@ -558,7 +830,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks + url: https://api.linode.com/v4beta/linode/instances/97900566/disks method: POST response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -569,6 +841,8 @@ 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: @@ -576,9 +850,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:23 GMT + - Wed, 20 May 2026 18:36:51 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -586,12 +862,12 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" - request: - body: '{"label":"deleteEvent-1","size":512}' + body: '{"label":"test-disk-1","size":512}' form: {} headers: Accept: @@ -600,12 +876,104 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks + url: https://api.linode.com/v4beta/linode/instances/97900566/disks method: POST response: - body: '{"id": 105633090, "status": "not ready", "label": "deleteEvent-1", "created": + body: '{"errors": [{"reason": "Linode busy."}]}' + 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: + - "40" + Content-Type: + - application/json + Expires: + - Wed, 20 May 2026 18:36:54 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"label":"test-disk-1","size":512}' + 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/97900566/disks + method: POST + response: + body: '{"errors": [{"reason": "Linode busy."}]}' + 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: + - "40" + Content-Type: + - application/json + Expires: + - Wed, 20 May 2026 18:36:57 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + status: 400 Bad Request + code: 400 + duration: "" +- request: + body: '{"label":"test-disk-1","size":512}' + 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/97900566/disks + method: POST + response: + body: '{"id": 184471998, "status": "not ready", "label": "test-disk-1", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": "ext4", - "size": 512}' + "size": 512, "disk_encryption": "enabled"}' headers: Access-Control-Allow-Credentials: - "true" @@ -617,18 +985,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: - - "169" + - "197" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:27 GMT + - Wed, 20 May 2026 18:37:01 GMT Pragma: - no-cache Strict-Transport-Security: @@ -645,7 +1015,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -662,7 +1032,7 @@ interactions: User-Agent: - linodego/dev https://github.com/linode/linodego X-Filter: - - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":53282734,"entity.type":"linode"}' + - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":97900566,"entity.type":"linode"}' url: https://api.linode.com/v4beta/account/events?page=1 method: GET response: @@ -678,6 +1048,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: @@ -689,7 +1061,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:27 GMT + - Wed, 20 May 2026 18:37:01 GMT Pragma: - no-cache Strict-Transport-Security: @@ -707,7 +1079,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -724,7 +1096,7 @@ interactions: User-Agent: - linodego/dev https://github.com/linode/linodego X-Filter: - - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":53282734,"entity.type":"linode"}' + - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":97900566,"entity.type":"linode"}' url: https://api.linode.com/v4beta/account/events?page=1 method: GET response: @@ -740,6 +1112,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: @@ -751,7 +1125,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:27 GMT + - Wed, 20 May 2026 18:37:01 GMT Pragma: - no-cache Strict-Transport-Security: @@ -769,7 +1143,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -785,7 +1159,103 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633086 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471993 + method: DELETE + response: + body: '{"errors": [{"reason": "Linode busy."}]}' + 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: + - "40" + Content-Type: + - application/json + Expires: + - Wed, 20 May 2026 18:37:01 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/97900566/disks/184471993 + method: DELETE + response: + body: '{"errors": [{"reason": "Linode busy."}]}' + 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: + - "40" + Content-Type: + - application/json + Expires: + - Wed, 20 May 2026 18:37:04 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/97900566/disks/184471993 method: DELETE response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -796,6 +1266,8 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: @@ -805,9 +1277,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:27 GMT + - Wed, 20 May 2026 18:37:07 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -815,7 +1289,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" @@ -829,7 +1303,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633086 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471993 method: DELETE response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -840,6 +1314,8 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: @@ -849,9 +1325,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:30 GMT + - Wed, 20 May 2026 18:37:10 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -859,7 +1337,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" @@ -873,7 +1351,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633086 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471993 method: DELETE response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -884,6 +1362,8 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: @@ -893,9 +1373,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:34 GMT + - Wed, 20 May 2026 18:37:13 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -903,7 +1385,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" @@ -917,7 +1399,55 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633086 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471993 + method: DELETE + response: + body: '{"errors": [{"reason": "Linode busy."}]}' + 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: + - "40" + Content-Type: + - application/json + Expires: + - Wed, 20 May 2026 18:37:17 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/97900566/disks/184471993 method: DELETE response: body: '{}' @@ -932,6 +1462,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: @@ -943,7 +1475,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:41 GMT + - Wed, 20 May 2026 18:37:20 GMT Pragma: - no-cache Strict-Transport-Security: @@ -960,7 +1492,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -976,7 +1508,55 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633090 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471998 + method: DELETE + response: + body: '{"errors": [{"reason": "Linode busy."}]}' + 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: + - "40" + Content-Type: + - application/json + Expires: + - Wed, 20 May 2026 18:37:20 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Frame-Options: + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1840" + 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/97900566/disks/184471998 method: DELETE response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -987,6 +1567,8 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: @@ -996,9 +1578,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:41 GMT + - Wed, 20 May 2026 18:37:23 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -1006,7 +1590,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" @@ -1020,7 +1604,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633090 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471998 method: DELETE response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -1031,6 +1615,8 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: @@ -1040,9 +1626,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:44 GMT + - Wed, 20 May 2026 18:37:26 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -1050,7 +1638,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" @@ -1064,7 +1652,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633090 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471998 method: DELETE response: body: '{"errors": [{"reason": "Linode busy."}]}' @@ -1075,6 +1663,8 @@ interactions: - HEAD, GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Origin: - '*' + Akamai-Internal-Account: + - '*' Cache-Control: - max-age=0, no-cache, no-store Connection: @@ -1084,9 +1674,11 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:49 GMT + - Wed, 20 May 2026 18:37:29 GMT Pragma: - no-cache + Strict-Transport-Security: + - max-age=31536000 X-Accepted-Oauth-Scopes: - linodes:read_write X-Frame-Options: @@ -1094,7 +1686,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" status: 400 Bad Request code: 400 duration: "" @@ -1108,7 +1700,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734/disks/105633090 + url: https://api.linode.com/v4beta/linode/instances/97900566/disks/184471998 method: DELETE response: body: '{}' @@ -1123,6 +1715,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: @@ -1134,7 +1728,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:08:59 GMT + - Wed, 20 May 2026 18:37:32 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1151,7 +1745,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1168,23 +1762,23 @@ interactions: User-Agent: - linodego/dev https://github.com/linode/linodego X-Filter: - - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":53282734,"entity.type":"linode"}' + - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":97900566,"entity.type":"linode"}' url: https://api.linode.com/v4beta/account/events?page=1 method: GET response: - body: '{"data": [{"id": 615701642, "created": "2018-01-02T03:04:05", "seen": false, - "read": false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": - 12.0, "action": "disk_delete", "username": "lgarber-dev", "entity": {"label": - "go-ins-poll-test", "id": 53282734, "type": "linode", "url": "/v4/linode/instances/53282734"}, - "status": "finished", "secondary_entity": {"id": 105633090, "type": "disk", - "label": "deleteEvent-1", "url": "/v4/linode/instances/53282734/disks/105633090"}, - "message": ""}, {"id": 615701539, "created": "2018-01-02T03:04:05", "seen": - false, "read": false, "percent_complete": 100, "time_remaining": 0, "rate": - null, "duration": 13.0, "action": "disk_delete", "username": "lgarber-dev", - "entity": {"label": "go-ins-poll-test", "id": 53282734, "type": "linode", "url": - "/v4/linode/instances/53282734"}, "status": "finished", "secondary_entity": - {"id": 105633086, "type": "disk", "label": "deleteEvent-0", "url": "/v4/linode/instances/53282734/disks/105633086"}, - "message": ""}], "page": 1, "pages": 1, "results": 2}' + body: '{"data": [{"id": 1586400154, "created": "2018-01-02T03:04:05", "seen": + false, "read": false, "percent_complete": 100, "time_remaining": null, "rate": + null, "duration": 7.0, "action": "disk_delete", "username": "zliang27", "entity": + {"label": "go-ins-poll-test", "id": 97900566, "type": "linode", "url": "/v4/linode/instances/97900566"}, + "status": "finished", "secondary_entity": {"id": 184471998, "type": "disk", + "label": "test-disk-1", "url": "/v4/linode/instances/97900566/disks/184471998"}, + "message": "", "details": {}}, {"id": 1586400079, "created": "2018-01-02T03:04:05", + "seen": false, "read": false, "percent_complete": 100, "time_remaining": null, + "rate": null, "duration": 11.0, "action": "disk_delete", "username": "zliang27", + "entity": {"label": "go-ins-poll-test", "id": 97900566, "type": "linode", "url": + "/v4/linode/instances/97900566"}, "status": "finished", "secondary_entity": + {"id": 184471993, "type": "disk", "label": "test-disk-0", "url": "/v4/linode/instances/97900566/disks/184471993"}, + "message": "", "details": {}}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -1196,6 +1790,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: @@ -1205,7 +1801,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:09:14 GMT + - Wed, 20 May 2026 18:37:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1224,7 +1820,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1240,16 +1836,16 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/account/events/615701539 + url: https://api.linode.com/v4beta/account/events/1586400079 method: GET response: - body: '{"id": 615701539, "created": "2018-01-02T03:04:05", "seen": false, "read": - false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": - 13.0, "action": "disk_delete", "username": "lgarber-dev", "entity": {"label": - "go-ins-poll-test", "id": 53282734, "type": "linode", "url": "/v4/linode/instances/53282734"}, - "status": "finished", "secondary_entity": {"id": 105633086, "type": "disk", - "label": "deleteEvent-0", "url": "/v4/linode/instances/53282734/disks/105633086"}, - "message": ""}' + body: '{"id": 1586400079, "created": "2018-01-02T03:04:05", "seen": false, "read": + false, "percent_complete": 100, "time_remaining": null, "rate": null, "duration": + 11.0, "action": "disk_delete", "username": "zliang27", "entity": {"label": "go-ins-poll-test", + "id": 97900566, "type": "linode", "url": "/v4/linode/instances/97900566"}, "status": + "finished", "secondary_entity": {"id": 184471993, "type": "disk", "label": "test-disk-0", + "url": "/v4/linode/instances/97900566/disks/184471993"}, "message": "", "details": + {}}' headers: Access-Control-Allow-Credentials: - "true" @@ -1261,18 +1857,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: - - "500" + - "514" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:09:14 GMT + - Wed, 20 May 2026 18:37:48 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1290,7 +1888,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1307,23 +1905,23 @@ interactions: User-Agent: - linodego/dev https://github.com/linode/linodego X-Filter: - - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":53282734,"entity.type":"linode"}' + - '{"+order":"desc","+order_by":"created","action":"disk_delete","entity.id":97900566,"entity.type":"linode"}' url: https://api.linode.com/v4beta/account/events?page=1 method: GET response: - body: '{"data": [{"id": 615701642, "created": "2018-01-02T03:04:05", "seen": false, - "read": false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": - 12.0, "action": "disk_delete", "username": "lgarber-dev", "entity": {"label": - "go-ins-poll-test", "id": 53282734, "type": "linode", "url": "/v4/linode/instances/53282734"}, - "status": "finished", "secondary_entity": {"id": 105633090, "type": "disk", - "label": "deleteEvent-1", "url": "/v4/linode/instances/53282734/disks/105633090"}, - "message": ""}, {"id": 615701539, "created": "2018-01-02T03:04:05", "seen": - false, "read": false, "percent_complete": 100, "time_remaining": 0, "rate": - null, "duration": 13.0, "action": "disk_delete", "username": "lgarber-dev", - "entity": {"label": "go-ins-poll-test", "id": 53282734, "type": "linode", "url": - "/v4/linode/instances/53282734"}, "status": "finished", "secondary_entity": - {"id": 105633086, "type": "disk", "label": "deleteEvent-0", "url": "/v4/linode/instances/53282734/disks/105633086"}, - "message": ""}], "page": 1, "pages": 1, "results": 2}' + body: '{"data": [{"id": 1586400154, "created": "2018-01-02T03:04:05", "seen": + false, "read": false, "percent_complete": 100, "time_remaining": null, "rate": + null, "duration": 7.0, "action": "disk_delete", "username": "zliang27", "entity": + {"label": "go-ins-poll-test", "id": 97900566, "type": "linode", "url": "/v4/linode/instances/97900566"}, + "status": "finished", "secondary_entity": {"id": 184471998, "type": "disk", + "label": "test-disk-1", "url": "/v4/linode/instances/97900566/disks/184471998"}, + "message": "", "details": {}}, {"id": 1586400079, "created": "2018-01-02T03:04:05", + "seen": false, "read": false, "percent_complete": 100, "time_remaining": null, + "rate": null, "duration": 11.0, "action": "disk_delete", "username": "zliang27", + "entity": {"label": "go-ins-poll-test", "id": 97900566, "type": "linode", "url": + "/v4/linode/instances/97900566"}, "status": "finished", "secondary_entity": + {"id": 184471993, "type": "disk", "label": "test-disk-0", "url": "/v4/linode/instances/97900566/disks/184471993"}, + "message": "", "details": {}}], "page": 1, "pages": 1, "results": 2}' headers: Access-Control-Allow-Credentials: - "true" @@ -1335,6 +1933,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: @@ -1344,7 +1944,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:09:29 GMT + - Wed, 20 May 2026 18:38:03 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1363,7 +1963,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1379,16 +1979,16 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/account/events/615701642 + url: https://api.linode.com/v4beta/account/events/1586400154 method: GET response: - body: '{"id": 615701642, "created": "2018-01-02T03:04:05", "seen": false, "read": - false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": - 12.0, "action": "disk_delete", "username": "lgarber-dev", "entity": {"label": - "go-ins-poll-test", "id": 53282734, "type": "linode", "url": "/v4/linode/instances/53282734"}, - "status": "finished", "secondary_entity": {"id": 105633090, "type": "disk", - "label": "deleteEvent-1", "url": "/v4/linode/instances/53282734/disks/105633090"}, - "message": ""}' + body: '{"id": 1586400154, "created": "2018-01-02T03:04:05", "seen": false, "read": + false, "percent_complete": 100, "time_remaining": null, "rate": null, "duration": + 7.0, "action": "disk_delete", "username": "zliang27", "entity": {"label": "go-ins-poll-test", + "id": 97900566, "type": "linode", "url": "/v4/linode/instances/97900566"}, "status": + "finished", "secondary_entity": {"id": 184471998, "type": "disk", "label": "test-disk-1", + "url": "/v4/linode/instances/97900566/disks/184471998"}, "message": "", "details": + {}}' headers: Access-Control-Allow-Credentials: - "true" @@ -1400,18 +2000,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: - - "500" + - "513" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:09:29 GMT + - Wed, 20 May 2026 18:38:03 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1429,7 +2031,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -1445,7 +2047,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/53282734 + url: https://api.linode.com/v4beta/linode/instances/97900566 method: DELETE response: body: '{}' @@ -1460,6 +2062,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: @@ -1471,7 +2075,7 @@ interactions: Content-Type: - application/json Expires: - - Wed, 20 Dec 2023 22:09:29 GMT + - Wed, 20 May 2026 18:38:03 GMT Pragma: - no-cache Strict-Transport-Security: @@ -1488,7 +2092,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "400" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestVLANs_List.yaml b/test/integration/fixtures/TestVLANs_List.yaml index bfd9d497f..dce16b562 100644 --- a/test/integration/fixtures/TestVLANs_List.yaml +++ b/test/integration/fixtures/TestVLANs_List.yaml @@ -14,294 +14,449 @@ interactions: url: https://api.linode.com/v4beta/regions?page=1 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": - {"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": - null, "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "fr-par", "label": - "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Backups", "NodeBalancers", + body: '{"data": [{"id": "au-mel", "label": "Melbourne, AU", "country": "au", "capabilities": + ["Linodes", "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", + "Backups", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-lax", + "label": "Los Angeles, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nz-akl-1", + "label": "Auckland, NZ", "country": "nz", "capabilities": ["Linodes", "Disk + Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance + Policy"], "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": + {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-den-1", "label": "Denver, CO", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "de-ham-1", "label": "Hamburg, DE", "country": "de", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "za-jnb-1", "label": "Johannesburg, ZA", "country": "za", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "my-kul-1", "label": "Kuala Lumpur, MY", "country": "my", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "co-bog-1", "label": "Bogot\u00e1, CO", "country": "co", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "mx-qro-1", "label": "Quer\u00e9taro, MX", "country": "mx", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-hou-1", "label": "Houston, TX", "country": "us", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "cl-scl-1", "label": "Santiago, CL", "country": "cl", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "gb-lon", "label": "London 2, UK", "country": "gb", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter + LKE-E"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": + ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "id-cgk", + "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-bom-2", + "label": "Mumbai 2, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-fra-2", + "label": "Frankfurt 2, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "sg-sin-2", + "label": "Singapore 2, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-tyo-3", + "label": "Tokyo 3, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "de-ber-1", + "label": "Berlin, DE", "country": "de", "capabilities": ["Linodes", "Disk Encryption", + "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", "Maintenance Policy"], + "monitors": {"alerts": [], "metrics": []}, "status": "ok", "resolvers": {"ipv4": + "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "no-osl-1", "label": "Oslo, NO", "country": "no", "capabilities": ["Linodes", + "Block Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block + Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", + "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.238.140.33,172.238.140.25,172.238.140.30,172.238.140.31,172.238.140.26,172.238.140.28,172.238.140.34,172.238.140.32,172.238.140.27,172.238.140.29", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad-2", + "label": "Washington 2, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed + Databases", "NodeBalancers"]}, "status": "ok", "resolvers": {"ipv4": "172.239.142.102,172.239.142.89,172.239.142.92,172.239.142.87,172.239.142.88,172.239.142.103,172.239.142.91,172.239.142.90,172.239.142.86,172.239.142.100", + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par-2", + "label": "Paris 2, FR", "country": "fr", "capabilities": ["Linodes", "Block + Storage Encryption", "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", + "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", + "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", "Premium Plans", + "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces", + "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "172.239.11.24,172.239.11.22,172.239.11.17,172.239.11.20,172.239.11.23,172.239.11.19,172.239.11.21,172.239.11.15,172.239.11.16,172.239.11.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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-rno-1", + "label": "Reno, NV", "country": "us", "capabilities": ["Linodes", "Disk Encryption", + "Backups", "NodeBalancers", "GPU Linodes", "Cloud Firewall", "Metadata", "Premium + Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], + "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, "status": + "ok", "resolvers": {"ipv4": "", "ipv6": ""}, "placement_group_limits": {"maximum_pgs_per_customer": + null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": + "core"}, {"id": "co-bog-2", "label": "Bogot\u00e1 2, CO", "country": "co", "capabilities": + ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed + Plans", "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "fr-mrs-2", "label": "Marseille 2, FR", "country": "fr", "capabilities": ["Linodes", + "Disk Encryption", "Cloud Firewall", "Vlans", "Metadata", "Distributed Plans", + "Maintenance Policy"], "monitors": {"alerts": [], "metrics": []}, "status": + "ok", "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, + "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": + 0, "maximum_linodes_per_flexible_pg": 0}, "site_type": "distributed"}, {"id": + "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", + "Block Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", + "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", + "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", + "Managed Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", + "NETINT Quadra T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-west", + "label": "Mumbai, IN", "country": "in", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ca-central", + "label": "Toronto, CA", "country": "ca", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-southeast", + "label": "Sydney, AU", "country": "au", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-iad", + "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Linodes", "Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-ord", + "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "fr-par", + "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-sea", + "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces", "ACLP Logs Datacenter LKE-E"], "monitors": {"alerts": + ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "br-gru", + "label": "Sao Paulo, BR", "country": "br", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Kubernetes Enterprise", "Cloud + Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", "Metadata", + "Premium Plans", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["Managed Databases", "NodeBalancers"], + "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "se-sto", + "label": "Stockholm, SE", "country": "se", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "es-mad", + "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "in-maa", + "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "NETINT Quadra + T1U", "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed + Databases", "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, + "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "it-mil", + "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Kubernetes + Enterprise", "Cloud Firewall", "Vlans", "VPCs", "VPC Dual Stack", "Managed Databases", + "Metadata", "Premium Plans", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-northeast", + "label": "Tokyo 2, JP", "country": "jp", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk 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": "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-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", - "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"}, - "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"}, - "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"}, - "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", - "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": - {"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, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "us-southeast", "label": - "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Metadata", "Placement Group", "StackScripts", + "Maintenance Policy", "Linode Interfaces"], "monitors": {"alerts": ["NodeBalancers"], + "metrics": ["NodeBalancers"]}, "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "eu-west", + "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Metadata", "Placement Group", "StackScripts", "Maintenance Policy", "Linode + Interfaces"], "monitors": {"alerts": ["NodeBalancers"], "metrics": ["NodeBalancers"]}, + "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": null, "maximum_linodes_per_pg": + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-east", + "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Block Storage + Encryption", "LA Disk Encryption", "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": "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-east", "label": - "Newark, NJ", "country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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,173.255.225.5,66.228.35.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, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-southeast", + "label": "Atlanta, GA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "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": "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"}, + Group", "StackScripts", "Maintenance Policy", "Linode Interfaces"], "monitors": + {"alerts": ["Managed Databases", "NodeBalancers"], "metrics": ["Managed Databases", + "NodeBalancers"]}, "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, "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": - 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": - 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", + 5, "maximum_linodes_per_flexible_pg": 5}, "site_type": "core"}, {"id": "us-west", + "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "Block + Storage Encryption", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases", "Metadata", "Placement Group", "StackScripts", "Maintenance + Policy", "Linode Interfaces"], "monitors": {"alerts": ["Managed Databases", + "NodeBalancers"], "metrics": ["Managed Databases", "NodeBalancers"]}, "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, "maximum_linodes_per_pg": 5}, "site_type": - "core"}], "page": 1, "pages": 1, "results": 34}' + {"maximum_pgs_per_customer": null, "maximum_linodes_per_pg": 5, "maximum_linodes_per_flexible_pg": + 5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 47}' headers: Access-Control-Allow-Credentials: - "true" @@ -324,7 +479,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:27:33 GMT + - Wed, 20 May 2026 18:38:55 GMT Pragma: - no-cache Strict-Transport-Security: @@ -341,19 +496,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-ins-test-list-0","root_pass":"lO21L5-u2H`i)''*2~$-AXyC!q89)^EN\u003em;ey~6vy\u003eIt9TiRs-5eG460In5R3qD4Y","image":"linode/debian9","interfaces":[{"ipam_address":"10.0.0.1/24","label":"go-vlan-test-list","purpose":"vlan"}],"firewall_id":693021,"booted":true}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-ins-test-list-0","root_pass":"p57\u00260:IQ|pP''RL*eV@+E2YwPm1aN|dJm(z16y#\\w:7dQ1M$''31pa5431K@Ac6w/W","image":"linode/debian12","firewall_id":21736190,"booted":true,"interfaces":[{"ipam_address":"10.0.0.1/24","label":"go-vlan-test-list","purpose":"vlan"}]}' form: {} headers: Accept: @@ -365,16 +517,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61875475, "label": "go-ins-test-list-0", "group": "", "status": + body: '{"id": 97900609, "label": "go-ins-test-list-0", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.1.65"], "ipv6": "1234::5678/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": 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}' + "type": "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -392,20 +547,19 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "803" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:27:34 GMT + - Wed, 20 May 2026 18:38:57 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: @@ -414,19 +568,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: - - "10" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-ins-test-list-1","root_pass":"RT.M80/4r8=599k5q00IA\\j9''Vp[OqV5U};9NvhKbn=F+i7\u0026.ljr@|LuV0X,rF{8","image":"linode/debian9","interfaces":[{"ipam_address":"10.0.0.1/24","label":"go-vlan-test-list","purpose":"vlan"}],"firewall_id":693021,"booted":true}' + body: '{"region":"au-mel","type":"g6-nanode-1","label":"go-ins-test-list-1","root_pass":"Y5Tmw]P`q26n8:2O`xBzH(#*0#1176\\5dz\\-E8xJtJo7Baq[OAZ;W^,3uv3J3iU:","image":"linode/debian12","firewall_id":21736190,"booted":true,"interfaces":[{"ipam_address":"10.0.0.1/24","label":"go-vlan-test-list","purpose":"vlan"}]}' form: {} headers: Accept: @@ -438,16 +589,19 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 61875477, "label": "go-ins-test-list-1", "group": "", "status": + body: '{"id": 97900611, "label": "go-ins-test-list-1", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.1.131"], "ipv6": "1234::5678/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": true, "available": false, "schedule": {"day": - null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": - true, "tags": [], "host_uuid": "8aca7a754c37f5b4e94afd4a43d57ad2c7090730", "has_user_data": - false, "placement_group": null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["172.236.51.198"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "5387d9832343076b3dd8123772c585acfed1b8ec", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -465,20 +619,19 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "804" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:27:35 GMT + - Wed, 20 May 2026 18:38:59 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: @@ -487,12 +640,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: - - "10" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -508,19 +658,168 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875475 + url: https://api.linode.com/v4beta/linode/instances/97900609 method: GET response: - body: '{"id": 61875475, "label": "go-ins-test-list-0", "group": "", "status": + body: '{"id": 97900609, "label": "go-ins-test-list-0", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.1.65"], "ipv6": "1234::5678/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": true, "available": false, "schedule": {"day": - "Scheduling", "window": "Scheduling"}, "last_successful": null}, "hypervisor": - "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": "0be889ff8efab8e9f1cbbb28b1799aa440e95149", - "has_user_data": false, "placement_group": null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' + 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, 20 May 2026 18:39:14 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: + - "1840" + 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/97900609 + method: GET + response: + body: '{"id": 97900609, "label": "go-ins-test-list-0", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' + 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, 20 May 2026 18:39:29 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: + - "1840" + 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/97900609 + method: GET + response: + body: '{"id": 97900609, "label": "go-ins-test-list-0", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -538,14 +837,12 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "819" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:27:50 GMT + - Wed, 20 May 2026 18:39:44 GMT Pragma: - no-cache Strict-Transport-Security: @@ -553,6 +850,7 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - linodes:read_only X-Content-Type-Options: @@ -561,12 +859,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -582,19 +877,22 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875475 + url: https://api.linode.com/v4beta/linode/instances/97900609 method: GET response: - body: '{"id": 61875475, "label": "go-ins-test-list-0", "group": "", "status": + body: '{"id": 97900609, "label": "go-ins-test-list-0", "group": "", "status": "booting", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.1.65"], "ipv6": "1234::5678/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": true, "available": false, "schedule": {"day": - "Scheduling", "window": "Scheduling"}, "last_successful": null}, "hypervisor": - "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": "0be889ff8efab8e9f1cbbb28b1799aa440e95149", - "has_user_data": false, "placement_group": null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -612,14 +910,12 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "814" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:28:05 GMT + - Wed, 20 May 2026 18:39:59 GMT Pragma: - no-cache Strict-Transport-Security: @@ -627,6 +923,7 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - linodes:read_only X-Content-Type-Options: @@ -635,12 +932,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -656,19 +950,22 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875475 + url: https://api.linode.com/v4beta/linode/instances/97900609 method: GET response: - body: '{"id": 61875475, "label": "go-ins-test-list-0", "group": "", "status": + body: '{"id": 97900609, "label": "go-ins-test-list-0", "group": "", "status": "running", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.1.65"], "ipv6": "1234::5678/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": true, "available": false, "schedule": {"day": - "Scheduling", "window": "Scheduling"}, "last_successful": null}, "hypervisor": - "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": "0be889ff8efab8e9f1cbbb28b1799aa440e95149", - "has_user_data": false, "placement_group": null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["172.236.51.176"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "288e63c85b047d1cb41106d47e6898933356966a", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -686,14 +983,12 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "814" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:28:20 GMT + - Wed, 20 May 2026 18:40:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -701,6 +996,7 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - linodes:read_only X-Content-Type-Options: @@ -709,12 +1005,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -730,19 +1023,22 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875477 + url: https://api.linode.com/v4beta/linode/instances/97900611 method: GET response: - body: '{"id": 61875477, "label": "go-ins-test-list-1", "group": "", "status": + body: '{"id": 97900611, "label": "go-ins-test-list-1", "group": "", "status": "running", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.1.131"], "ipv6": "1234::5678/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": true, "available": false, "schedule": {"day": - "Scheduling", "window": "Scheduling"}, "last_successful": null}, "hypervisor": - "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": "8aca7a754c37f5b4e94afd4a43d57ad2c7090730", - "has_user_data": false, "placement_group": null, "lke_cluster_id": null}' + "type": "g6-nanode-1", "ipv4": ["172.236.51.198"], "ipv6": "1234::5678/128", + "image": "linode/debian12", "region": "au-mel", "site_type": "core", "specs": + {"disk": 25600, "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, "system_alerts": [], "user_alerts": []}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "5387d9832343076b3dd8123772c585acfed1b8ec", "has_user_data": false, "placement_group": + null, "disk_encryption": "enabled", "lke_cluster_id": null, "capabilities": + ["Block Storage Encryption", "SMTP Enabled", "Maintenance Policy"], "interface_generation": + "legacy_config", "maintenance_policy": "linode/migrate", "locks": []}' headers: Access-Control-Allow-Credentials: - "true" @@ -760,14 +1056,12 @@ interactions: - max-age=0, no-cache, no-store Connection: - keep-alive - Content-Length: - - "815" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:28:35 GMT + - Wed, 20 May 2026 18:40:29 GMT Pragma: - no-cache Strict-Transport-Security: @@ -775,6 +1069,7 @@ interactions: Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - linodes:read_only X-Content-Type-Options: @@ -783,12 +1078,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -809,8 +1101,8 @@ interactions: url: https://api.linode.com/v4beta/networking/vlans?page=1 method: GET response: - body: '{"data": [{"region": "ap-west", "label": "go-vlan-test-list", "linodes": - [61875475, 61875477], "created": "2018-01-02T03:04:05"}], "page": 1, "pages": + body: '{"data": [{"region": "au-mel", "label": "go-vlan-test-list", "linodes": + [97900609, 97900611], "created": "2018-01-02T03:04:05"}], "page": 1, "pages": 1, "results": 1}' headers: Access-Control-Allow-Credentials: @@ -830,13 +1122,13 @@ interactions: Connection: - keep-alive Content-Length: - - "167" + - "166" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:28:35 GMT + - Wed, 20 May 2026 18:40:29 GMT Pragma: - no-cache Strict-Transport-Security: @@ -852,12 +1144,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -873,7 +1162,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875477 + url: https://api.linode.com/v4beta/linode/instances/97900611 method: DELETE response: body: '{}' @@ -901,7 +1190,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:28:35 GMT + - Wed, 20 May 2026 18:40:30 GMT Pragma: - no-cache Strict-Transport-Security: @@ -916,12 +1205,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -937,7 +1223,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/61875475 + url: https://api.linode.com/v4beta/linode/instances/97900609 method: DELETE response: body: '{}' @@ -965,7 +1251,7 @@ interactions: Content-Type: - application/json Expires: - - Thu, 25 Jul 2024 18:28:36 GMT + - Wed, 20 May 2026 18:40:30 GMT Pragma: - no-cache Strict-Transport-Security: @@ -980,12 +1266,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" + - "1840" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/vlans_test.go b/test/integration/vlans_test.go index 22c3e1b16..c1a057818 100644 --- a/test/integration/vlans_test.go +++ b/test/integration/vlans_test.go @@ -19,7 +19,7 @@ func TestVLANs_List_smoke(t *testing.T) { client, fixturesTeardown := createTestClient(t, "fixtures/TestVLANs_List") defer fixturesTeardown() - var instances []*linodego.Instance + var instances []linodego.Instance for i := 0; i < 2; i++ { instance, instanceTeardown, err := createVLANInstance(t, client, fmt.Sprintf("%s-%d", instancePrefix, i), vlanName) if err != nil { @@ -27,7 +27,7 @@ func TestVLANs_List_smoke(t *testing.T) { } defer instanceTeardown() - instances = append(instances, instance) + instances = append(instances, *instance) } for _, instance := range instances { diff --git a/test/integration/waitfor_test.go b/test/integration/waitfor_test.go index 31d2fa82f..9674690a3 100644 --- a/test/integration/waitfor_test.go +++ b/test/integration/waitfor_test.go @@ -177,7 +177,7 @@ func TestEventPoller_Secondary(t *testing.T) { } // Create two instance disks - disks := make([]*linodego.InstanceDisk, 2) + disks := make([]linodego.InstanceDisk, 2) for i := 0; i < 2; i++ { disk, err := client.CreateInstanceDisk(context.Background(), instance.ID, linodego.InstanceDiskCreateOptions{ @@ -188,7 +188,7 @@ func TestEventPoller_Secondary(t *testing.T) { t.Fatalf("failed to create instance disk: %s", err) } - disks[i] = disk + disks[i] = *disk } // Poll for the first disk to be deleted diff --git a/test/unit/nodebalancers_test.go b/test/unit/nodebalancers_test.go index b4e7cd273..ed69b96e5 100644 --- a/test/unit/nodebalancers_test.go +++ b/test/unit/nodebalancers_test.go @@ -24,7 +24,7 @@ func TestNodeBalancers_UDP(t *testing.T) { Label: linodego.Pointer("foobar"), Region: "us-mia", ClientUDPSessThrottle: linodego.Pointer(5), - Configs: []*linodego.NodeBalancerConfigCreateOptions{ + Configs: []linodego.NodeBalancerConfigCreateOptions{ { Protocol: linodego.ProtocolUDP, Port: 1234, From 2cc01877599e80fe5b22f58bcf41b7a8306fa03d Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Wed, 27 May 2026 14:09:48 -0400 Subject: [PATCH 14/17] Remove LKE cluster dashboard function, tests, and related fixture (#975) --- lke_clusters.go | 11 - .../TestLKECluster_Dashboard_Get.yaml | 688 ------------------ test/integration/lke_clusters_test.go | 27 - test/unit/fixtures/lke_cluster_dashboard.json | 4 - test/unit/lke_clusters_test.go | 15 - 5 files changed, 745 deletions(-) delete mode 100644 test/integration/fixtures/TestLKECluster_Dashboard_Get.yaml delete mode 100644 test/unit/fixtures/lke_cluster_dashboard.json diff --git a/lke_clusters.go b/lke_clusters.go index 0fadf2f70..bb00dbc09 100644 --- a/lke_clusters.go +++ b/lke_clusters.go @@ -88,11 +88,6 @@ type LKEClusterKubeconfig struct { KubeConfig string `json:"kubeconfig"` // Base64-encoded Kubeconfig file for this Cluster. } -// LKEClusterDashboard fields are those returned by GetLKEClusterDashboard -type LKEClusterDashboard struct { - URL string `json:"url"` -} - // LKEVersion fields are those returned by GetLKEVersion type LKEVersion struct { ID string `json:"id"` @@ -276,12 +271,6 @@ func (c *Client) DeleteLKEClusterKubeconfig(ctx context.Context, clusterID int) return doDELETERequest(ctx, c, e) } -// GetLKEClusterDashboard gets information about the dashboard for an LKE cluster -func (c *Client) GetLKEClusterDashboard(ctx context.Context, clusterID int) (*LKEClusterDashboard, error) { - e := formatAPIPath("lke/clusters/%d/dashboard", clusterID) - return doGETRequest[LKEClusterDashboard](ctx, c, e) -} - // RecycleLKEClusterNodes recycles all nodes in all pools of the specified LKE Cluster. func (c *Client) RecycleLKEClusterNodes(ctx context.Context, clusterID int) error { e := formatAPIPath("lke/clusters/%d/recycle", clusterID) diff --git a/test/integration/fixtures/TestLKECluster_Dashboard_Get.yaml b/test/integration/fixtures/TestLKECluster_Dashboard_Get.yaml deleted file mode 100644 index 9fddde6ff..000000000 --- a/test/integration/fixtures/TestLKECluster_Dashboard_Get.yaml +++ /dev/null @@ -1,688 +0,0 @@ ---- -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", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-ord", "label": "Chicago, IL", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "fr-par", "label": "Paris, FR", "country": - "fr", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-sea", "label": "Seattle, WA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "se-sto", "label": "Stockholm, SE", "country": - "se", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "es-mad", "label": "Madrid, ES", "country": - "es", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-maa", "label": "Chennai, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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": "nz-akl-1", "label": "Auckland, NZ", "country": - "nz", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-den-1", "label": "Denver, CO", "country": - "us", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "de-ham-1", "label": "Hamburg, DE", - "country": "de", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "fr-mrs-1", "label": "Marseille, FR", - "country": "fr", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "za-jnb-1", "label": "Johannesburg, - ZA", "country": "za", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "my-kul-1", "label": "Kuala Lumpur, - MY", "country": "my", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "co-bog-1", "label": "Bogot\u00e1, CO", - "country": "co", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "mx-qro-1", "label": "Quer\u00e9taro, - MX", "country": "mx", "capabilities": ["Linodes", "Disk Encryption", "Cloud - Firewall", "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", - "resolvers": {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-hou-1", "label": "Houston, TX", - "country": "us", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "cl-scl-1", "label": "Santiago, CL", - "country": "cl", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", - "Vlans", "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": - {"ipv4": "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "gb-lon", "label": "London 2, UK", "country": - "gb", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "au-mel", "label": "Melbourne, AU", "country": - "au", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", "VPCs", "Managed - Databases", "Metadata", "Premium Plans", "Placement Group", "StackScripts", - "NETINT Quadra T1U", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "in-bom-2", "label": "Mumbai 2, IN", "country": - "in", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", - "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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": "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": "de-fra-2", "label": "Frankfurt 2, DE", "country": - "de", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "GPU Linodes", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "NETINT Quadra T1U", "Linode Interfaces"], - "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": "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": "sg-sin-2", "label": "Singapore 2, SG", "country": - "sg", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Kubernetes Enterprise", "Cloud Firewall", "Vlans", - "VPCs", "Managed Databases", "Metadata", "Premium Plans", "Placement Group", - "StackScripts", "Linode Interfaces"], "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": "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-tyo-3", "label": "Tokyo 3, JP", "country": - "jp", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans", - "Placement Group", "StackScripts", "Linode Interfaces"], "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": "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": "de-ber-1", "label": "Berlin, DE", "country": - "de", "capabilities": ["Linodes", "Disk Encryption", "Cloud Firewall", "Vlans", - "VPCs", "Metadata", "Distributed Plans"], "status": "ok", "resolvers": {"ipv4": - "173.223.100.53,173.223.101.53", "ipv6": "1234::5678,1234::5678"}, - "placement_group_limits": {"maximum_pgs_per_customer": 0, "maximum_linodes_per_pg": - 0}, "site_type": "distributed"}, {"id": "us-central", "label": "Dallas, TX", - "country": "us", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", - "Backups", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group", "StackScripts", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA", "country": - "us", "capabilities": ["Linodes", "Block Storage Encryption", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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, "maximum_linodes_per_pg": 5}, "site_type": - "core"}, {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": - ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", "NodeBalancers", - "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", - "Vlans", "Block Storage Migrations", "Managed Databases", "Metadata", "Placement - Group", "StackScripts", "Linode Interfaces"], "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, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ", "country": - "us", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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,173.255.225.5,66.228.35.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": "eu-west", "label": "London, UK", "country": - "gb", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Metadata", "Placement Group", "StackScripts", "Linode - Interfaces"], "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": null, - "maximum_linodes_per_pg": 5}, "site_type": "core"}, {"id": "ap-south", "label": - "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "LA Disk Encryption", - "Disk Encryption", "Backups", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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": null, "maximum_linodes_per_pg": - 5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country": - "de", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", - "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases", - "Metadata", "Placement Group", "StackScripts", "Linode Interfaces"], "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 2, JP", "country": - "jp", "capabilities": ["Linodes", "LA Disk Encryption", "Disk Encryption", "Backups", - "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases", "Metadata", "Placement Group", "StackScripts", - "Linode Interfaces"], "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": 42}' - 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, 12 May 2025 19:09:38 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: - - "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/lke/tiers/standard/versions?page=1 - method: GET - response: - body: '{"data": [{"id": "1.32", "tier": "standard"}, {"id": "1.31", "tier": "standard"}], - "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: - - "119" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Mon, 12 May 2025 19:09:39 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - lke:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"node_pools":[{"count":1,"type":"g6-standard-2","disks":null,"tags":["test"],"labels":null,"taints":null}],"label":"go-lke-test-dash","region":"ap-west","k8s_version":"1.32","tags":["testing"],"tier":"standard"}' - 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/clusters - method: POST - response: - body: '{"id": 433124, "status": "ready", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "label": "go-lke-test-dash", "region": "ap-west", "k8s_version": - "1.32", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": - false, "tags": ["testing"]}' - 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: - - "284" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Mon, 12 May 2025 19:09:49 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - lke:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/lke/clusters/433124 - method: GET - response: - body: '{"id": 433124, "status": "ready", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "label": "go-lke-test-dash", "region": "ap-west", "k8s_version": - "1.32", "tier": "standard", "control_plane": {"high_availability": false}, "apl_enabled": - false, "tags": ["testing"]}' - 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: - - "284" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Mon, 12 May 2025 19:10:04 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - lke:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/lke/clusters/433124/dashboard - method: GET - response: - body: '{"url": "https://76e279ae-78ec-4fbe-ad46-88c595b2e237.ap-west-1-gw.linodelke.net"}' - 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: - - "82" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Mon, 12 May 2025 19:10:05 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - lke:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - 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/lke/clusters/433124 - 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, 12 May 2025 19:10:10 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - lke:read_write - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "1600" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" diff --git a/test/integration/lke_clusters_test.go b/test/integration/lke_clusters_test.go index 7ad30eb55..8580e1aaf 100644 --- a/test/integration/lke_clusters_test.go +++ b/test/integration/lke_clusters_test.go @@ -3,7 +3,6 @@ package integration import ( "context" "fmt" - "net/url" "reflect" "testing" "time" @@ -253,32 +252,6 @@ func TestLKECluster_Kubeconfig_Delete(t *testing.T) { } } -func TestLKECluster_Dashboard_Get(t *testing.T) { - ctx := waitContext(t, 180*time.Second) - - client, lkeCluster, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { - createOpts.Label = "go-lke-test-dash" - }}, "fixtures/TestLKECluster_Dashboard_Get") - defer teardown() - - _, err = client.WaitForLKEClusterStatus(ctx, lkeCluster.ID, linodego.LKEClusterReady) - if err != nil { - t.Errorf("Error waiting for LKECluster readiness: %s", err) - } - i, err := client.GetLKEClusterDashboard(context.Background(), lkeCluster.ID) - if err != nil { - t.Errorf("Error getting LKE cluster dashboard URL, expected struct, got %v and error %v", i, err) - } - - if len(i.URL) == 0 { - t.Errorf("Expected an LKE cluster dashboard URL, but got empty string %v", i) - } - - if _, err := url.ParseRequestURI(i.URL); err != nil { - t.Errorf("invalid url: %s", err) - } -} - func TestLKEClusters_List(t *testing.T) { client, _, teardown, err := setupLKECluster(t, []clusterModifier{func(createOpts *linodego.LKEClusterCreateOptions) { createOpts.Label = "go-lke-test-list" diff --git a/test/unit/fixtures/lke_cluster_dashboard.json b/test/unit/fixtures/lke_cluster_dashboard.json deleted file mode 100644 index 7a5ed5e42..000000000 --- a/test/unit/fixtures/lke_cluster_dashboard.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "url": "https://dashboard.example.com" -} - \ No newline at end of file diff --git a/test/unit/lke_clusters_test.go b/test/unit/lke_clusters_test.go index 0a1a3fd21..3199efb7b 100644 --- a/test/unit/lke_clusters_test.go +++ b/test/unit/lke_clusters_test.go @@ -182,21 +182,6 @@ func TestLKECluster_DeleteKubeconfig(t *testing.T) { assert.NoError(t, err) } -func TestLKECluster_GetDashboard(t *testing.T) { - fixtureData, err := fixtures.GetFixture("lke_cluster_dashboard") - assert.NoError(t, err) - - var base ClientBaseCase - base.SetUp(t) - defer base.TearDown(t) - - base.MockGet("lke/clusters/123/dashboard", fixtureData) - - dashboard, err := base.Client.GetLKEClusterDashboard(context.Background(), 123) - assert.NoError(t, err) - assert.Equal(t, "https://dashboard.example.com", dashboard.URL) -} - func TestLKECluster_GetAPLConsoleURL(t *testing.T) { fixtureData, err := fixtures.GetFixture("lke_cluster_apl") assert.NoError(t, err) From 2e3feb3ad34f95cf16e35d52aaf32ad55d973d68 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Wed, 27 May 2026 14:16:52 -0400 Subject: [PATCH 15/17] Simplify client.go (#976) Signed-off-by: Zhiwei Liang --- client.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/client.go b/client.go index bb94093e3..02d27ef1e 100644 --- a/client.go +++ b/client.go @@ -212,7 +212,6 @@ func NewClient(hc *http.Client) (client Client, err error) { SetRetryWaitTime(APISecondsPerPoll * time.Second). SetPollDelay(APISecondsPerPoll * time.Second). SetRetries(). - SetLogger(createLogger()). SetDebug(envDebug). enableLogSanitization() @@ -516,13 +515,7 @@ func (c *Client) doRequest(ctx context.Context, method, endpoint string, params ) for range c.retryCount { - // Reset the body to the start for each retry if it's not nil - if params.Body != nil { - if _, seekErr := params.Body.Seek(0, io.SeekStart); seekErr != nil { - return c.ErrorAndLogf("failed to seek to the start of the body: %v", seekErr.Error()) - } - } - + // createRequest seeks params.Body back to the start, so it's safe to retry. req, err = c.createRequest(ctx, method, endpoint, params) if err != nil { return err @@ -784,9 +777,7 @@ func formatBody(body string) (string, error) { } var jsonData any - - err := json.Unmarshal([]byte(body), &jsonData) - if err != nil { + if err := json.Unmarshal([]byte(body), &jsonData); err != nil { return "", fmt.Errorf("error unmarshalling JSON: %w", err) } From c8a9cf55759fbd2e2623677db3b11b82af725b9f Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Wed, 27 May 2026 14:25:12 -0400 Subject: [PATCH 16/17] Apply suggestion from @zliang-akamai --- instance_disks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instance_disks.go b/instance_disks.go index 380c2c652..52d3538d1 100644 --- a/instance_disks.go +++ b/instance_disks.go @@ -47,7 +47,7 @@ type InstanceDiskCreateOptions struct { Label string `json:"label"` Size int `json:"size"` - // Image is optional, but requires RootPass if provided + // Image is optional, but requires at least one of RootPass, AuthorizedUsers, or AuthorizedKeys if provided Image string `json:"image,omitzero"` RootPass string `json:"root_pass,omitzero"` From f6388b03b2aac972081d6e6bb02ebe00619b6b1e Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Wed, 27 May 2026 14:31:58 -0400 Subject: [PATCH 17/17] Update region capability in TestImageSharing_Suite to use Linodes --- test/integration/image_sharegroups_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/image_sharegroups_test.go b/test/integration/image_sharegroups_test.go index 349ba7e60..850ac4c49 100644 --- a/test/integration/image_sharegroups_test.go +++ b/test/integration/image_sharegroups_test.go @@ -17,7 +17,7 @@ func TestImageSharing_Suite(t *testing.T) { client, instance, teardown, err := setupInstance( t, "fixtures/TestImageSharing_Suite", true, func(client *linodego.Client, options *linodego.InstanceCreateOptions) { - options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityDBAAS})[0] + options.Region = getRegionsWithCaps(t, client, []linodego.RegionCapability{linodego.CapabilityLinodes})[0] options.Image = "linode/alpine3.22" }) if err != nil {