From 21a812012630be937bf172291ef714fc306a2cf3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Mar 2025 01:20:23 +0000 Subject: [PATCH 01/18] build(deps): bump docker/setup-qemu-action from 3.3.0 to 3.6.0 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.3.0 to 3.6.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/53851d14592bedcffcf25ea515637cff71ef929a...29109295f81e9208d7d86ff1c6c12d2833863392) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d24ab9e8b..113aad4a6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,7 +39,7 @@ jobs: run: make requirements - name: Set up QEMU - uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # pin@v3.3.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # pin@v3.6.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # pin@v3.8.0 From 952d844653bd76d6ab167cf713e3790d373a2fd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Mar 2025 01:20:25 +0000 Subject: [PATCH 02/18] build(deps): bump docker/setup-buildx-action from 3.8.0 to 3.10.0 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.8.0 to 3.10.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/6524bf65af31da8d45b59e8c27de4bd072b392f5...b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d24ab9e8b..b697fe611 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # pin@v3.3.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # pin@v3.8.0 + uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # pin@v3.10.0 - name: Login to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # pin@v3.3.0 From 7d7ddcf507b2f917a3f348e4fc74a74a64166b04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 11:25:35 -0500 Subject: [PATCH 03/18] build(deps): bump crazy-max/ghaction-github-labeler from 5.1.0 to 5.2.0 (#742) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 444c69ffd..8a9bcadd2 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v4 - name: Run Labeler - uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c + uses: crazy-max/ghaction-github-labeler@31674a3852a9074f2086abcf1c53839d466a47e7 with: github-token: ${{ secrets.GITHUB_TOKEN }} yaml-file: .github/labels.yml From 3587441f3d14cb4c9d303005e6d39896a43841c6 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 3 Mar 2025 14:51:23 -0500 Subject: [PATCH 04/18] SSH login by domain (#723) --- linodecli/plugins/ssh.py | 8 ++++++++ tests/unit/test_plugin_ssh.py | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/linodecli/plugins/ssh.py b/linodecli/plugins/ssh.py index 2ed53cbdb..c644f7993 100644 --- a/linodecli/plugins/ssh.py +++ b/linodecli/plugins/ssh.py @@ -50,6 +50,11 @@ def call(args, context): # pylint: disable=too-many-branches action="store_true", help="If given, uses the Linode's SLAAC address for SSH.", ) + parser.add_argument( + "-d", + action="store_true", + help="If given, uses the Lindoe's domain name for SSH", + ) parsed, args = parser.parse_known_args(args) @@ -147,4 +152,7 @@ def parse_target_address( if ip.startswith("192.168"): continue + if getattr(parsed, "d"): + ip = ip.replace(".", "-") + ".ip.linodeusercontent.com" + return ip diff --git a/tests/unit/test_plugin_ssh.py b/tests/unit/test_plugin_ssh.py index 92471fde9..216734da0 100644 --- a/tests/unit/test_plugin_ssh.py +++ b/tests/unit/test_plugin_ssh.py @@ -187,11 +187,17 @@ def test_parse_target_address(): "ipv6": "c001:d00d::1337/128", } - test_namespace = argparse.Namespace(**{"6": False}) + test_namespace = argparse.Namespace(**{"6": False, "d": False}) address = plugin.parse_target_address(test_namespace, test_target) assert address == "123.123.123.123" + # Hack to work around invalid key + setattr(test_namespace, "d", True) + + address = plugin.parse_target_address(test_namespace, test_target) + assert address == "123-123-123-123.ip.linodeusercontent.com" + # Hack to work around invalid key setattr(test_namespace, "6", True) From 2cd1160bd058851fe931968f6fb8e161ec6f8494 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:22:19 -0500 Subject: [PATCH 05/18] build(deps): bump docker/build-push-action from 6.13.0 to 6.15.0 (#741) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d24ab9e8b..c1e1f969e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -67,7 +67,7 @@ jobs: result-encoding: string - name: Build and push to DockerHub - uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # pin@v6.13.0 + uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # pin@v6.15.0 with: context: . file: Dockerfile From 9146e20b83c423bd5b23f7037786f5abea7753d8 Mon Sep 17 00:00:00 2001 From: Ye Chen <127243817+yec-akamai@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:13:34 -0500 Subject: [PATCH 06/18] Update image view integration test (#738) --- tests/integration/image/test_plugin_image_upload.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/integration/image/test_plugin_image_upload.py b/tests/integration/image/test_plugin_image_upload.py index 3174986b5..5a05b0536 100644 --- a/tests/integration/image/test_plugin_image_upload.py +++ b/tests/integration/image/test_plugin_image_upload.py @@ -199,3 +199,6 @@ def test_image_view(get_image_id): headers = ["label", "description"] assert_headers_in_lines(headers, lines) + + # assert that regions in the output + assert "regions" in lines From e0d17e36e51880207daf178fdf1099f3345329d8 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 11 Mar 2025 09:41:44 -0400 Subject: [PATCH 07/18] Print OBJ plugin errors to stderr (#737) --- linodecli/plugins/obj/__init__.py | 12 ++++++++---- linodecli/plugins/obj/objects.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/linodecli/plugins/obj/__init__.py b/linodecli/plugins/obj/__init__.py index 9fd981b65..b25ffbf43 100644 --- a/linodecli/plugins/obj/__init__.py +++ b/linodecli/plugins/obj/__init__.py @@ -173,7 +173,8 @@ def set_acl(get_client, args, **kwargs): # pylint: disable=unused-argument try: set_acl_func(**set_acl_options) - except ClientError: + except ClientError as e: + print(e, file=sys.stderr) sys.exit(ExitCodes.REQUEST_FAILED) print("ACL updated") @@ -203,14 +204,16 @@ def show_usage(get_client, args, **kwargs): # pylint: disable=unused-argument bucket_names = [ b["Name"] for b in client.list_buckets().get("Buckets", []) ] - except ClientError: + except ClientError as e: + print(e, file=sys.stderr) sys.exit(ExitCodes.REQUEST_FAILED) grand_total = 0 for b in bucket_names: try: objects = client.list_objects_v2(Bucket=b).get("Contents", []) - except ClientError: + except ClientError as e: + print(e, file=sys.stderr) sys.exit(ExitCodes.REQUEST_FAILED) total = 0 obj_count = 0 @@ -358,7 +361,8 @@ def call( # we can't do anything - ask for an install print( "This plugin requires the 'boto3' module. Please install it by running " - "'pip3 install boto3' or 'pip install boto3'" + "'pip3 install boto3' or 'pip install boto3'", + file=sys.stderr, ) sys.exit( diff --git a/linodecli/plugins/obj/objects.py b/linodecli/plugins/obj/objects.py index f3e2513cf..56aa5cf3f 100644 --- a/linodecli/plugins/obj/objects.py +++ b/linodecli/plugins/obj/objects.py @@ -81,6 +81,10 @@ def upload_object( for f in files: file_path = Path(f).resolve() if not file_path.is_file(): + print( + f"Error: '{file_path}' is not a valid file or does not exist.", + file=sys.stderr, + ) sys.exit(ExitCodes.FILE_ERROR) to_upload.append(file_path) @@ -112,7 +116,8 @@ def upload_object( ) try: client.upload_file(**upload_options) - except S3UploadFailedError: + except S3UploadFailedError as e: + print(e, file=sys.stderr) sys.exit(ExitCodes.REQUEST_FAILED) print("Done.") @@ -174,7 +179,8 @@ def get_object( # In the future we should allow the automatic creation of parent directories if not destination_parent.exists(): print( - f"ERROR: Output directory {destination_parent} does not exist locally." + f"ERROR: Output directory {destination_parent} does not exist locally.", + file=sys.stderr, ) sys.exit(ExitCodes.REQUEST_FAILED) From 0ed9d73f731f6b00afd403e4411e81ef08d8bb80 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 11 Mar 2025 09:42:51 -0400 Subject: [PATCH 08/18] Added integration tests for suspend and resume (#743) --- tests/integration/database/test_database.py | 119 +++++++++++++++++++- 1 file changed, 114 insertions(+), 5 deletions(-) diff --git a/tests/integration/database/test_database.py b/tests/integration/database/test_database.py index b98732553..3fc9843bb 100644 --- a/tests/integration/database/test_database.py +++ b/tests/integration/database/test_database.py @@ -1,12 +1,15 @@ +import time + import pytest -from tests.integration.helpers import assert_headers_in_lines, exec_test_command +from tests.integration.helpers import ( + assert_headers_in_lines, + delete_target_id, + exec_test_command, +) +from tests.integration.linodes.helpers_linodes import DEFAULT_LABEL BASE_CMD = ["linode-cli", "databases"] -pytestmark = pytest.mark.skip( - "This command is currently only available for customers who already have an active " - "Managed Database." -) def test_engines_list(): @@ -20,6 +23,112 @@ def test_engines_list(): assert_headers_in_lines(headers, lines) +timestamp = str(time.time_ns()) +mysql_database_label = DEFAULT_LABEL + "-mysql-" + timestamp +postgresql_database_label = DEFAULT_LABEL + "-postgresql-" + timestamp + + +@pytest.fixture(scope="package", autouse=True) +def test_mysql_cluster(): + database_id = ( + exec_test_command( + BASE_CMD + + [ + "mysql-create", + "--type", + "g6-nanode-1", + "--region", + "us-ord", + "--label", + mysql_database_label, + "--engine", + "mysql/8", + "--text", + "--delimiter", + ",", + "--no-headers", + "--format", + "id", + "--no-defaults", + "--format", + "id", + ] + ) + .stdout.decode() + .rstrip() + ) + + yield database_id + + delete_target_id( + target="databases", delete_command="mysql-delete", id=database_id + ) + + +def test_mysql_suspend_resume(test_mysql_cluster): + database_id = test_mysql_cluster + res = exec_test_command( + BASE_CMD + ["mysql-suspend", database_id, "--text", "--delimiter=,"] + ).stdout.decode() + assert "Request failed: 400" not in res + + res = exec_test_command( + BASE_CMD + ["mysql-resume", database_id, "--text", "--delimiter=,"] + ).stdout.decode() + assert "Request failed: 400" not in res + + +@pytest.fixture(scope="package", autouse=True) +def test_postgresql_cluster(): + database_id = ( + exec_test_command( + BASE_CMD + + [ + "postgresql-create", + "--type", + "g6-nanode-1", + "--region", + "us-ord", + "--label", + postgresql_database_label, + "--engine", + "postgresql/16", + "--text", + "--delimiter", + ",", + "--no-headers", + "--format", + "id", + "--no-defaults", + "--format", + "id", + ] + ) + .stdout.decode() + .rstrip() + ) + + yield database_id + + delete_target_id( + target="databases", delete_command="postgresql-delete", id=database_id + ) + + +def test_postgresql_suspend_resume(test_postgresql_cluster): + database_id = test_postgresql_cluster + res = exec_test_command( + BASE_CMD + + ["postgresql-suspend", database_id, "--text", "--delimiter=,"] + ).stdout.decode() + assert "Request failed: 400" not in res + + res = exec_test_command( + BASE_CMD + ["postgresql-resume", database_id, "--text", "--delimiter=,"] + ).stdout.decode() + assert "Request failed: 400" not in res + + @pytest.fixture def get_engine_id(): engine_id = ( From 6ff18287dbac4a4e065f8238e328e1fe3016fb0c Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-akamai@users.noreply.github.com> Date: Fri, 14 Mar 2025 08:31:29 -0700 Subject: [PATCH 09/18] Add test summary to slack notification (#744) --- .github/workflows/e2e-suite.yml | 27 ++++++++++++++++++++++++++- e2e_scripts | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-suite.yml b/.github/workflows/e2e-suite.yml index 7c73e3209..165055a1b 100644 --- a/.github/workflows/e2e-suite.yml +++ b/.github/workflows/e2e-suite.yml @@ -235,6 +235,8 @@ jobs: runs-on: ubuntu-latest needs: [integration_tests] if: always() && github.repository == 'linode/linode-cli' # Run even if integration tests fail and only on main repository + outputs: + summary: ${{ steps.set-test-summary.outputs.summary }} steps: - name: Checkout code @@ -275,6 +277,17 @@ jobs: LINODE_CLI_OBJ_ACCESS_KEY: ${{ secrets.LINODE_CLI_OBJ_ACCESS_KEY }} LINODE_CLI_OBJ_SECRET_KEY: ${{ secrets.LINODE_CLI_OBJ_SECRET_KEY }} + - name: Generate test summary and save to output + id: set-test-summary + run: | + filename=$(ls | grep -E '^[0-9]{12}_cli_test_report\.xml$') + test_output=$(python3 e2e_scripts/tod_scripts/generate_test_summary.py "${filename}") + { + echo 'summary<> "$GITHUB_OUTPUT" + notify-slack: runs-on: ubuntu-latest @@ -283,6 +296,7 @@ jobs: steps: - name: Notify Slack + id: main_message uses: slackapi/slack-github-action@v2.0.0 with: method: chat.postMessage @@ -293,7 +307,7 @@ jobs: - type: section text: type: mrkdwn - text: ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:" + text: ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* ${{ needs.integration_tests.result == 'success' && ':white_check_mark:' || ':failed:' }}" - type: divider - type: section fields: @@ -312,3 +326,14 @@ jobs: elements: - type: mrkdwn text: "Triggered by: :bust_in_silhouette: `${{ github.actor }}`" + + - name: Test summary thread + if: success() + uses: slackapi/slack-github-action@v2.0.0 + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + channel: ${{ secrets.SLACK_CHANNEL_ID }} + thread_ts: "${{ steps.main_message.outputs.ts }}" + text: "${{ needs.process-upload-report.outputs.summary }}" \ No newline at end of file diff --git a/e2e_scripts b/e2e_scripts index 6b71cb72e..a906260be 160000 --- a/e2e_scripts +++ b/e2e_scripts @@ -1 +1 @@ -Subproject commit 6b71cb72eb20a18ace82f9e73a0f99fe1141d625 +Subproject commit a906260be88208a24d0a1af002a48f9c5efbd561 From 679561f9b0227be20eba9b26329e28c0236b064f Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Mon, 17 Mar 2025 11:05:15 -0400 Subject: [PATCH 10/18] Improve maintainability of arg_helpers.py (#745) --- linodecli/arg_helpers.py | 61 ++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/linodecli/arg_helpers.py b/linodecli/arg_helpers.py index 5cd853ea3..c485d5f62 100644 --- a/linodecli/arg_helpers.py +++ b/linodecli/arg_helpers.py @@ -1,9 +1,14 @@ #!/usr/local/bin/python3 """ -Argument parser for the linode CLI +Argument parser for the linode CLI. +This module defines argument parsing, plugin registration, and plugin removal +functionalities for the Linode CLI. """ import sys +from argparse import ArgumentParser +from configparser import ConfigParser from importlib import import_module +from typing import Dict, Tuple from linodecli import plugins from linodecli.helpers import ( @@ -14,9 +19,13 @@ from linodecli.output.helpers import register_output_args_shared -def register_args(parser): +def register_args(parser: ArgumentParser) -> ArgumentParser: """ - Register static command arguments + Register static command arguments for the Linode CLI. + + :param parser: Argument parser object to which arguments will be added. + + :return: The updated ArgumentParser instance. """ parser.add_argument( "command", @@ -58,6 +67,7 @@ def register_args(parser): help="Prints version information and exits.", ) + # Register shared argument groups register_output_args_shared(parser) register_pagination_args_shared(parser) register_args_shared(parser) @@ -67,38 +77,51 @@ def register_args(parser): # TODO: maybe move to plugins/__init__.py -def register_plugin(module, config, ops): +def register_plugin( + module: str, config: ConfigParser, ops: Dict[str, str] +) -> Tuple[str, int]: """ - Handle registering a plugin - Registering sets up the plugin for all CLI users + Handle registering a plugin for the Linode CLI. + + :param module: The name of the module to be registered as a plugin. + :param config: Configuration parser object. + :param ops: Dictionary of existing CLI operations. + + :return: A tuple containing a message and an exit code. """ - # attempt to import the module to prove it is installed and exists + + # Attempt to import the module to prove it is installed and exists try: plugin = import_module(module) except ImportError: return f"Module {module} not installed", 10 + # Ensure the module defines a PLUGIN_NAME attribute try: plugin_name = plugin.PLUGIN_NAME except AttributeError: msg = f"{module} is not a valid Linode CLI plugin - missing PLUGIN_NAME" return msg, 11 + # Ensure the module has a 'call' function, which is required for execution try: call_func = plugin.call - del call_func + del call_func # Just checking if it exists, so we can discard it except AttributeError: msg = f"{module} is not a valid Linode CLI plugin - missing call" return msg, 11 + # Check if the plugin name conflicts with existing CLI operations if plugin_name in ops: msg = "Plugin name conflicts with CLI operation - registration failed." return msg, 12 + # Check if the plugin name conflicts with an internal CLI plugin if plugin_name in plugins.AVAILABLE_LOCAL: msg = "Plugin name conflicts with internal CLI plugin - registration failed." return msg, 13 + # Check if the plugin is already registered and ask for re-registration if needed reregistering = False if plugin_name in plugins.available(config): print( @@ -110,20 +133,26 @@ def register_plugin(module, config, ops): return "Registration aborted.", 0 reregistering = True + # Retrieve the list of already registered plugins from the config already_registered = [] if config.config.has_option("DEFAULT", "registered-plugins"): already_registered = config.config.get( "DEFAULT", "registered-plugins" ).split(",") + # If re-registering, remove the existing entry before adding it again if reregistering: already_registered.remove(plugin_name) config.config.remove_option("DEFAULT", f"plugin-name-{plugin_name}") + # Add the new plugin to the registered list already_registered.append(plugin_name) config.config.set( "DEFAULT", "registered-plugins", ",".join(already_registered) ) + + # Store the module name associated with this plugin in the config + # and save the updated config to persist changes config.config.set("DEFAULT", f"plugin-name-{plugin_name}", module) config.write_config() @@ -136,19 +165,27 @@ def register_plugin(module, config, ops): # TODO: also maybe move to plugins -def remove_plugin(plugin_name, config): +def remove_plugin(plugin_name: str, config: ConfigParser) -> Tuple[str, int]: """ - Remove a plugin + Remove a registered plugin from the Linode CLI. + + :param plugin_name: The name of the plugin to remove. + :param config: Configuration parser object that manages CLI settings. + + :return: A tuple containing a message and an exit code. """ + + # Check if the plugin is a built-in CLI plugin that cannot be removed if plugin_name in plugins.AVAILABLE_LOCAL: msg = f"{plugin_name} is bundled with the CLI and cannot be removed" return msg, 13 + # Check if the plugin is actually registered before attempting removal if plugin_name not in plugins.available(config): msg = f"{plugin_name} is not a registered plugin" return msg, 14 - # do the removal + # Do the removal current_plugins = config.config.get("DEFAULT", "registered-plugins").split( "," ) @@ -157,7 +194,7 @@ def remove_plugin(plugin_name, config): "DEFAULT", "registered-plugins", ",".join(current_plugins) ) - # if the config if malformed, don't blow up + # If the config is malformed, don't blow up if config.config.has_option("DEFAULT", f"plugin-name-{plugin_name}"): config.config.remove_option("DEFAULT", f"plugin-name-{plugin_name}") From 533e9ceebe287b4db01339b3d16402e32592c530 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 18 Mar 2025 14:57:11 -0700 Subject: [PATCH 11/18] Improve maintainability of api_request.py (#748) --- linodecli/api_request.py | 181 +++++++++++++++++++++++++++++++-------- 1 file changed, 146 insertions(+), 35 deletions(-) diff --git a/linodecli/api_request.py b/linodecli/api_request.py index c133d823b..8c7879ee7 100644 --- a/linodecli/api_request.py +++ b/linodecli/api_request.py @@ -7,7 +7,7 @@ import os import sys import time -from typing import Any, Iterable, List, Optional +from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional import requests from packaging import version @@ -23,13 +23,22 @@ ) from .helpers import handle_url_overrides +if TYPE_CHECKING: + from linodecli.cli import CLI -def get_all_pages(ctx, operation: OpenAPIOperation, args: List[str]): + +def get_all_pages( + ctx: "CLI", operation: OpenAPIOperation, args: List[str] +) -> Dict[str, Any]: """ - Receive all pages of a resource from multiple - API responses then merge into one page. + Retrieves all pages of a resource from multiple API responses + and merges them into a single page. + + :param ctx: The main CLI object that maintains API request state. + :param operation: The OpenAPI operation to be executed. + :param args: A list of arguments passed to the API request. - :param ctx: The main CLI object + :return: A dictionary containing the merged results from all pages. """ ctx.page_size = 500 @@ -38,6 +47,7 @@ def get_all_pages(ctx, operation: OpenAPIOperation, args: List[str]): total_pages = result.get("pages") + # If multiple pages exist, generate results for all additional pages if total_pages and total_pages > 1: pages_needed = range(2, total_pages + 1) @@ -51,19 +61,25 @@ def get_all_pages(ctx, operation: OpenAPIOperation, args: List[str]): def do_request( - ctx, - operation, - args, - filter_header=None, - skip_error_handling=False, + ctx: "CLI", + operation: OpenAPIOperation, + args: List[str], + filter_header: Optional[dict] = None, + skip_error_handling: bool = False, ) -> ( Response ): # pylint: disable=too-many-locals,too-many-branches,too-many-statements """ - Makes a request to an operation's URL and returns the resulting JSON, or - prints and error if a non-200 comes back + Makes an HTTP request to an API operation's URL and returns the resulting response. + Optionally retries the request if specified, handles errors, and supports debugging. + + :param ctx: The main CLI object that maintains API request state. + :param operation: The OpenAPI operation to be executed. + :param args: A list of arguments passed to the API request. + :param filter_header: Optional filter header to be included in the request (default: None). + :param skip_error_handling: Whether to skip error handling (default: False). - :param ctx: The main CLI object + :return: The `Response` object returned from the HTTP request. """ # TODO: Revisit using pre-built calls from OpenAPI method = getattr(requests, operation.method) @@ -95,6 +111,7 @@ def do_request( if ctx.debug_request: _print_response_debug_info(result) + # Retry the request if necessary while _check_retry(result) and not ctx.no_retry and ctx.retry_count < 3: time.sleep(_get_retry_after(result.headers)) ctx.retry_count += 1 @@ -102,24 +119,37 @@ def do_request( _attempt_warn_old_version(ctx, result) + # If the response is an error and we're not skipping error handling, raise an error if not 199 < result.status_code < 399 and not skip_error_handling: _handle_error(ctx, result) return result -def _merge_results_data(results: Iterable[dict]): - """Merge multiple json response into one""" +def _merge_results_data(results: Iterable[dict]) -> Optional[Dict[str, Any]]: + """ + Merges multiple JSON responses into one, combining their 'data' fields + and setting 'pages' and 'page' to 1 if they exist. + + :param results: An iterable of dictionaries containing JSON response data. + + :return: A merged dictionary containing the combined data or None if no results are provided. + """ iterator = iter(results) merged_result = next(iterator, None) + + # If there are no results to merge, return None if not merged_result: return None + # Set 'pages' and 'page' to 1 if they exist in the first result if "pages" in merged_result: merged_result["pages"] = 1 if "page" in merged_result: merged_result["page"] = 1 + + # Merge the 'data' fields by combining the 'data' from all results if "data" in merged_result: merged_result["data"] += list( itertools.chain.from_iterable(r["data"] for r in iterator) @@ -128,13 +158,21 @@ def _merge_results_data(results: Iterable[dict]): def _generate_all_pages_results( - ctx, + ctx: "CLI", operation: OpenAPIOperation, args: List[str], pages_needed: Iterable[int], -): +) -> Iterable[dict]: """ - :param ctx: The main CLI object + Generates results from multiple pages by iterating through the specified page numbers + and yielding the JSON response for each page.e. + + :param ctx: The main CLI object that maintains API request state. + :param operation: The OpenAPI operation to be executed. + :param args: A list of arguments passed to the API request. + :param pages_needed: An iterable of page numbers to request. + + :yield: The JSON response (as a dictionary) for each requested page. """ for p in pages_needed: ctx.page = p @@ -142,8 +180,21 @@ def _generate_all_pages_results( def _build_filter_header( - operation, parsed_args, filter_header=None + operation: OpenAPIOperation, + parsed_args: Any, + filter_header: Optional[dict] = None, ) -> Optional[str]: + """ + Builds a filter header for a request based on the parsed + arguments. This is used for GET requests to filter results according + to the specified arguments. If no filter is provided, returns None. + + :param operation: The OpenAPI operation to be executed. + :param parsed_args: The parsed arguments from the CLI or request + :param filter_header: Optional filter header to be included in the request (default: None). + + :return: A JSON string representing the filter header, or None if no filters are applied. + """ if operation.method != "get": # Non-GET operations don't support filters return None @@ -188,7 +239,19 @@ def _build_filter_header( return json.dumps(result) if len(result) > 0 else None -def _build_request_url(ctx, operation, parsed_args) -> str: +def _build_request_url( + ctx: "CLI", operation: OpenAPIOperation, parsed_args: Any +) -> str: + """ + Constructs the full request URL for an API operation, + incorporating user-defined API host and scheme overrides. + + :param ctx: The main CLI object that maintains API request state. + :param operation: The OpenAPI operation to be executed. + :param parsed_args: The parsed arguments from the CLI or request. + + :return: The fully constructed request URL as a string. + """ url_base = handle_url_overrides( operation.url_base, host=ctx.config.get_value("api_host"), @@ -206,6 +269,7 @@ def _build_request_url(ctx, operation, parsed_args) -> str: **vars(parsed_args), ) + # Append pagination parameters for GET requests if operation.method == "get": result += f"?page={ctx.page}&page_size={ctx.page_size}" @@ -214,10 +278,15 @@ def _build_request_url(ctx, operation, parsed_args) -> str: def _traverse_request_body(o: Any) -> Any: """ - This function traverses is intended to be called immediately before - request body serialization and contains special handling for dropping - keys with null values and translating ExplicitNullValue instances into - serializable null values. + Traverses a request body before serialization, handling special cases: + - Drops keys with `None` values (implicit null values). + - Converts `ExplicitEmptyListValue` instances to empty lists. + - Converts `ExplicitNullValue` instances to `None`. + - Recursively processes nested dictionaries and lists. + + :param o: The request body object to process. + + :return: A modified version of `o` with appropriate transformations applied. """ if isinstance(o, dict): result = {} @@ -253,7 +322,18 @@ def _traverse_request_body(o: Any) -> Any: return o -def _build_request_body(ctx, operation, parsed_args) -> Optional[str]: +def _build_request_body( + ctx: "CLI", operation: OpenAPIOperation, parsed_args: Any +) -> Optional[str]: + """ + Builds the request body for API calls, handling default values and nested structures. + + :param ctx: The main CLI object that maintains API request state. + :param operation: The OpenAPI operation to be executed. + :param parsed_args: The parsed arguments from the CLI or request. + + :return: A JSON string representing the request body, or None if not applicable. + """ if operation.method == "get": # Get operations don't have a body return None @@ -266,7 +346,7 @@ def _build_request_body(ctx, operation, parsed_args) -> Optional[str]: expanded_json = {} - # expand paths + # Expand dotted keys into nested dictionaries for k, v in vars(parsed_args).items(): if v is None or k in param_names: continue @@ -282,9 +362,17 @@ def _build_request_body(ctx, operation, parsed_args) -> Optional[str]: return json.dumps(_traverse_request_body(expanded_json)) -def _print_request_debug_info(method, url, headers, body): +def _print_request_debug_info( + method: Any, url: str, headers: Dict[str, Any], body: Optional[str] +) -> None: """ - Prints debug info for an HTTP request + Prints debug info for an HTTP request. + + :param method: An object with a `__name__` attribute representing + the HTTP method (e.g., "get", "post"). + :param url: The full request URL. + :param headers: A dictionary of request headers. + :param body: The request body as a string, or None if no body exists. """ print(f"> {method.__name__.upper()} {url}", file=sys.stderr) for k, v in headers.items(): @@ -297,9 +385,11 @@ def _print_request_debug_info(method, url, headers, body): print("> ", file=sys.stderr) -def _print_response_debug_info(response): +def _print_response_debug_info(response: Any) -> None: """ - Prints debug info for a response from requests + Prints debug info for a response from requests. + + :param response: The response object returned by a `requests` call. """ # these come back as ints, convert to HTTP version http_version = response.raw.version / 10 @@ -316,7 +406,14 @@ def _print_response_debug_info(response): print("< ", file=sys.stderr) -def _attempt_warn_old_version(ctx, result): +def _attempt_warn_old_version(ctx: "CLI", result: Any) -> None: + """ + Checks if the API version is newer than the CLI version and + warns the user if an upgrade is available. + + :param ctx: The main CLI object that maintains API request state. + :param result: The HTTP response object from the API request. + """ if ctx.suppress_warnings: return @@ -398,9 +495,13 @@ def _attempt_warn_old_version(ctx, result): ) -def _handle_error(ctx, response): +def _handle_error(ctx: "CLI", response: Any) -> None: """ - Given an error message, properly displays the error to the user and exits. + Handles API error responses by displaying a formatted error message + and exiting with the appropriate error code. + + :param ctx: The main CLI object that maintains API request state. + :param response: The HTTP response object from the API request. """ print(f"Request failed: {response.status_code}", file=sys.stderr) @@ -422,7 +523,9 @@ def _handle_error(ctx, response): def _check_retry(response): """ - Check for valid retry scenario, returns true if retry is valid + Check for valid retry scenario, returns true if retry is valid. + + :param response: The HTTP response object from the API request. """ if response.status_code in (408, 429): # request timed out or rate limit exceeded @@ -436,6 +539,14 @@ def _check_retry(response): ) -def _get_retry_after(headers): +def _get_retry_after(headers: Dict[str, str]) -> int: + """ + Extracts the "Retry-After" value from the response headers and returns it + as an integer representing the number of seconds to wait before retrying. + + :param headers: The HTTP response headers as a dictionary. + + :return: The number of seconds to wait before retrying, or 0 if not specified. + """ retry_str = headers.get("Retry-After", "") return int(retry_str) if retry_str else 0 From 7ad1df41b16765b60c71f0acc9a080759114d162 Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-akamai@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:02:46 -0700 Subject: [PATCH 12/18] Add conditions to notification job in e2e workflow (#747) --- .github/workflows/e2e-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-suite.yml b/.github/workflows/e2e-suite.yml index 165055a1b..b1e19ab49 100644 --- a/.github/workflows/e2e-suite.yml +++ b/.github/workflows/e2e-suite.yml @@ -291,7 +291,7 @@ jobs: notify-slack: runs-on: ubuntu-latest - needs: [integration_tests] + needs: [integration_tests, process-upload-report] if: ${{ (success() || failure()) && github.repository == 'linode/linode-cli' }} # Run even if integration tests fail and only on main repository steps: From a939ff520108462c343700d9ba7262a240f2b45c Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-akamai@users.noreply.github.com> Date: Fri, 21 Mar 2025 12:25:25 -0700 Subject: [PATCH 13/18] Remove deprecated warning and update license format to latest format (#751) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8b1c35e1c..27a8aea5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ authors = [{ name = "Akamai Technologies Inc.", email = "developers@linode.com" description = "The official command-line interface for interacting with the Linode API." readme = "README.md" requires-python = ">=3.9" -license = { text = "BSD-3-Clause" } +license = "BSD-3-Clause" classifiers = [] dependencies = [ "openapi3", From 6583a5f62114339289b66fc38085dd1d51d4656e Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:56:18 -0400 Subject: [PATCH 14/18] Configure Python `logging` level when debug flag is specified; add debug logs to bake command (#749) Co-authored-by: Ye Chen <127243817+yec-akamai@users.noreply.github.com> --- Makefile | 4 +- linodecli/__init__.py | 6 + linodecli/api_request.py | 75 +- linodecli/baked/operation.py | 15 +- linodecli/cli.py | 47 +- linodecli/helpers.py | 5 +- openapi.json | 114632 ++++++++++++++++++++++++++++++ tests/unit/test_api_request.py | 48 +- 8 files changed, 114772 insertions(+), 60 deletions(-) create mode 100644 openapi.json diff --git a/Makefile b/Makefile index 27eb93550..8c87974e0 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,8 @@ VERSION_FILE := ./linodecli/version.py VERSION_MODULE_DOCSTRING ?= \"\"\"\nThe version of the Linode CLI.\n\"\"\"\n\n LINODE_CLI_VERSION ?= "0.0.0.dev" +BAKE_FLAGS := --debug + .PHONY: install install: check-prerequisites requirements build pip3 install --force dist/*.whl @@ -21,7 +23,7 @@ bake: clean ifeq ($(SKIP_BAKE), 1) @echo Skipping bake stage else - python3 -m linodecli bake ${SPEC} --skip-config + python3 -m linodecli bake ${SPEC} --skip-config $(BAKE_FLAGS) cp data-3 linodecli/ endif diff --git a/linodecli/__init__.py b/linodecli/__init__.py index 3fa192e8c..762c676f7 100755 --- a/linodecli/__init__.py +++ b/linodecli/__init__.py @@ -4,6 +4,7 @@ """ import argparse +import logging import os import sys from importlib.metadata import version @@ -38,6 +39,11 @@ TEST_MODE = os.getenv("LINODE_CLI_TEST_MODE") == "1" +# Configure the `logging` package log level depending on the --debug flag. +logging.basicConfig( + level=logging.DEBUG if "--debug" in argv else logging.WARNING, +) + # if any of these arguments are given, we don't need to prompt for configuration skip_config = ( any( diff --git a/linodecli/api_request.py b/linodecli/api_request.py index 8c7879ee7..f0369370b 100644 --- a/linodecli/api_request.py +++ b/linodecli/api_request.py @@ -7,6 +7,7 @@ import os import sys import time +from logging import getLogger from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional import requests @@ -26,6 +27,8 @@ if TYPE_CHECKING: from linodecli.cli import CLI +logger = getLogger(__name__) + def get_all_pages( ctx: "CLI", operation: OpenAPIOperation, args: List[str] @@ -103,13 +106,18 @@ def do_request( # Print response debug info is requested if ctx.debug_request: - _print_request_debug_info(method, url, headers, body) + # Multiline log entries aren't ideal, we should consider + # using single-line structured logging in the future. + logger.debug( + "\n%s", + "\n".join(_format_request_for_log(method, url, headers, body)), + ) result = method(url, headers=headers, data=body, verify=API_CA_PATH) # Print response debug info is requested if ctx.debug_request: - _print_response_debug_info(result) + logger.debug("\n%s", "\n".join(_format_response_for_log(result))) # Retry the request if necessary while _check_retry(result) and not ctx.no_retry and ctx.retry_count < 3: @@ -362,48 +370,61 @@ def _build_request_body( return json.dumps(_traverse_request_body(expanded_json)) -def _print_request_debug_info( - method: Any, url: str, headers: Dict[str, Any], body: Optional[str] -) -> None: +def _format_request_for_log( + method: Any, + url: str, + headers: Dict[str, str], + body: str, +) -> List[str]: """ - Prints debug info for an HTTP request. + Builds a debug output for the given request. - :param method: An object with a `__name__` attribute representing - the HTTP method (e.g., "get", "post"). - :param url: The full request URL. - :param headers: A dictionary of request headers. - :param body: The request body as a string, or None if no body exists. + :param method: The HTTP method of the request. + :param url: The URL of the request. + :param headers: The headers of the request. + :param body: The body of the request. + + :returns: The lines of the generated debug output. """ - print(f"> {method.__name__.upper()} {url}", file=sys.stderr) + result = [f"> {method.__name__.upper()} {url}"] + for k, v in headers.items(): # If this is the Authorization header, sanitize the token if k.lower() == "authorization": v = "Bearer " + "*" * 64 - print(f"> {k}: {v}", file=sys.stderr) - print("> Body:", file=sys.stderr) - print("> ", body or "", file=sys.stderr) - print("> ", file=sys.stderr) + + result.append(f"> {k}: {v}") + + result.extend(["> Body:", f"> {body or ''}", "> "]) + + return result -def _print_response_debug_info(response: Any) -> None: +def _format_response_for_log( + response: requests.Response, +): """ - Prints debug info for a response from requests. + Builds a debug output for the given response. - :param response: The response object returned by a `requests` call. + :param response: The HTTP response to format. + + :returns: The lines of the generated debug output. """ + # these come back as ints, convert to HTTP version http_version = response.raw.version / 10 body = response.content.decode("utf-8", errors="replace") - print( - f"< HTTP/{http_version:.1f} {response.status_code} {response.reason}", - file=sys.stderr, - ) + result = [ + f"< HTTP/{http_version:.1f} {response.status_code} {response.reason}" + ] + for k, v in response.headers.items(): - print(f"< {k}: {v}", file=sys.stderr) - print("< Body:", file=sys.stderr) - print("< ", body or "", file=sys.stderr) - print("< ", file=sys.stderr) + result.append(f"< {k}: {v}") + + result.extend(["< Body:", f"< {body or ''}", "< "]) + + return result def _attempt_warn_old_version(ctx: "CLI", result: Any) -> None: diff --git a/linodecli/baked/operation.py b/linodecli/baked/operation.py index a14b2a1e9..0c41d2b6a 100644 --- a/linodecli/baked/operation.py +++ b/linodecli/baked/operation.py @@ -5,6 +5,7 @@ import argparse import glob import json +import logging import platform import re import sys @@ -400,9 +401,10 @@ def __init__( self.docs_url = self._resolve_operation_docs_url(operation) if self.docs_url is None: - print( - f"INFO: Could not resolve docs URL for {operation}", - file=sys.stderr, + logging.warning( + "%s %s Could not resolve docs URL for operation", + self.method.upper(), + self.url_path, ) code_samples_ext = operation.extensions.get("code-samples") @@ -426,6 +428,13 @@ def arg_routes(self) -> Dict[str, List[OpenAPIRequestArg]]: """ return self.request.attr_routes if self.request else [] + @property + def attrs(self): + """ + Return a list of attributes from the request schema + """ + return self.response_model.attrs if self.response_model else [] + @staticmethod def _flatten_url_path(tag: str) -> str: """ diff --git a/linodecli/cli.py b/linodecli/cli.py index 1838afd25..545b469ec 100644 --- a/linodecli/cli.py +++ b/linodecli/cli.py @@ -8,6 +8,7 @@ import pickle import sys from json import JSONDecodeError +from logging import getLogger from sys import version_info from typing import IO, Any, ContextManager, Dict @@ -23,6 +24,8 @@ METHODS = ("get", "post", "put", "delete") +logger = getLogger(__name__) + class CLI: # pylint: disable=too-many-instance-attributes """ @@ -54,6 +57,7 @@ def bake(self, spec_location: str): """ try: + logger.debug("Loading and parsing OpenAPI spec: %s", spec_location) spec = self._load_openapi_spec(spec_location) except Exception as e: print(f"Failed to load spec: {e}") @@ -72,21 +76,60 @@ def bake(self, spec_location: str): command = path.extensions.get(ext["command"], "default") for m in METHODS: operation = getattr(path, m) - if operation is None or ext["skip"] in operation.extensions: + + if operation is None: + continue + + operation_log_fmt = f"{m.upper()} {path.path[-1]}" + + logger.debug( + "%s: Attempting to generate command for operation", + operation_log_fmt, + ) + + if ext["skip"] in operation.extensions: + logger.debug( + "%s: Skipping operation due to x-linode-cli-skip extension", + operation_log_fmt, + ) continue + action = operation.extensions.get( ext["action"], operation.operationId ) if not action: + logger.warning( + "%s: Skipping operation due to unresolvable action", + operation_log_fmt, + ) continue + if isinstance(action, list): action = action[0] + if command not in self.ops: self.ops[command] = {} - self.ops[command][action] = OpenAPIOperation( + + operation = OpenAPIOperation( command, operation, m, path.parameters ) + logger.debug( + "%s %s: Successfully built command for operation: " + "command='%s %s'; summary='%s'; paginated=%s; num_args=%s; num_attrs=%s", + operation.method.upper(), + operation.url_path, + operation.command, + operation.action, + operation.summary.rstrip("."), + operation.response_model + and operation.response_model.is_paginated, + len(operation.args), + len(operation.attrs), + ) + + self.ops[command][action] = operation + # hide the base_url from the spec away self.ops["_base_url"] = self.spec.servers[0].url self.ops["_spec_version"] = self.spec.info.version diff --git a/linodecli/helpers.py b/linodecli/helpers.py index f94096194..81a51eb12 100644 --- a/linodecli/helpers.py +++ b/linodecli/helpers.py @@ -106,7 +106,10 @@ def register_debug_arg(parser: ArgumentParser): ArgumentParser that may be shared across the CLI and plugins. """ parser.add_argument( - "--debug", action="store_true", help="Enable verbose HTTP debug output." + "--debug", + action="store_true", + help="Enable verbose debug logging, including displaying HTTP debug output and " + "configuring the Python logging package level to DEBUG.", ) diff --git a/openapi.json b/openapi.json new file mode 100644 index 000000000..ee48bc1dd --- /dev/null +++ b/openapi.json @@ -0,0 +1,114632 @@ +{ + "components": { + "parameters": { + "api-version-path": { + "description": "Call either the `v4` URL, or `v4beta` for operations still in Beta.", + "in": "path", + "name": "apiVersion", + "required": true, + "schema": { + "enum": [ + "v4", + "v4beta" + ], + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/api-version-path.yaml" + } + }, + "beta-id": { + "description": "The ID of the Beta Program.", + "in": "path", + "name": "betaId", + "required": true, + "schema": { + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/beta-id.yaml" + } + }, + "client-id-path": { + "description": "The OAuth Client ID to look up.", + "in": "path", + "name": "clientId", + "required": true, + "schema": { + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/client-id-path.yaml" + } + }, + "client-id-path-ecf807fb": { + "description": "The OAuth Client ID to look up.", + "in": "path", + "name": "clientId", + "required": true, + "schema": { + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/client-id-path-ecf807fb.yaml" + } + }, + "eeuid": { + "description": "The child account to look up. You can run the [List child accounts](https://techdocs.akamai.com/linode-api/reference/get-child-accounts) operation to find the applicable account and store its `euuid`.", + "in": "path", + "name": "euuid", + "required": true, + "schema": { + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/eeuid.yaml" + } + }, + "event-id-path-214cd042": { + "description": "The ID of the Event to designate as seen.", + "in": "path", + "name": "eventId", + "required": true, + "schema": { + "example": 824, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/event-id-path-214cd042.yaml" + } + }, + "event-id-path-39255fcf": { + "description": "The ID of the Event.", + "in": "path", + "name": "eventId", + "required": true, + "schema": { + "example": 824, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/event-id-path-39255fcf.yaml" + } + }, + "event-id-path-625aa248": { + "description": "The ID of the Event to designate as read.", + "in": "path", + "name": "eventId", + "required": true, + "schema": { + "example": 824, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/event-id-path-625aa248.yaml" + } + }, + "id-path": { + "description": "The slug for the applicable data center. Run the [List regions](https://techdocs.akamai.com/linode-api/reference/get-regions) operation to view the slug for each data center.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/id-path.yaml" + } + }, + "invoice-id-path": { + "description": "The ID of the Invoice.", + "in": "path", + "name": "invoiceId", + "required": true, + "schema": { + "example": 387, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/invoice-id-path.yaml" + } + }, + "login-id-path": { + "description": "The ID of the login object to access.", + "in": "path", + "name": "loginId", + "required": true, + "schema": { + "example": 863, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/login-id-path.yaml" + } + }, + "page-offset": { + "description": "The page of a collection to return.", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "example": 6, + "minimum": 1, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/page-offset.yaml" + } + }, + "page-size": { + "description": "The number of items to return per page.", + "in": "query", + "name": "page_size", + "schema": { + "default": 100, + "example": 50, + "maximum": 500, + "minimum": 25, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/page-size.yaml" + } + }, + "payment-id-path": { + "description": "The ID of the Payment to look up.", + "in": "path", + "name": "paymentId", + "required": true, + "schema": { + "example": 627, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/payment-id-path.yaml" + } + }, + "payment-method-id-path-6078bc7b": { + "description": "The ID of the Payment Method to look up.", + "in": "path", + "name": "paymentMethodId", + "required": true, + "schema": { + "example": 267, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/payment-method-id-path-6078bc7b.yaml" + } + }, + "payment-method-id-path-fb39a844": { + "description": "The ID of the Payment Method to make default.", + "in": "path", + "name": "paymentMethodId", + "required": true, + "schema": { + "example": 267, + "type": "integer" + }, + "x-akamai": { + "file-path": "parameters/payment-method-id-path-fb39a844.yaml" + } + }, + "token-path-f857f5a2": { + "description": "The UUID of the Service Transfer.", + "in": "path", + "name": "token", + "required": true, + "schema": { + "format": "uuid", + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/token-path-f857f5a2.yaml" + } + }, + "token-path-faf66b58": { + "description": "The UUID of the Entity Transfer.", + "in": "path", + "name": "token", + "required": true, + "schema": { + "format": "uuid", + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/token-path-faf66b58.yaml" + } + }, + "username-path": { + "description": "The username to look up.", + "in": "path", + "name": "username", + "required": true, + "schema": { + "type": "string" + }, + "x-akamai": { + "file-path": "parameters/username-path.yaml" + } + } + }, + "responses": { + "409": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "errors": { + "items": { + "additionalProperties": false, + "properties": { + "reason": { + "description": "A string explaining that the account could not be canceled because there is an outstanding balance on the account that must be paid first.", + "example": "We were unable to charge your credit card for services rendered. We cannot cancel this account until the balance has been paid.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-cancel-account-409.yaml" + } + }, + "x-example": { + "x-ref": "../examples/tbd.json" + } + } + }, + "description": "Could not charge the credit card on file.", + "x-akamai": { + "file-path": "errors/409.yaml" + } + }, + "accepted-response": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "warnings": { + "items": { + "additionalProperties": false, + "description": "An object for describing a single warning associated with a response.", + "properties": { + "details": { + "description": "Specific information related to the warning.", + "example": "Linode 123 could not be rebooted.", + "type": "string" + }, + "title": { + "description": "The general warning message.", + "example": "Unable to reboot Linode.", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/warning-object.yaml" + } + }, + "type": "array" + } + }, + "type": "object" + } + } + }, + "description": "Accepted with warning.\n\nA warnings array is included with the standard 200 response body." + }, + "deprecated-response": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "warnings": { + "items": { + "additionalProperties": false, + "description": "An object for describing a single warning associated with a response.", + "properties": { + "details": { + "description": "Specific information related to the warning.", + "example": "Linode 123 could not be rebooted.", + "type": "string" + }, + "title": { + "description": "The general warning message.", + "example": "Unable to reboot Linode.", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/warning-object.yaml" + } + }, + "type": "array" + } + }, + "type": "object" + } + } + }, + "description": "Request successful. This operation is deprecated and may be removed in a future release.\n\nA warnings array is included with the standard 200 response body." + }, + "error-response": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "errors": { + "items": { + "additionalProperties": false, + "description": "An object for describing a single error that occurred during the processing of a request.", + "properties": { + "field": { + "description": "The field in the request that caused this error. This may be a path, separated by periods in the case of nested fields. In some cases this may come back as `null` if the error is not specific to any single element of the request.", + "example": "fieldname", + "type": "string" + }, + "reason": { + "description": "What happened to cause this error. In most cases, this can be fixed immediately by changing the data you sent in the request, but in some cases you will be instructed to [Open a support ticket](https://techdocs.akamai.com/linode-api/reference/post-ticket) or perform some other action before you can complete the request successfully.", + "example": "fieldname must be a valid value", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/error-object.yaml" + } + }, + "type": "array" + } + }, + "type": "object" + } + } + }, + "description": "See [Errors](https://techdocs.akamai.com/linode-api/reference/errors) for the range of possible error response codes." + } + }, + "schemas": { + "account": { + "additionalProperties": false, + "description": "Account object.", + "properties": { + "active_promotions": { + "items": { + "additionalProperties": false, + "description": "__Read-only__ Promotions generally offer a set amount of credit that can be used toward your Linode services, and the promotion expires after a specified date. As well, a monthly cap on the promotional offer is set.\n\nSimply put, a promotion offers a certain amount of credit month, until either the expiration date is passed, or until the total promotional credit is used, whichever comes first.", + "properties": { + "credit_monthly_cap": { + "description": "The amount available to spend per month.", + "example": "10.00", + "type": "string", + "x-linode-cli-display": 5 + }, + "credit_remaining": { + "description": "The total amount of credit left for this promotion.", + "example": "50.00", + "type": "string", + "x-linode-cli-display": 3 + }, + "description": { + "description": "A detailed description of this promotion.", + "example": "Receive up to $10 off your services every month for 6 months! Unused credits will expire once this promotion period ends.", + "type": "string" + }, + "expire_dt": { + "description": "When this promotion's credits expire.", + "example": "2018-01-31T23:59:59", + "type": "string", + "x-linode-cli-display": 2 + }, + "image_url": { + "description": "The location of an image for this promotion.", + "example": "https://linode.com/10_a_month_promotion.svg", + "type": "string" + }, + "service_type": { + "description": "The service to which this promotion applies.", + "enum": [ + "all", + "backup", + "blockstorage", + "db_mysql", + "ip_v4", + "linode", + "linode_disk", + "linode_memory", + "longview", + "managed", + "nodebalancer", + "objectstorage", + "placement_group", + "transfer_tx" + ], + "example": "all", + "type": "string", + "x-linode-cli-display": 1 + }, + "summary": { + "description": "Short details of this promotion.", + "example": "$10 off your Linode a month!", + "type": "string", + "x-linode-cli-display": 10 + }, + "this_month_credit_remaining": { + "description": "The amount of credit left for this month for this promotion.", + "example": "10.00", + "type": "string", + "x-linode-cli-display": 4 + } + }, + "readOnly": true, + "type": "object", + "x-akamai": { + "file-path": "schemas/promotion.yaml" + } + }, + "readOnly": true, + "type": "array" + }, + "active_since": { + "description": "__Read-only__ The date and time the account was activated.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "address_1": { + "description": "The first line of this account's billing address.", + "example": "123 Main Street", + "maxLength": 64, + "type": "string" + }, + "address_2": { + "description": "The second line of this account's billing address.", + "example": "Suite A", + "maxLength": 64, + "type": "string" + }, + "balance": { + "description": "__Read-only__ This account's balance, in US dollars.", + "example": 200, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "balance_uninvoiced": { + "description": "__Read-only__ This account's current estimated invoice in US dollars. This is not your final invoice balance. Transfer charges are not included in the estimate.", + "example": 145, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "billing_source": { + "description": "__Read-only__ The source of service charges for this account. Accounts that are associated with Akamai-specific customers return a value of `akamai`. All other accounts return a value of `linode`.", + "enum": [ + "akamai", + "linode" + ], + "example": "akamai", + "readOnly": true, + "type": "string" + }, + "capabilities": { + "description": "__Read-only__ The Akamai Cloud Computing services your account supports.", + "example": [ + "Linodes", + "NodeBalancers", + "Block Storage", + "Object Storage", + "Placement Groups", + "Block Storage Encryption" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "city": { + "description": "The city for this account's `address`.", + "example": "Philadelphia", + "maxLength": 24, + "type": "string" + }, + "company": { + "description": "The company name assigned to this account. This value can't include the characters, `<` `>` `(` `)` `\"` `=`.", + "example": "Linode LLC", + "maxLength": 128, + "type": "string" + }, + "country": { + "description": "The two-letter ISO 3166 country code for this account's `address`.", + "example": "US", + "type": "string" + }, + "credit_card": { + "additionalProperties": false, + "description": "__Read-only__ The credit card information assigned to this account.", + "properties": { + "expiry": { + "description": "The expiration month and year of the `credit_card`.", + "example": "11/2022", + "type": "string" + }, + "last_four": { + "description": "The last four digits of the `credit_card` assigned to this account.", + "example": 1111, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "email": { + "description": "The email address of the person assigned to this account.", + "example": "john.smith@linode.com", + "maxLength": 128, + "type": "string", + "x-linode-cli-display": 3 + }, + "euuid": { + "description": "__Read-only__ An external unique identifier for this account.", + "example": "E1AF5EEC-526F-487D-B317EBEB34C87D71", + "format": "uuid", + "readOnly": true, + "type": "string" + }, + "first_name": { + "description": "The first name of the person assigned to this account. This value can't include the characters, `<` `>` `(` `)` `\"` `=`.", + "example": "John", + "maxLength": 50, + "type": "string", + "x-linode-cli-display": 1 + }, + "last_name": { + "description": "The last name of the person assigned to this account. This value can't include the characters, `<` `>` `(` `)` `\"` `=`.", + "example": "Smith", + "maxLength": 50, + "type": "string", + "x-linode-cli-display": 2 + }, + "phone": { + "description": "The phone number assigned to this account.", + "example": "215-555-1212", + "maxLength": 32, + "type": "string" + }, + "state": { + "description": "The state or province for the `address` set for your account, if applicable.\n\n- If the `address` is in the United States (US) or Canada (CA), this is the two-letter ISO 3166 code for the state or province.\n\n- If it's a US military `address`, this is the abbreviation for that territory. This includes `AA` for Armed Forces Americas (excluding Canada), `AE` for Armed Forces Africa, Europe, Middle East, and Canada, or `AP` for Armed Forces Pacific.\n\n- If outside the US or CA, this is the province associated with the account's `address`.", + "example": "PA", + "maxLength": 24, + "type": "string" + }, + "tax_id": { + "description": "The tax identification number (TIN) assigned to this account, used for tax calculations. A TIN is set by the national authorities in your `country`, based on your `address_1`, and it may be named differently between countries. Set to an empty string (`\"\"`) if a TIN doesn't apply or for countries that don't collect tax.\n\n> \ud83d\udcd8\n>\n> This value is externally validated. If the validation is successful, a `tax_id_valid` [event](https://techdocs.akamai.com/linode-api/reference/get-events) is triggered. If unsuccessful, a `tax_id_invalid` event is triggered and an error response is issued for an operation that included it.", + "example": "ATU99999999", + "maxLength": 25, + "type": "string" + }, + "zip": { + "description": "The zip code for this account's `address`.\n\n- It can only contain ASCII letters, numbers, and dashes (`-`).\n\n- It can't contain more than nine letter or number characters.", + "example": "19102-1234", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/account.yaml" + } + }, + "account-availability": { + "additionalProperties": false, + "description": "Account Service Availability object.", + "properties": { + "available": { + "description": "__Read-only__ A list of services _available_ to your account in the `region`.", + "example": [ + "Linodes", + "NodeBalancers" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "region": { + "description": "__Read-only__ The Akamai cloud computing data center (region), represented by a slug value. You can view a full list of regions and their associated slugs with the [List regions](https://techdocs.akamai.com/linode-api/reference/get-regions) operation.", + "example": "us-east", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "unavailable": { + "description": "__Read-only__ A list of services _unavailable_ to your account in the `region`.", + "example": [ + "Kubernetes", + "Block Storage" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array", + "x-linode-cli-display": 3 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/account-availability.yaml" + } + }, + "account-settings": { + "additionalProperties": false, + "description": "Account Settings object.", + "properties": { + "backups_enabled": { + "description": "Account-wide backups default. If `true`, all Linodes created will automatically be enrolled in the Backups service. If `false`, Linodes will not be enrolled by default, but may still be enrolled on creation or later.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 4 + }, + "longview_subscription": { + "description": "__Read-only__ The Longview Pro tier you are currently subscribed to. The value must be a [Longview subscription](https://techdocs.akamai.com/linode-api/reference/get-longview-subscriptions) ID or `null` for Longview Free.", + "example": "longview-3", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "managed": { + "description": "__Read-only__ Our 24/7 incident response service. This robust, multi-homed monitoring system distributes monitoring checks to ensure that your servers remain online and available at all times. Linode Managed can monitor any service or software stack reachable over TCP or HTTP. Once you add a service to Linode Managed, we'll monitor it for connectivity, response, and total request time.", + "example": true, + "readOnly": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "network_helper": { + "description": "Enables network helper across all users by default for new Linodes and Linode Configs.", + "example": false, + "type": "boolean", + "x-linode-cli-display": 1 + }, + "object_storage": { + "default": "disabled", + "description": "__Read-only__ A string describing the status of this account's Object Storage service enrollment.", + "enum": [ + "disabled", + "suspended", + "active" + ], + "example": "active", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 5 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/account-settings.yaml" + } + }, + "added-empty-obj": { + "description": "The API responds with an empty object.", + "maxProperties": 0, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-empty-obj.yaml" + } + }, + "added-get-account-logins-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "An object representing a previous successful login for a User.", + "properties": { + "datetime": { + "description": "__Read-only__ When the login was initiated.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "id": { + "description": "__Read-only__ The unique ID of this login object.", + "example": 1234, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "ip": { + "description": "__Read-only__ The remote IP address that requested the login.", + "example": "192.0.2.0", + "format": "ip", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "restricted": { + "description": "__Read-only__ True if the User that attempted the login was a restricted User, false otherwise.", + "example": true, + "readOnly": true, + "type": "boolean", + "x-linode-cli-display": 6 + }, + "status": { + "description": "__Read-only__ Whether the login attempt succeeded or failed.", + "enum": [ + "successful", + "failed" + ], + "example": "successful", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 5 + }, + "username": { + "description": "__Read-only__ The username of the User that attempted the login.", + "example": "example_user", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 4 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/login.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-account-logins-200.yaml" + } + }, + "added-get-availability-200": { + "allOf": [ + { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "Account Service Availability object.", + "properties": { + "available": { + "description": "__Read-only__ A list of services _available_ to your account in the `region`.", + "example": [ + "Linodes", + "NodeBalancers" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "region": { + "description": "__Read-only__ The Akamai cloud computing data center (region), represented by a slug value. You can view a full list of regions and their associated slugs with the [List regions](https://techdocs.akamai.com/linode-api/reference/get-regions) operation.", + "example": "us-east", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "unavailable": { + "description": "__Read-only__ A list of services _unavailable_ to your account in the `region`.", + "example": [ + "Kubernetes", + "Block Storage" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array", + "x-linode-cli-display": 3 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/account-availability.yaml" + } + }, + "type": "array" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "description": "An envelope for paginated response. When accessing a collection through a GET endpoint, the results are wrapped in this envelope which includes metadata about those results. Results are presented within a `data` array. See [Pagination](https://techdocs.akamai.com/linode-api/reference/pagination) for more information.", + "properties": { + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/pagination-envelope.yaml" + } + } + ], + "x-akamai": { + "file-path": "schemas/added-get-availability-200.yaml" + } + }, + "added-get-child-accounts-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "Child account object.", + "properties": { + "active_since": { + "description": "__Read-only__ The activation date and time for the child account.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "address_1": { + "description": "__Filterable__ First line of this child account's billing address.", + "example": "123 Main Street", + "maxLength": 64, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "address_2": { + "description": "__Filterable__ Second line of this child account's billing address, if applicable.", + "example": "Suite A", + "maxLength": 64, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "balance": { + "description": "__Read-only__ This child account's balance, in US dollars.", + "example": 200, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "balance_uninvoiced": { + "description": "__Read-only__ This child account's current estimated invoice in US dollars. This is not your final invoice balance. Transfer charges are not included in the estimate.", + "example": 145, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "billing_source": { + "description": "__Read-only__ The source of service charges for this account, as determined by its relationship with Akamai. The API returns a value of `external` to describe a child account in a parent-child account environment.", + "enum": [ + "external" + ], + "example": "external", + "readOnly": true, + "type": "string" + }, + "capabilities": { + "description": "__Read-only__ A list of the capabilities the child account supports.", + "example": [ + "Linodes", + "NodeBalancers", + "Block Storage", + "Object Storage" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "city": { + "description": "__Filterable__ The city for this child account's billing address.", + "example": "San Diego", + "maxLength": 24, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "company": { + "description": "__Filterable__ The company name for the owner of this child account. It can't include any of these characters: `<` `>` `(` `)` `\"` `=`. You can't change this value yourself. We use it to create the proxy users that a parent account uses to access a child account. Talk to your account team if you need to change this value.", + "example": "Acme", + "maxLength": 128, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "country": { + "description": "__Filterable__ The two-letter ISO 3166 country code for this child account's billing address.", + "example": "US", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "credit_card": { + "additionalProperties": false, + "description": "__Read-only__ Information for the credit card you've assigned to this child account.", + "properties": { + "expiry": { + "description": "The expiration month and year of the credit card.", + "example": "11/2024", + "type": "string" + }, + "last_four": { + "description": "The last four digits of the credit card.", + "example": 1111, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "email": { + "description": "__Filterable__ The email address of the owner of this child account.", + "example": "john.smith@linode.com", + "maxLength": 128, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3, + "x-linode-filterable": true + }, + "euuid": { + "description": "__Read-only__ An external, unique identifier that Akamai assigned to the child account.", + "example": "A1BC2DEF-34GH-567I-J890KLMN12O34P56", + "format": "uuid", + "readOnly": true, + "type": "string" + }, + "first_name": { + "description": "__Filterable__ The first name of the owner of this child account. It can't include any of these characters: `<` `>` `(` `)` `\"` `=`.", + "example": "John", + "maxLength": 50, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "last_name": { + "description": "__Filterable__ The last name of the owner of this child account. It can't include any of these characters: `<` `>` `(` `)` `\"` `=`.", + "example": "Smith", + "maxLength": 50, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "phone": { + "description": "__Filterable__ The phone number for the owner of this child account.", + "example": "858-555-1212", + "maxLength": 32, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "state": { + "description": "__Filterable__ The state or province for the billing address (`address_1` and `address_2, if applicable`). If in the United States (US) or Canada (CA), this is the two-letter ISO 3166 State or Province code.\n\n> \ud83d\udcd8\n>\n> If this is a US military address, use state abbreviations (AA, AE, AP).", + "example": "CA", + "maxLength": 24, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "tax_id": { + "description": "The tax identification number for this child account. Use this for tax calculations in some countries. If you live in a country that doesn't collect taxes, ensure this is an empty string (`\"\"`).", + "example": "ATU99999999", + "maxLength": 25, + "type": "string" + }, + "zip": { + "description": "__Filterable__ The zip code of this Account's billing address. The following restrictions apply:\n\n- Can only contain ASCII letters, numbers, and hyphens (`-`).\n- Can't contain more than 9 letter or number characters.", + "example": "92111-1234", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/child-account.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-child-accounts-200.yaml" + } + }, + "added-get-clients-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "A third-party application registered to Linode that users may log into with their Linode account through our authentication server at [login.linode.com](https://login.linode.com). Using an OAuth Client, a third-party developer may be given access to some, or all, of a User's account for the purposes of their application.", + "properties": { + "id": { + "description": "__Read-only__ The OAuth Client ID. This is used to identify the client, and is a publicly known value (it is not a secret).", + "example": "2737bf16b39ab5d7b4a1", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__ The name of this application. This will be presented to users when they are asked to grant it access to their Account.", + "example": "Test_Client_1", + "maxLength": 512, + "minLength": 1, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "public": { + "default": false, + "description": "__Filterable__ If this is a public or private OAuth Client. Public clients have a slightly different authentication workflow than private clients. See the [OAuth spec](https://oauth.net/2/) for more details.", + "example": false, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "redirect_uri": { + "description": "The location a successful log in from [login.linode.com](https://login.linode.com) should be redirected to for this client. The receiver of this redirect should be ready to accept an OAuth exchange code and finish the OAuth exchange.", + "example": "https://example.org/oauth/callback", + "format": "url", + "type": "string", + "x-linode-cli-display": 5 + }, + "secret": { + "description": "__Read-only__ The OAuth Client secret, used in the OAuth exchange. This is returned as `` except when an OAuth Client is created or its secret is reset. This is a secret, and should not be shared or disclosed publicly.", + "example": "", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The status of this application. `active` by default.", + "enum": [ + "active", + "disabled", + "suspended" + ], + "example": "active", + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "default_": "white", + "suspended": "red" + }, + "x-linode-cli-display": 3 + }, + "thumbnail_url": { + "description": "__Read-only__ The URL where this client's thumbnail may be viewed, or `null` if this client does not have a thumbnail set.", + "example": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", + "format": "url", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/oauth-client.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-clients-200.yaml" + } + }, + "added-get-enrolled-beta-programs-200": { + "allOf": [ + { + "additionalProperties": false, + "description": "An envelope for paginated response. When accessing a collection through a GET endpoint, the results are wrapped in this envelope which includes metadata about those results. Results are presented within a `data` array. See [Pagination](https://techdocs.akamai.com/linode-api/reference/pagination) for more information.", + "properties": { + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/pagination-envelope.yaml" + } + }, + { + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "An object representing an enrolled Beta Program for the Account.", + "properties": { + "description": { + "description": "__Read-only__ Additional details regarding the Beta Program.", + "example": "This is an open public beta for an example feature.", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "ended": { + "description": "__Filterable__, __Read-only__ The date-time that the Beta Program ended.\n\n`null` indicates that the Beta Program is ongoing.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 5, + "x-linode-filterable": true + }, + "enrolled": { + "description": "__Filterable__, __Read-only__ The date-time of Account enrollment to the Beta Program.", + "example": "2023-09-11T00:00:00", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + }, + "id": { + "description": "The unique identifier of the Beta Program.", + "example": "example_open", + "type": "string", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__, __Read-only__ The name of the Beta Program.", + "example": "Example Open Beta", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "started": { + "description": "__Filterable__, __Read-only__ The start date-time of the Beta Program.", + "example": "2023-07-11T00:00:00", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/beta-program-enrolled.yaml" + } + }, + "type": "array" + } + }, + "type": "object" + } + ], + "x-akamai": { + "file-path": "schemas/added-get-enrolled-beta-programs-200.yaml" + } + }, + "added-get-entity-transfers-200": { + "allOf": [ + { + "additionalProperties": false, + "description": "An envelope for paginated response. When accessing a collection through a GET endpoint, the results are wrapped in this envelope which includes metadata about those results. Results are presented within a `data` array. See [Pagination](https://techdocs.akamai.com/linode-api/reference/pagination) for more information.", + "properties": { + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/pagination-envelope.yaml" + } + }, + { + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "An object representing an Entity Transfer.", + "properties": { + "created": { + "description": "When this transfer was created.", + "example": "2021-02-11T16:37:03", + "format": "date-time", + "type": "string" + }, + "entities": { + "additionalProperties": false, + "description": "A collection of the entities to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + }, + "expiry": { + "description": "When this transfer expires. Transfers will automatically expire 24 hours after creation.", + "example": "2021-02-12T16:37:03", + "format": "date-time", + "type": "string", + "x-linode-cli-display": 3 + }, + "is_sender": { + "description": "__Filterable__ If the requesting account created this transfer.", + "example": true, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "status": { + "description": "__Filterable__ The status of the transfer request:\n\n`accepted`: The transfer has been accepted by another user and is currently in progress. Transfers can take up to 3 hours to complete.\n`canceled`: The transfer has been canceled by the sender.\n`completed`: The transfer has completed successfully.\n`failed`: The transfer has failed after initiation.\n`pending`: The transfer is ready to be accepted.\n`stale`: The transfer has exceeded its expiration date. It can no longer be accepted or canceled.", + "enum": [ + "accepted", + "canceled", + "completed", + "failed", + "pending", + "stale" + ], + "example": "pending", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-color": { + "accepted": "yellow", + "canceled": "red", + "completed": "green", + "default_": "white", + "failed": "red", + "pending": "yellow", + "stale": "red" + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "token": { + "description": "The token used to identify and accept or cancel this transfer.", + "example": "123E4567-E89B-12D3-A456-426614174000", + "format": "uuid", + "type": "string", + "x-linode-cli-display": 1 + }, + "updated": { + "description": "When this transfer was last updated.", + "example": "2021-02-11T16:37:03", + "format": "date-time", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/entity-transfer.yaml" + } + }, + "type": "array" + } + } + } + ], + "x-akamai": { + "file-path": "schemas/added-get-entity-transfers-200.yaml" + } + }, + "added-get-events-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "A collection of Event objects. An Event is an action taken against an entity related to your Account. For example, booting a Linode would create an Event. The Events returned depends on your grants.", + "properties": { + "action": { + "description": "__Filterable__, __Read-only__ The action that caused this Event. New actions may be added in the future.", + "enum": [ + "account_update", + "account_settings_update", + "backups_enable", + "backups_cancel", + "backups_restore", + "community_question_reply", + "community_like", + "credit_card_updated", + "disk_create", + "disk_delete", + "disk_update", + "disk_duplicate", + "disk_imagize", + "disk_resize", + "dns_record_create", + "dns_record_delete", + "dns_record_update", + "dns_zone_create", + "dns_zone_delete", + "dns_zone_import", + "dns_zone_update", + "entity_transfer_accept", + "entity_transfer_cancel", + "entity_transfer_create", + "entity_transfer_fail", + "entity_transfer_stale", + "firewall_apply", + "firewall_create", + "firewall_delete", + "firewall_disable", + "firewall_enable", + "firewall_update", + "firewall_device_add", + "firewall_device_remove", + "host_reboot", + "image_delete", + "image_update", + "image_upload", + "ipaddress_update", + "lassie_reboot", + "lish_boot", + "linode_addip", + "linode_boot", + "linode_clone", + "linode_create", + "linode_delete", + "linode_update", + "linode_deleteip", + "linode_migrate", + "linode_migrate_datacenter", + "linode_migrate_datacenter_create", + "linode_mutate", + "linode_mutate_create", + "linode_reboot", + "linode_rebuild", + "linode_resize", + "linode_resize_create", + "linode_shutdown", + "linode_snapshot", + "linode_config_create", + "linode_config_delete", + "linode_config_update", + "lke_cluster_create", + "lke_cluster_update", + "lke_cluster_delete", + "lke_cluster_recycle", + "lke_cluster_regenerate", + "lke_node_create", + "lke_node_delete", + "lke_node_recycle", + "lke_pool_create", + "lke_pool_delete", + "lke_pool_recycle", + "lke_kubeconfig_regenerate", + "lke_token_rotate", + "longviewclient_create", + "longviewclient_delete", + "longviewclient_update", + "managed_disabled", + "managed_enabled", + "managed_service_create", + "managed_service_delete", + "nodebalancer_create", + "nodebalancer_delete", + "nodebalancer_update", + "nodebalancer_config_create", + "nodebalancer_config_delete", + "nodebalancer_config_update", + "nodebalancer_node_create", + "nodebalancer_node_delete", + "nodebalancer_node_update", + "oauth_client_create", + "oauth_client_delete", + "oauth_client_secret_reset", + "oauth_client_update", + "obj_access_key_create", + "obj_access_key_delete", + "obj_access_key_update", + "password_reset", + "payment_method_add", + "payment_submitted", + "placement_group_assign", + "placement_group_became_compliant", + "placement_group_became_non_compliant", + "placement_group_create", + "placement_group_delete", + "placement_group_unassign", + "placement_group_update", + "profile_update", + "stackscript_create", + "stackscript_delete", + "stackscript_update", + "stackscript_publicize", + "stackscript_revise", + "subnet_create", + "subnet_delete", + "subnet_update", + "tag_create", + "tag_delete", + "tax_id_valid", + "tax_id_invalid", + "tfa_disabled", + "tfa_enabled", + "ticket_attachment_upload", + "ticket_create", + "ticket_update", + "token_create", + "token_delete", + "token_update", + "user_create", + "user_update", + "user_delete", + "user_ssh_key_add", + "user_ssh_key_delete", + "user_ssh_key_update", + "vlan_attach", + "vlan_detach", + "volume_attach", + "volume_clone", + "volume_create", + "volume_delete", + "volume_update", + "volume_detach", + "volume_resize", + "vpc_create", + "vpc_delete", + "vpc_update" + ], + "example": "ticket_create", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3, + "x-linode-filterable": true + }, + "created": { + "description": "__Filterable__, __Read-only__ When this Event was created.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + }, + "duration": { + "description": "__Read-only__ The total duration in seconds that it takes for the Event to complete.", + "example": 300.56, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 7 + }, + "entity": { + "additionalProperties": false, + "description": "__Read-only__ Detailed information about the Event's entity, including ID, type, label, and URL used to access it.", + "properties": { + "id": { + "description": "__Filterable__ The unique ID for an Event's entity.\n\nSome Event entities do not have IDs associated with them, so they will not be returned when filtering by ID. These Events include:\n\n - `account`\n - `profile`\n\nEntities for some Events are assigned the ID of the Linode they correspond to. When filtering by ID for these Events, use the corresponding Linode's ID. These Events include:\n\n - `disks`\n - `backups`\n\nTag Events use a tag's name for the entity ID field. When filtering by ID for tag Events, supply the name of the tag.", + "example": 11111, + "type": "integer", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "label": { + "description": "The current label of this object. The label may reflect changes that occur with this Event.", + "example": "Problem booting my Linode", + "type": "string", + "x-linode-cli-display": 5 + }, + "type": { + "description": "__Filterable__, __Read-only__ The type of entity that is being referenced by the Event.", + "enum": [ + "account", + "backups", + "community", + "disks", + "domain", + "entity_transfer", + "firewall", + "image", + "ipaddress", + "linode", + "longview", + "loadbalancer", + "managed_service", + "nodebalancer", + "oauth_client", + "profile", + "stackscript", + "tag", + "ticket", + "token", + "user", + "user_ssh_key", + "volume" + ], + "example": "ticket", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "url": { + "description": "The URL where you can access the object this Event is for. If a relative URL, it is relative to the domain you retrieved the Event from.", + "example": "/v4/support/tickets/11111", + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "id": { + "description": "__Filterable__, __Read-only__ The unique ID of this Event.", + "example": 123, + "readOnly": true, + "type": "integer", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "message": { + "description": "Provides additional information about the event. Additional information may include, but is not limited to, a more detailed representation of events which can help diagnose non-obvious failures.", + "example": "None", + "nullable": true, + "type": "string", + "x-linode-cli-display": 9 + }, + "percent_complete": { + "description": "__Read-only__ A percentage estimating the amount of time remaining for an Event. Returns `null` for notification events.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "integer" + }, + "rate": { + "description": "__Read-only__ The rate of completion of the Event. Only some Events will return rate; for example, migration and resize Events.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "string" + }, + "read": { + "description": "__Filterable__, __Read-only__ If this Event has been read.", + "example": true, + "readOnly": true, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "secondary_entity": { + "additionalProperties": false, + "description": "__Read-only__ Detailed information about the Event's secondary entity, which provides additional information for events such as, but not limited to, `linode_boot`, `linode_reboot`, `linode_create`, and `linode_clone` Event actions.", + "properties": { + "id": { + "description": "The ID of the object that is the secondary entity.", + "example": "linode/debian9", + "type": "string" + }, + "label": { + "description": "The label of this object.", + "example": "linode1234", + "type": "string" + }, + "type": { + "description": "__Read-only__ The type of entity that is being referenced by the Event.", + "example": "linode", + "readOnly": true, + "type": "string" + }, + "url": { + "description": "The URL where you can access the object this Event is for. If a relative URL, it is relative to the domain you retrieved the Event from.", + "example": "/v4/linode/instances/1234", + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "seen": { + "description": "__Read-only__ If this Event has been seen.", + "example": true, + "readOnly": true, + "type": "boolean" + }, + "status": { + "description": "__Read-only__ The current status of this Event.", + "enum": [ + "failed", + "finished", + "notification", + "scheduled", + "started" + ], + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "default_": "white", + "failed": "red", + "finished": "green", + "started": "yellow" + }, + "x-linode-cli-display": 8 + }, + "time_remaining": { + "description": "__Read-only__ The estimated time remaining until the completion of this Event. This value is only returned for some in-progress migration events. For all other in-progress events, the `percent_complete` attribute will indicate about how much more work is to be done.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "string" + }, + "username": { + "description": "__Read-only__ The username of the User who caused the Event.", + "example": "exampleUser", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/event.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-events-200.yaml" + } + }, + "added-get-invoice-items-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "An InvoiceItem object.", + "properties": { + "amount": { + "description": "__Read-only__ The price, in US dollars, of the Invoice Item. Equal to the unit price multiplied by quantity.", + "example": 20.2, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "from": { + "description": "__Read-only__ The date the Invoice Item started, based on month.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "label": { + "description": "__Read-only__ The Invoice Item's display label.", + "example": "Linode 123", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "quantity": { + "description": "__Read-only__ The quantity of this Item for the specified Invoice.", + "example": 4, + "readOnly": true, + "type": "integer" + }, + "region": { + "description": "__Read-only__ The ID of the applicable Region associated with this Invoice Item.\n\n`null` if there is no applicable Region.", + "example": "us-west", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 7 + }, + "tax": { + "description": "__Read-only__ The amount of tax levied on this Item in US Dollars.", + "example": 1.25, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 5 + }, + "to": { + "description": "__Read-only__ The date the Invoice Item ended, based on month.", + "example": "2018-01-31T11:59:59", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "total": { + "description": "__Read-only__ The price of this Item after taxes in US Dollars.", + "example": 21.45, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 6 + }, + "type": { + "description": "__Read-only__ The type of service, ether `hourly` or `misc`.", + "enum": [ + "hourly", + "misc" + ], + "example": "hourly", + "readOnly": true, + "type": "string" + }, + "unit_price": { + "description": "__Read-only__ The monthly service fee in US Dollars for this Item.", + "example": 5.05, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/invoice-item.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-invoice-items-200.yaml" + } + }, + "added-get-invoices-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "Account Invoice object.", + "properties": { + "billing_source": { + "description": "__Filterable__, __Read-only__ `akamai`: This Invoice was generated according to the terms of an agreement between the customer and Akamai.\n\n`linode`: This Invoice was generated according to the default terms, prices, and discounts.", + "enum": [ + "akamai", + "linode" + ], + "example": "linode", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3.5, + "x-linode-filterable": true + }, + "date": { + "description": "__Filterable__, __Read-only__ When this Invoice was generated.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "id": { + "description": "__Read-only__ The Invoice's unique ID.", + "example": 123, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__, __Read-only__ The Invoice's display label.", + "example": "Invoice", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3, + "x-linode-filterable": true + }, + "subtotal": { + "description": "__Read-only__ The amount of the Invoice before taxes in US Dollars.", + "example": 120.25, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "tax": { + "description": "__Read-only__ The amount of tax levied on the Invoice in US Dollars.", + "example": 12.25, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 5 + }, + "tax_summary": { + "description": "__Read-only__ The amount of tax broken down into subtotals by source.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "The source of this tax subtotal.", + "example": "PA STATE TAX", + "type": "string" + }, + "tax": { + "description": "The amount of tax subtotal attributable to this source.", + "example": 12.25, + "type": "number" + } + }, + "type": "object" + }, + "readOnly": true, + "type": "array" + }, + "total": { + "description": "__Filterable__, __Read-only__ The amount of the Invoice after taxes in US Dollars.", + "example": 132.5, + "readOnly": true, + "type": "number", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/invoice.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-invoices-200.yaml" + } + }, + "added-get-maintenance-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "Information about maintenance affecting an entity.", + "properties": { + "entity": { + "additionalProperties": false, + "description": "The entity being affected by maintenance.", + "properties": { + "id": { + "description": "The id of the entity being affected by maintenance.", + "example": 1234, + "type": "number" + }, + "label": { + "description": "The label of the entity being affected by maintenance.", + "example": "demo-linode", + "type": "string" + }, + "type": { + "description": "The type of entity.", + "example": "Linode", + "type": "string" + }, + "url": { + "description": "The API endpoint prefix to use in combination with the entity id to find specific information about the entity.", + "example": "https://api.linode.com/v4/linode/instances/{linodeId}", + "type": "string" + } + }, + "type": "object" + }, + "reason": { + "description": "The reason maintenance is being performed.", + "example": "This maintenance will allow us to update the BIOS on the host's motherboard.", + "type": "string" + }, + "status": { + "description": "__Filterable__ The maintenance status.\n\nMaintenance progresses in the following sequence: pending, started, then completed.", + "enum": [ + "completed", + "pending", + "started" + ], + "example": "started", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "type": { + "description": "__Filterable__ The type of maintenance.", + "enum": [ + "reboot", + "cold_migration", + "live_migration" + ], + "example": "reboot", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "when": { + "description": "__Filterable__ When the maintenance will begin.\n\n[Filterable](https://techdocs.akamai.com/linode-api/reference/filtering-and-sorting) with the following parameters:\n\n- A single value in date-time string format (`%Y-%m-%dT%H:%M:%S`), which returns only matches to that value.\n\n- A dictionary containing pairs of inequality operator string keys (`+or`, `+gt`, `+gte`, `+lt`, `+lte`, or `+neq`) and single date-time string format values (`%Y-%m-%dT%H:%M:%S`). `+or` accepts an array of values that may consist of single date-time strings or dictionaries of inequality operator pairs.", + "example": "2020-07-09T00:01:01", + "format": "date-time", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/maintenance.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-maintenance-200.yaml" + } + }, + "added-get-notifications-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "An important, often time-sensitive item related to your account.", + "properties": { + "body": { + "description": "__Read-only__ A full description of this notification, in markdown format. Not all notifications include a `body`.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "string" + }, + "entity": { + "additionalProperties": false, + "description": "__Read-only__ Detailed information about the notification.", + "properties": { + "id": { + "description": "The unique ID of the notification's entity, based on the entity type. Returns `null` for an `account` or `promotion` entity.", + "example": 3456, + "nullable": true, + "type": "integer" + }, + "label": { + "description": "The current label for this notification's entity.\n\nReturns `null` for the following entity types:\n\n- `entity_transfer`\n- `promotion`\n- `region`", + "example": "Linode not booting.", + "nullable": true, + "type": "string" + }, + "type": { + "description": "The type of entity this is related to.", + "enum": [ + "account", + "entity_transfer", + "linode", + "loadbalancers", + "nodebalancer", + "promotion", + "region", + "ticket", + "volume" + ], + "example": "ticket", + "type": "string" + }, + "url": { + "description": "The URL where you can access the notification's object. The URL is relative to the domain where you retrieved the notification. This value is `null` for the `promotion` entity type.", + "example": "/support/tickets/3456", + "nullable": true, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "label": { + "description": "__Read-only__ A short description of this notification.", + "example": "You have an important ticket open!", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "message": { + "description": "__Read-only__ A human-readable description of the notification.", + "example": "You have an important ticket open!", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "severity": { + "description": "__Read-only__ The severity of this notification. This field determines how prominently the notification is displayed and the color of the display text.", + "enum": [ + "minor", + "major", + "critical" + ], + "example": "major", + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "critical": "b", + "default_": "white", + "minor": "blue" + }, + "x-linode-cli-display": 3 + }, + "type": { + "description": "__Read-only__ The type of notification.", + "enum": [ + "migration_scheduled", + "migration_imminent", + "migration_pending", + "reboot_scheduled", + "outage", + "payment_due", + "ticket_important", + "ticket_abuse", + "notice", + "maintenance", + "promotion", + "tax_id_verifying" + ], + "example": "ticket_important", + "readOnly": true, + "type": "string" + }, + "until": { + "description": "__Read-only__ If this notification has a duration, this is when the event or action will complete. For example, if there's scheduled maintenance for one of our systems, `until` represents the end of the maintenance window.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "None": "black", + "default_": "white" + }, + "x-linode-cli-display": 5 + }, + "when": { + "description": "__Read-only__ If this notification is for an event in the future, this specifies when the action occurs. For example, if a compute instance needs to migrate in response to a security advisory, this field sets the approximate time the compute instance will be taken offline for migration.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "None": "black", + "default_": "white" + }, + "x-linode-cli-display": 4 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/notification.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-notifications-200.yaml" + } + }, + "added-get-payment-methods-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "Payment Method Response Object.", + "properties": { + "created": { + "description": "__Read-only__ When the Payment Method was added to the Account.", + "example": "2018-01-15T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "data": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Credit card information.", + "properties": { + "card_type": { + "description": "__Read-only__ The type of credit card.", + "example": "Discover", + "readOnly": true, + "type": "string" + }, + "expiry": { + "description": "__Read-only__ The expiration month and year of the credit card.", + "example": "06/2022", + "format": "MM/YYYY", + "readOnly": true, + "type": "string" + }, + "last_four": { + "description": "__Read-only__ The last four digits of the credit card number.", + "example": "1234", + "readOnly": true, + "type": "string" + } + }, + "title": "Credit card", + "type": "object", + "x-akamai": { + "file-path": "schemas/credit-card-data.yaml" + }, + "x-linode-ref-name": "Credit Card" + }, + { + "additionalProperties": false, + "description": "Google Pay information.", + "properties": { + "card_type": { + "description": "__Read-only__ The type of credit card.", + "example": "Discover", + "readOnly": true, + "type": "string" + }, + "expiry": { + "description": "__Read-only__ The expiration month and year of the credit card.", + "example": "06/2022", + "format": "MM/YYYY", + "readOnly": true, + "type": "string" + }, + "last_four": { + "description": "__Read-only__ The last four digits of the credit card number.", + "example": "1234", + "readOnly": true, + "type": "string" + } + }, + "title": "Google Pay", + "type": "object", + "x-akamai": { + "file-path": "schemas/google-pay-data.yaml" + }, + "x-linode-ref-name": "Google Pay" + }, + { + "additionalProperties": false, + "description": "PayPal information.", + "properties": { + "email": { + "description": "__Read-only__ The email address associated with your PayPal account.", + "example": "example@linode.com", + "readOnly": true, + "type": "string" + }, + "paypal_id": { + "description": "__Read-only__ PayPal Merchant ID associated with your PayPal account.", + "example": "ABC1234567890", + "readOnly": true, + "type": "string" + } + }, + "title": "Paypal", + "type": "object", + "x-akamai": { + "file-path": "schemas/paypal-data.yaml" + }, + "x-linode-ref-name": "Paypal" + } + ], + "x-linode-cli-display": 4, + "x-linode-cli-format": "json" + }, + "id": { + "description": "The unique ID of this Payment Method.", + "example": 123, + "type": "integer", + "x-linode-cli-display": 1 + }, + "is_default": { + "description": "Whether this Payment Method is the default method for automatically processing service charges.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "type": { + "description": "The type of Payment Method.", + "enum": [ + "credit_card", + "google_pay", + "paypal" + ], + "example": "credit_card", + "type": "string", + "x-linode-cli-display": 2 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/payment-method.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-payment-methods-200.yaml" + } + }, + "added-get-payments-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "Payment object response.", + "properties": { + "date": { + "description": "__Read-only__ When the Payment was made.", + "example": "2018-01-15T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "id": { + "description": "__Read-only__ The unique ID of the Payment.", + "example": 123, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "usd": { + "description": "__Read-only__ The amount, in US dollars, of the Payment.", + "example": "120.50", + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 3 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/payment.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-payments-200.yaml" + } + }, + "added-get-service-transfers-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "additionalProperties": false, + "description": "An object representing a Service Transfer.", + "properties": { + "created": { + "description": "When this transfer was created.", + "example": "2021-02-11T16:37:03", + "format": "date-time", + "type": "string" + }, + "entities": { + "additionalProperties": false, + "description": "A collection of the services to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + }, + "expiry": { + "description": "When this transfer expires. Transfers will automatically expire 24 hours after creation.", + "example": "2021-02-12T16:37:03", + "format": "date-time", + "type": "string", + "x-linode-cli-display": 3 + }, + "is_sender": { + "description": "__Filterable__ If the requesting account created this transfer.", + "example": true, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "status": { + "description": "__Filterable__ The status of the transfer request.\n\n`accepted`: The transfer has been accepted by another user and is currently in progress.\nTransfers can take up to 3 hours to complete.\n\n`canceled`: The transfer has been canceled by the sender.\n\n`completed`: The transfer has completed successfully.\n\n`failed`: The transfer has failed after initiation.\n\n`pending`: The transfer is ready to be accepted.\n\n`stale`: The transfer has exceeded its expiration date. It can no longer be accepted or\ncanceled.", + "enum": [ + "accepted", + "canceled", + "completed", + "failed", + "pending", + "stale" + ], + "example": "pending", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-color": { + "accepted": "yellow", + "canceled": "red", + "completed": "green", + "default_": "white", + "failed": "red", + "pending": "yellow", + "stale": "red" + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "token": { + "description": "The token used to identify and accept or cancel this transfer.", + "example": "123E4567-E89B-12D3-A456-426614174000", + "format": "uuid", + "type": "string", + "x-linode-cli-display": 1 + }, + "updated": { + "description": "When this transfer was last updated.", + "example": "2021-02-11T16:37:03", + "format": "date-time", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/service-transfer.yaml" + } + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-service-transfers-200.yaml" + } + }, + "added-get-user-200": { + "allOf": [ + { + "additionalProperties": false, + "description": "A user on your account. Unrestricted users can log in and access information about your account, while restricted users may only access entities or perform actions they've been granted access to.", + "properties": { + "email": { + "description": "This user's email address. Akamai uses this address for account management communications.", + "example": "example_user@linode.com", + "format": "email", + "type": "string", + "x-linode-cli-display": 2 + }, + "last_login": { + "additionalProperties": false, + "description": "__Read-only__ Details on this user's last login attempt. Returned as `null` if this user hasn't attempted a login since it was created. You can run the [List user logins](https://techdocs.akamai.com/linode-api/reference/get-account-logins) operation for additional login information.", + "nullable": true, + "properties": { + "login_datetime": { + "description": "__Read-only__ The date and time of this user's most recent login attempt.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The result of this user's most recent login attempt.", + "enum": [ + "successful", + "failed" + ], + "example": "successful", + "readOnly": true, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "password_created": { + "description": "__Read-only__ When this user's current password was created. You initially create a password during the account sign-up process, and you can update it using the [Reset Password](https://login.linode.com/forgot/password) webpage. Returned as `null` if this user doesn't have a password set.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string" + }, + "restricted": { + "description": "If `true`, this user needs specific access granted to perform actions or access entities on your account. Run [List a user's grants](https://techdocs.akamai.com/linode-api/reference/get-user-grants) for details on how to configure grants for a restricted user.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "ssh_keys": { + "description": "__Read-only__ A list of the labels for SSH keys added by this user. Users can add keys with the [Add an SSH key](https://techdocs.akamai.com/linode-api/reference/post-add-ssh-key) operation. These keys are deployed when this user is included in the `authorized_users` field of the following requests:\n\n- [Create a Linode](https://techdocs.akamai.com/linode-api/reference/post-linode-instance)\n\n- [Rebuild a Linode](https://techdocs.akamai.com/linode-api/reference/post-rebuild-linode-instance)\n\n- [Create a disk](https://techdocs.akamai.com/linode-api/reference/post-add-linode-disk)", + "example": [ + "home-pc", + "laptop" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "tfa_enabled": { + "description": "__Read-only__ Whether this user has Two Factor Authentication (TFA) enabled. Run the [Create a two factor secret](https://techdocs.akamai.com/linode-api/reference/post-tfa-enable) operation to enable TFA.", + "example": true, + "readOnly": true, + "type": "boolean" + }, + "username": { + "description": "__Filterable__ The name of this user. This user needs to use this value to log in. It may also display alongside actions this user performs, including events or public StackScripts.", + "example": "example_user", + "maxLength": 32, + "minLength": 3, + "pattern": "^[a-zA-Z0-9]((?![_-]{2,})[a-zA-Z0-9-_])+[a-zA-Z0-9]$", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "verified_phone_number": { + "description": "__Read-only__ The [verified](https://techdocs.akamai.com/linode-api/reference/post-profile-phone-number-verify) phone number for this user profile. Returned as `null` if the user doesn't have a verified phone number.", + "example": "+5555555555", + "format": "phone", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user.yaml" + } + }, + { + "additionalProperties": false, + "description": "The type of user on an account. Mostly applies to the use of the parent and child accounts for Akamai partners functionality.", + "properties": { + "user_type": { + "description": "__Read-only__ If the user belongs to a [parent or child account](https://www.linode.com/docs/guides/parent-child-accounts/) relationship, this defines the user type in the respective account. Possible values include:\n\n- `parent`. This is a user in an Akamai partner account. Akamai partners have a contractural relationship with their end customers, to sell Akamai services. This user can either have full access (a parent account admin user) or limited access. Limited users don't have access to manage child accounts, but they can be granted this access by an admin user.\n\n- `child`. This is an Akamai partner's end customer user, in a child account. A child user can have either full or limited access. Full access lets the user manage other child users and the proxy user in a child account.\n\n- `proxy`. This is a user on a child account that gives parent account users access to that child account. A parent account user with the `child_account_access` grant can [Create a proxy user token](https://techdocs.akamai.com/linode-api/reference/post-child-account-token) from the parent account. The parent user can use this token to run API operations from the child account, as if they were a child user.\n\n- `default`. This applies to all regular, non-parent-child account users.", + "enum": [ + "parent", + "child", + "proxy", + "default" + ], + "example": "parent", + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user-type.yaml" + } + } + ], + "x-akamai": { + "file-path": "schemas/added-get-user-200.yaml" + } + }, + "added-get-users-200": { + "additionalProperties": false, + "properties": { + "data": { + "items": { + "allOf": [ + { + "additionalProperties": false, + "description": "A user on your account. Unrestricted users can log in and access information about your account, while restricted users may only access entities or perform actions they've been granted access to.", + "properties": { + "email": { + "description": "This user's email address. Akamai uses this address for account management communications.", + "example": "example_user@linode.com", + "format": "email", + "type": "string", + "x-linode-cli-display": 2 + }, + "last_login": { + "additionalProperties": false, + "description": "__Read-only__ Details on this user's last login attempt. Returned as `null` if this user hasn't attempted a login since it was created. You can run the [List user logins](https://techdocs.akamai.com/linode-api/reference/get-account-logins) operation for additional login information.", + "nullable": true, + "properties": { + "login_datetime": { + "description": "__Read-only__ The date and time of this user's most recent login attempt.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The result of this user's most recent login attempt.", + "enum": [ + "successful", + "failed" + ], + "example": "successful", + "readOnly": true, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "password_created": { + "description": "__Read-only__ When this user's current password was created. You initially create a password during the account sign-up process, and you can update it using the [Reset Password](https://login.linode.com/forgot/password) webpage. Returned as `null` if this user doesn't have a password set.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string" + }, + "restricted": { + "description": "If `true`, this user needs specific access granted to perform actions or access entities on your account. Run [List a user's grants](https://techdocs.akamai.com/linode-api/reference/get-user-grants) for details on how to configure grants for a restricted user.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "ssh_keys": { + "description": "__Read-only__ A list of the labels for SSH keys added by this user. Users can add keys with the [Add an SSH key](https://techdocs.akamai.com/linode-api/reference/post-add-ssh-key) operation. These keys are deployed when this user is included in the `authorized_users` field of the following requests:\n\n- [Create a Linode](https://techdocs.akamai.com/linode-api/reference/post-linode-instance)\n\n- [Rebuild a Linode](https://techdocs.akamai.com/linode-api/reference/post-rebuild-linode-instance)\n\n- [Create a disk](https://techdocs.akamai.com/linode-api/reference/post-add-linode-disk)", + "example": [ + "home-pc", + "laptop" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "tfa_enabled": { + "description": "__Read-only__ Whether this user has Two Factor Authentication (TFA) enabled. Run the [Create a two factor secret](https://techdocs.akamai.com/linode-api/reference/post-tfa-enable) operation to enable TFA.", + "example": true, + "readOnly": true, + "type": "boolean" + }, + "username": { + "description": "__Filterable__ The name of this user. This user needs to use this value to log in. It may also display alongside actions this user performs, including events or public StackScripts.", + "example": "example_user", + "maxLength": 32, + "minLength": 3, + "pattern": "^[a-zA-Z0-9]((?![_-]{2,})[a-zA-Z0-9-_])+[a-zA-Z0-9]$", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "verified_phone_number": { + "description": "__Read-only__ The [verified](https://techdocs.akamai.com/linode-api/reference/post-profile-phone-number-verify) phone number for this user profile. Returned as `null` if the user doesn't have a verified phone number.", + "example": "+5555555555", + "format": "phone", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user.yaml" + } + }, + { + "additionalProperties": false, + "description": "The type of user on an account. Mostly applies to the use of the parent and child accounts for Akamai partners functionality.", + "properties": { + "user_type": { + "description": "__Read-only__ If the user belongs to a [parent or child account](https://www.linode.com/docs/guides/parent-child-accounts/) relationship, this defines the user type in the respective account. Possible values include:\n\n- `parent`. This is a user in an Akamai partner account. Akamai partners have a contractural relationship with their end customers, to sell Akamai services. This user can either have full access (a parent account admin user) or limited access. Limited users don't have access to manage child accounts, but they can be granted this access by an admin user.\n\n- `child`. This is an Akamai partner's end customer user, in a child account. A child user can have either full or limited access. Full access lets the user manage other child users and the proxy user in a child account.\n\n- `proxy`. This is a user on a child account that gives parent account users access to that child account. A parent account user with the `child_account_access` grant can [Create a proxy user token](https://techdocs.akamai.com/linode-api/reference/post-child-account-token) from the parent account. The parent user can use this token to run API operations from the child account, as if they were a child user.\n\n- `default`. This applies to all regular, non-parent-child account users.", + "enum": [ + "parent", + "child", + "proxy", + "default" + ], + "example": "parent", + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user-type.yaml" + } + } + ] + }, + "type": "array" + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-get-users-200.yaml" + } + }, + "added-post-beta-program": { + "additionalProperties": false, + "description": "The Beta Program ID to enroll in for your Account.", + "properties": { + "id": { + "description": "The unique identifier of the Beta Program.", + "example": "example_open", + "type": "string", + "x-linode-cli-display": 1 + } + }, + "required": [ + "id" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-beta-program.yaml" + } + }, + "added-post-cancel-account": { + "additionalProperties": false, + "properties": { + "comments": { + "description": "Any reason for cancelling the account, and any other comments you might have about your Linode service.", + "example": "I'm consolidating multiple accounts into one.", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-cancel-account.yaml" + } + }, + "added-post-cancel-account-200": { + "additionalProperties": false, + "example": { + "survey_link": "https://alinktothesurvey.com" + }, + "properties": { + "survey_link": { + "description": "A link to Linode's exit survey.", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-cancel-account-200.yaml" + } + }, + "added-post-cancel-account-409": { + "additionalProperties": false, + "properties": { + "errors": { + "items": { + "additionalProperties": false, + "properties": { + "reason": { + "description": "A string explaining that the account could not be canceled because there is an outstanding balance on the account that must be paid first.", + "example": "We were unable to charge your credit card for services rendered. We cannot cancel this account until the balance has been paid.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-cancel-account-409.yaml" + } + }, + "added-post-client": { + "allOf": [ + { + "additionalProperties": false, + "description": "A third-party application registered to Linode that users may log into with their Linode account through our authentication server at [login.linode.com](https://login.linode.com). Using an OAuth Client, a third-party developer may be given access to some, or all, of a User's account for the purposes of their application.", + "properties": { + "id": { + "description": "__Read-only__ The OAuth Client ID. This is used to identify the client, and is a publicly known value (it is not a secret).", + "example": "2737bf16b39ab5d7b4a1", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__ The name of this application. This will be presented to users when they are asked to grant it access to their Account.", + "example": "Test_Client_1", + "maxLength": 512, + "minLength": 1, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "public": { + "default": false, + "description": "__Filterable__ If this is a public or private OAuth Client. Public clients have a slightly different authentication workflow than private clients. See the [OAuth spec](https://oauth.net/2/) for more details.", + "example": false, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "redirect_uri": { + "description": "The location a successful log in from [login.linode.com](https://login.linode.com) should be redirected to for this client. The receiver of this redirect should be ready to accept an OAuth exchange code and finish the OAuth exchange.", + "example": "https://example.org/oauth/callback", + "format": "url", + "type": "string", + "x-linode-cli-display": 5 + }, + "secret": { + "description": "__Read-only__ The OAuth Client secret, used in the OAuth exchange. This is returned as `` except when an OAuth Client is created or its secret is reset. This is a secret, and should not be shared or disclosed publicly.", + "example": "", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The status of this application. `active` by default.", + "enum": [ + "active", + "disabled", + "suspended" + ], + "example": "active", + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "default_": "white", + "suspended": "red" + }, + "x-linode-cli-display": 3 + }, + "thumbnail_url": { + "description": "__Read-only__ The URL where this client's thumbnail may be viewed, or `null` if this client does not have a thumbnail set.", + "example": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", + "format": "url", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/oauth-client.yaml" + } + } + ], + "required": [ + "label", + "redirect_uri" + ], + "x-akamai": { + "file-path": "schemas/added-post-client.yaml" + } + }, + "added-post-entity-transfer": { + "additionalProperties": false, + "properties": { + "entities": { + "additionalProperties": false, + "description": "A collection of the entities to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + } + }, + "required": [ + "entities" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-entity-transfer.yaml" + } + }, + "added-post-pay-pal-payment-200": { + "additionalProperties": false, + "properties": { + "checkout_token": { + "description": "__Read-only__ The checkout token generated for this Payment.", + "example": "EC-1A2B3C4D5E6F7G8H9", + "readOnly": true, + "type": "string" + }, + "payment_id": { + "description": "The paypal-generated ID for this Payment. Used when authorizing the Payment in PayPal's interface.", + "example": "PAY-1234567890ABCDEFGHIJKLMN", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-pay-pal-payment-200.yaml" + } + }, + "added-post-payment": { + "additionalProperties": false, + "properties": { + "payment_method_id": { + "description": "The ID of the Payment Method to apply to the Payment.", + "example": 123, + "type": "integer" + }, + "usd": { + "description": "The amount in US Dollars of the Payment.\n\n- Can begin with or without `$`.\n- Commas (`,`) are not accepted.\n- Must end with a decimal expression, such as `.00` or `.99`.\n- Minimum: `$5.00` or the Account balance, whichever is lower.\n- Maximum: `$2000.00` or the Account balance up to `$50000.00`, whichever is greater.", + "example": "$120.50", + "pattern": "^\\$?\\d+\\.\\d{2}$", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-payment.yaml" + } + }, + "added-post-payment-method": { + "additionalProperties": false, + "description": "Payment Method Request Object.", + "properties": { + "data": { + "additionalProperties": false, + "description": "An object representing the credit card information you have on file with Linode to make Payments against your Account.", + "properties": { + "card_number": { + "description": "Your credit card number. No spaces or hyphens (`-`) allowed.", + "example": 4111111111111111, + "format": "digits", + "maxLength": 24, + "minLength": 14, + "type": "string" + }, + "cvv": { + "description": "CVV (Card Verification Value) of the credit card, typically found on the back of the card.", + "example": "123", + "format": "digits", + "maxLength": 4, + "minLength": 3, + "type": "string" + }, + "expiry_month": { + "description": "A value from 1-12 representing the expiration month of your credit card.\n\n - 1 = January\n - 2 = February\n - 3 = March\n - Etc.", + "example": 12, + "maximum": 12, + "minimum": 1, + "type": "integer" + }, + "expiry_year": { + "description": "A four-digit integer representing the expiration year of your credit card.\n\nThe combination of `expiry_month` and `expiry_year` must result in a month/year combination of the current month or in the future. An expiration date set in the past is invalid.", + "example": 2020, + "maxLength": 4, + "minLength": 4, + "type": "integer" + } + }, + "required": [ + "card_number", + "expiry_month", + "expiry_year", + "cvv" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/credit-card.yaml" + } + }, + "is_default": { + "description": "Whether this Payment Method is the default method for automatically processing service charges.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "type": { + "description": "The type of Payment Method.\n\nAlternative Payment Methods including Google Pay and PayPal can be added using the Cloud Manager. See the [Manage Payment Methods](https://www.linode.com/docs/products/platform/billing/guides/payment-methods/) guide\nfor details and instructions.", + "enum": [ + "credit_card" + ], + "example": "credit_card", + "type": "string" + } + }, + "required": [ + "type", + "data", + "is_default" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-payment-method.yaml" + } + }, + "added-post-promo-credit": { + "additionalProperties": false, + "properties": { + "promo_code": { + "description": "The Promo Code.", + "maxLength": 32, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "promo_code" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-promo-credit.yaml" + } + }, + "added-post-service-transfer": { + "additionalProperties": false, + "properties": { + "entities": { + "additionalProperties": false, + "description": "A collection of the services to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + } + }, + "required": [ + "entities" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/added-post-service-transfer.yaml" + } + }, + "added-post-user": { + "allOf": [ + { + "additionalProperties": false, + "description": "A user on your account. Unrestricted users can log in and access information about your account, while restricted users may only access entities or perform actions they've been granted access to.", + "properties": { + "email": { + "description": "This user's email address. Akamai uses this address for account management communications.", + "example": "example_user@linode.com", + "format": "email", + "type": "string", + "x-linode-cli-display": 2 + }, + "last_login": { + "additionalProperties": false, + "description": "__Read-only__ Details on this user's last login attempt. Returned as `null` if this user hasn't attempted a login since it was created. You can run the [List user logins](https://techdocs.akamai.com/linode-api/reference/get-account-logins) operation for additional login information.", + "nullable": true, + "properties": { + "login_datetime": { + "description": "__Read-only__ The date and time of this user's most recent login attempt.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The result of this user's most recent login attempt.", + "enum": [ + "successful", + "failed" + ], + "example": "successful", + "readOnly": true, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "password_created": { + "description": "__Read-only__ When this user's current password was created. You initially create a password during the account sign-up process, and you can update it using the [Reset Password](https://login.linode.com/forgot/password) webpage. Returned as `null` if this user doesn't have a password set.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string" + }, + "restricted": { + "description": "If `true`, this user needs specific access granted to perform actions or access entities on your account. Run [List a user's grants](https://techdocs.akamai.com/linode-api/reference/get-user-grants) for details on how to configure grants for a restricted user.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "ssh_keys": { + "description": "__Read-only__ A list of the labels for SSH keys added by this user. Users can add keys with the [Add an SSH key](https://techdocs.akamai.com/linode-api/reference/post-add-ssh-key) operation. These keys are deployed when this user is included in the `authorized_users` field of the following requests:\n\n- [Create a Linode](https://techdocs.akamai.com/linode-api/reference/post-linode-instance)\n\n- [Rebuild a Linode](https://techdocs.akamai.com/linode-api/reference/post-rebuild-linode-instance)\n\n- [Create a disk](https://techdocs.akamai.com/linode-api/reference/post-add-linode-disk)", + "example": [ + "home-pc", + "laptop" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "tfa_enabled": { + "description": "__Read-only__ Whether this user has Two Factor Authentication (TFA) enabled. Run the [Create a two factor secret](https://techdocs.akamai.com/linode-api/reference/post-tfa-enable) operation to enable TFA.", + "example": true, + "readOnly": true, + "type": "boolean" + }, + "username": { + "description": "__Filterable__ The name of this user. This user needs to use this value to log in. It may also display alongside actions this user performs, including events or public StackScripts.", + "example": "example_user", + "maxLength": 32, + "minLength": 3, + "pattern": "^[a-zA-Z0-9]((?![_-]{2,})[a-zA-Z0-9-_])+[a-zA-Z0-9]$", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "verified_phone_number": { + "description": "__Read-only__ The [verified](https://techdocs.akamai.com/linode-api/reference/post-profile-phone-number-verify) phone number for this user profile. Returned as `null` if the user doesn't have a verified phone number.", + "example": "+5555555555", + "format": "phone", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user.yaml" + } + } + ], + "required": [ + "username", + "email" + ], + "x-akamai": { + "file-path": "schemas/added-post-user.yaml" + } + }, + "added-put-user-200": { + "allOf": [ + { + "additionalProperties": false, + "description": "A user on your account. Unrestricted users can log in and access information about your account, while restricted users may only access entities or perform actions they've been granted access to.", + "properties": { + "email": { + "description": "This user's email address. Akamai uses this address for account management communications.", + "example": "example_user@linode.com", + "format": "email", + "type": "string", + "x-linode-cli-display": 2 + }, + "last_login": { + "additionalProperties": false, + "description": "__Read-only__ Details on this user's last login attempt. Returned as `null` if this user hasn't attempted a login since it was created. You can run the [List user logins](https://techdocs.akamai.com/linode-api/reference/get-account-logins) operation for additional login information.", + "nullable": true, + "properties": { + "login_datetime": { + "description": "__Read-only__ The date and time of this user's most recent login attempt.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The result of this user's most recent login attempt.", + "enum": [ + "successful", + "failed" + ], + "example": "successful", + "readOnly": true, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "password_created": { + "description": "__Read-only__ When this user's current password was created. You initially create a password during the account sign-up process, and you can update it using the [Reset Password](https://login.linode.com/forgot/password) webpage. Returned as `null` if this user doesn't have a password set.", + "example": "2018-01-01T01:01:01", + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string" + }, + "restricted": { + "description": "If `true`, this user needs specific access granted to perform actions or access entities on your account. Run [List a user's grants](https://techdocs.akamai.com/linode-api/reference/get-user-grants) for details on how to configure grants for a restricted user.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "ssh_keys": { + "description": "__Read-only__ A list of the labels for SSH keys added by this user. Users can add keys with the [Add an SSH key](https://techdocs.akamai.com/linode-api/reference/post-add-ssh-key) operation. These keys are deployed when this user is included in the `authorized_users` field of the following requests:\n\n- [Create a Linode](https://techdocs.akamai.com/linode-api/reference/post-linode-instance)\n\n- [Rebuild a Linode](https://techdocs.akamai.com/linode-api/reference/post-rebuild-linode-instance)\n\n- [Create a disk](https://techdocs.akamai.com/linode-api/reference/post-add-linode-disk)", + "example": [ + "home-pc", + "laptop" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "tfa_enabled": { + "description": "__Read-only__ Whether this user has Two Factor Authentication (TFA) enabled. Run the [Create a two factor secret](https://techdocs.akamai.com/linode-api/reference/post-tfa-enable) operation to enable TFA.", + "example": true, + "readOnly": true, + "type": "boolean" + }, + "username": { + "description": "__Filterable__ The name of this user. This user needs to use this value to log in. It may also display alongside actions this user performs, including events or public StackScripts.", + "example": "example_user", + "maxLength": 32, + "minLength": 3, + "pattern": "^[a-zA-Z0-9]((?![_-]{2,})[a-zA-Z0-9-_])+[a-zA-Z0-9]$", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "verified_phone_number": { + "description": "__Read-only__ The [verified](https://techdocs.akamai.com/linode-api/reference/post-profile-phone-number-verify) phone number for this user profile. Returned as `null` if the user doesn't have a verified phone number.", + "example": "+5555555555", + "format": "phone", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user.yaml" + } + }, + { + "additionalProperties": false, + "description": "The type of user on an account. Mostly applies to the use of the parent and child accounts for Akamai partners functionality.", + "properties": { + "user_type": { + "description": "__Read-only__ If the user belongs to a [parent or child account](https://www.linode.com/docs/guides/parent-child-accounts/) relationship, this defines the user type in the respective account. Possible values include:\n\n- `parent`. This is a user in an Akamai partner account. Akamai partners have a contractural relationship with their end customers, to sell Akamai services. This user can either have full access (a parent account admin user) or limited access. Limited users don't have access to manage child accounts, but they can be granted this access by an admin user.\n\n- `child`. This is an Akamai partner's end customer user, in a child account. A child user can have either full or limited access. Full access lets the user manage other child users and the proxy user in a child account.\n\n- `proxy`. This is a user on a child account that gives parent account users access to that child account. A parent account user with the `child_account_access` grant can [Create a proxy user token](https://techdocs.akamai.com/linode-api/reference/post-child-account-token) from the parent account. The parent user can use this token to run API operations from the child account, as if they were a child user.\n\n- `default`. This applies to all regular, non-parent-child account users.", + "enum": [ + "parent", + "child", + "proxy", + "default" + ], + "example": "parent", + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/user-type.yaml" + } + } + ], + "x-akamai": { + "file-path": "schemas/added-put-user-200.yaml" + } + }, + "agreements": { + "additionalProperties": false, + "description": "Acknowledgment status for agreements on your account. When acknowledging any agreements, set them to `true` and omit any remainders.", + "properties": { + "billing_agreement": { + "description": "Certain regions require that you share your tax identification number (TIN) with Akamai. When you do, you need to acknowledge Akamai's [privacy statement](https://www.akamai.com/legal/privacy-statement) agreement, in regards to its protection. When set to `true`, you've acknowledged this agreement.", + "type": "boolean" + }, + "eu_model": { + "description": "The acknowledgement status for the [cross-border data transfer](https://www.akamai.com/legal/compliance/privacy-trust-center/cross-border-data-transfer-statement) agreement.", + "example": true, + "type": "boolean" + }, + "master_service_agreement": { + "description": "The acknowledgement status for Akamai's [master service agreement](https://www.linode.com/legal-msa/).", + "example": true, + "type": "boolean" + }, + "privacy_policy": { + "description": "The acknowledgement status for Akamai's [privacy statement](https://www.akamai.com/legal/privacy-statement).", + "example": true, + "type": "boolean" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/agreements.yaml" + } + }, + "beta-program-enrolled": { + "additionalProperties": false, + "description": "An object representing an enrolled Beta Program for the Account.", + "properties": { + "description": { + "description": "__Read-only__ Additional details regarding the Beta Program.", + "example": "This is an open public beta for an example feature.", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "ended": { + "description": "__Filterable__, __Read-only__ The date-time that the Beta Program ended.\n\n`null` indicates that the Beta Program is ongoing.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 5, + "x-linode-filterable": true + }, + "enrolled": { + "description": "__Filterable__, __Read-only__ The date-time of Account enrollment to the Beta Program.", + "example": "2023-09-11T00:00:00", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + }, + "id": { + "description": "The unique identifier of the Beta Program.", + "example": "example_open", + "type": "string", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__, __Read-only__ The name of the Beta Program.", + "example": "Example Open Beta", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "started": { + "description": "__Filterable__, __Read-only__ The start date-time of the Beta Program.", + "example": "2023-07-11T00:00:00", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/beta-program-enrolled.yaml" + } + }, + "child-account": { + "additionalProperties": false, + "description": "Child account object.", + "properties": { + "active_since": { + "description": "__Read-only__ The activation date and time for the child account.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "address_1": { + "description": "__Filterable__ First line of this child account's billing address.", + "example": "123 Main Street", + "maxLength": 64, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "address_2": { + "description": "__Filterable__ Second line of this child account's billing address, if applicable.", + "example": "Suite A", + "maxLength": 64, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "balance": { + "description": "__Read-only__ This child account's balance, in US dollars.", + "example": 200, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "balance_uninvoiced": { + "description": "__Read-only__ This child account's current estimated invoice in US dollars. This is not your final invoice balance. Transfer charges are not included in the estimate.", + "example": 145, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "billing_source": { + "description": "__Read-only__ The source of service charges for this account, as determined by its relationship with Akamai. The API returns a value of `external` to describe a child account in a parent-child account environment.", + "enum": [ + "external" + ], + "example": "external", + "readOnly": true, + "type": "string" + }, + "capabilities": { + "description": "__Read-only__ A list of the capabilities the child account supports.", + "example": [ + "Linodes", + "NodeBalancers", + "Block Storage", + "Object Storage" + ], + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array" + }, + "city": { + "description": "__Filterable__ The city for this child account's billing address.", + "example": "San Diego", + "maxLength": 24, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "company": { + "description": "__Filterable__ The company name for the owner of this child account. It can't include any of these characters: `<` `>` `(` `)` `\"` `=`. You can't change this value yourself. We use it to create the proxy users that a parent account uses to access a child account. Talk to your account team if you need to change this value.", + "example": "Acme", + "maxLength": 128, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "country": { + "description": "__Filterable__ The two-letter ISO 3166 country code for this child account's billing address.", + "example": "US", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "credit_card": { + "additionalProperties": false, + "description": "__Read-only__ Information for the credit card you've assigned to this child account.", + "properties": { + "expiry": { + "description": "The expiration month and year of the credit card.", + "example": "11/2024", + "type": "string" + }, + "last_four": { + "description": "The last four digits of the credit card.", + "example": 1111, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "email": { + "description": "__Filterable__ The email address of the owner of this child account.", + "example": "john.smith@linode.com", + "maxLength": 128, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3, + "x-linode-filterable": true + }, + "euuid": { + "description": "__Read-only__ An external, unique identifier that Akamai assigned to the child account.", + "example": "A1BC2DEF-34GH-567I-J890KLMN12O34P56", + "format": "uuid", + "readOnly": true, + "type": "string" + }, + "first_name": { + "description": "__Filterable__ The first name of the owner of this child account. It can't include any of these characters: `<` `>` `(` `)` `\"` `=`.", + "example": "John", + "maxLength": 50, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "last_name": { + "description": "__Filterable__ The last name of the owner of this child account. It can't include any of these characters: `<` `>` `(` `)` `\"` `=`.", + "example": "Smith", + "maxLength": 50, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "phone": { + "description": "__Filterable__ The phone number for the owner of this child account.", + "example": "858-555-1212", + "maxLength": 32, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "state": { + "description": "__Filterable__ The state or province for the billing address (`address_1` and `address_2, if applicable`). If in the United States (US) or Canada (CA), this is the two-letter ISO 3166 State or Province code.\n\n> \ud83d\udcd8\n>\n> If this is a US military address, use state abbreviations (AA, AE, AP).", + "example": "CA", + "maxLength": 24, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "tax_id": { + "description": "The tax identification number for this child account. Use this for tax calculations in some countries. If you live in a country that doesn't collect taxes, ensure this is an empty string (`\"\"`).", + "example": "ATU99999999", + "maxLength": 25, + "type": "string" + }, + "zip": { + "description": "__Filterable__ The zip code of this Account's billing address. The following restrictions apply:\n\n- Can only contain ASCII letters, numbers, and hyphens (`-`).\n- Can't contain more than 9 letter or number characters.", + "example": "92111-1234", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/child-account.yaml" + } + }, + "credit-card": { + "additionalProperties": false, + "description": "An object representing the credit card information you have on file with Linode to make Payments against your Account.", + "properties": { + "card_number": { + "description": "Your credit card number. No spaces or hyphens (`-`) allowed.", + "example": 4111111111111111, + "format": "digits", + "maxLength": 24, + "minLength": 14, + "type": "string" + }, + "cvv": { + "description": "CVV (Card Verification Value) of the credit card, typically found on the back of the card.", + "example": "123", + "format": "digits", + "maxLength": 4, + "minLength": 3, + "type": "string" + }, + "expiry_month": { + "description": "A value from 1-12 representing the expiration month of your credit card.\n\n - 1 = January\n - 2 = February\n - 3 = March\n - Etc.", + "example": 12, + "maximum": 12, + "minimum": 1, + "type": "integer" + }, + "expiry_year": { + "description": "A four-digit integer representing the expiration year of your credit card.\n\nThe combination of `expiry_month` and `expiry_year` must result in a month/year combination of the current month or in the future. An expiration date set in the past is invalid.", + "example": 2020, + "maxLength": 4, + "minLength": 4, + "type": "integer" + } + }, + "required": [ + "card_number", + "expiry_month", + "expiry_year", + "cvv" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/credit-card.yaml" + } + }, + "credit-card-data": { + "additionalProperties": false, + "description": "Credit card information.", + "properties": { + "card_type": { + "description": "__Read-only__ The type of credit card.", + "example": "Discover", + "readOnly": true, + "type": "string" + }, + "expiry": { + "description": "__Read-only__ The expiration month and year of the credit card.", + "example": "06/2022", + "format": "MM/YYYY", + "readOnly": true, + "type": "string" + }, + "last_four": { + "description": "__Read-only__ The last four digits of the credit card number.", + "example": "1234", + "readOnly": true, + "type": "string" + } + }, + "title": "Credit card", + "type": "object", + "x-akamai": { + "file-path": "schemas/credit-card-data.yaml" + } + }, + "description": { + "description": "__Read-only__ Additional details regarding the Beta Program.", + "example": "This is an open public beta for an example feature.", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "ended": { + "description": "__Filterable__, __Read-only__ The date-time that the Beta Program ended.\n\n`null` indicates that the Beta Program is ongoing.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + }, + "entities": { + "additionalProperties": false, + "description": "A collection of the entities to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + }, + "entity-transfer": { + "additionalProperties": false, + "description": "An object representing an Entity Transfer.", + "properties": { + "created": { + "description": "When this transfer was created.", + "example": "2021-02-11T16:37:03", + "format": "date-time", + "type": "string" + }, + "entities": { + "additionalProperties": false, + "description": "A collection of the entities to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + }, + "expiry": { + "description": "When this transfer expires. Transfers will automatically expire 24 hours after creation.", + "example": "2021-02-12T16:37:03", + "format": "date-time", + "type": "string", + "x-linode-cli-display": 3 + }, + "is_sender": { + "description": "__Filterable__ If the requesting account created this transfer.", + "example": true, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "status": { + "description": "__Filterable__ The status of the transfer request:\n\n`accepted`: The transfer has been accepted by another user and is currently in progress. Transfers can take up to 3 hours to complete.\n`canceled`: The transfer has been canceled by the sender.\n`completed`: The transfer has completed successfully.\n`failed`: The transfer has failed after initiation.\n`pending`: The transfer is ready to be accepted.\n`stale`: The transfer has exceeded its expiration date. It can no longer be accepted or canceled.", + "enum": [ + "accepted", + "canceled", + "completed", + "failed", + "pending", + "stale" + ], + "example": "pending", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-color": { + "accepted": "yellow", + "canceled": "red", + "completed": "green", + "default_": "white", + "failed": "red", + "pending": "yellow", + "stale": "red" + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "token": { + "description": "The token used to identify and accept or cancel this transfer.", + "example": "123E4567-E89B-12D3-A456-426614174000", + "format": "uuid", + "type": "string", + "x-linode-cli-display": 1 + }, + "updated": { + "description": "When this transfer was last updated.", + "example": "2021-02-11T16:37:03", + "format": "date-time", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/entity-transfer.yaml" + } + }, + "error-object": { + "additionalProperties": false, + "description": "An object for describing a single error that occurred during the processing of a request.", + "properties": { + "field": { + "description": "The field in the request that caused this error. This may be a path, separated by periods in the case of nested fields. In some cases this may come back as `null` if the error is not specific to any single element of the request.", + "example": "fieldname", + "type": "string" + }, + "reason": { + "description": "What happened to cause this error. In most cases, this can be fixed immediately by changing the data you sent in the request, but in some cases you will be instructed to [Open a support ticket](https://techdocs.akamai.com/linode-api/reference/post-ticket) or perform some other action before you can complete the request successfully.", + "example": "fieldname must be a valid value", + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/error-object.yaml" + } + }, + "event": { + "additionalProperties": false, + "description": "A collection of Event objects. An Event is an action taken against an entity related to your Account. For example, booting a Linode would create an Event. The Events returned depends on your grants.", + "properties": { + "action": { + "description": "__Filterable__, __Read-only__ The action that caused this Event. New actions may be added in the future.", + "enum": [ + "account_update", + "account_settings_update", + "backups_enable", + "backups_cancel", + "backups_restore", + "community_question_reply", + "community_like", + "credit_card_updated", + "disk_create", + "disk_delete", + "disk_update", + "disk_duplicate", + "disk_imagize", + "disk_resize", + "dns_record_create", + "dns_record_delete", + "dns_record_update", + "dns_zone_create", + "dns_zone_delete", + "dns_zone_import", + "dns_zone_update", + "entity_transfer_accept", + "entity_transfer_cancel", + "entity_transfer_create", + "entity_transfer_fail", + "entity_transfer_stale", + "firewall_apply", + "firewall_create", + "firewall_delete", + "firewall_disable", + "firewall_enable", + "firewall_update", + "firewall_device_add", + "firewall_device_remove", + "host_reboot", + "image_delete", + "image_update", + "image_upload", + "ipaddress_update", + "lassie_reboot", + "lish_boot", + "linode_addip", + "linode_boot", + "linode_clone", + "linode_create", + "linode_delete", + "linode_update", + "linode_deleteip", + "linode_migrate", + "linode_migrate_datacenter", + "linode_migrate_datacenter_create", + "linode_mutate", + "linode_mutate_create", + "linode_reboot", + "linode_rebuild", + "linode_resize", + "linode_resize_create", + "linode_shutdown", + "linode_snapshot", + "linode_config_create", + "linode_config_delete", + "linode_config_update", + "lke_cluster_create", + "lke_cluster_update", + "lke_cluster_delete", + "lke_cluster_recycle", + "lke_cluster_regenerate", + "lke_node_create", + "lke_node_delete", + "lke_node_recycle", + "lke_pool_create", + "lke_pool_delete", + "lke_pool_recycle", + "lke_kubeconfig_regenerate", + "lke_token_rotate", + "longviewclient_create", + "longviewclient_delete", + "longviewclient_update", + "managed_disabled", + "managed_enabled", + "managed_service_create", + "managed_service_delete", + "nodebalancer_create", + "nodebalancer_delete", + "nodebalancer_update", + "nodebalancer_config_create", + "nodebalancer_config_delete", + "nodebalancer_config_update", + "nodebalancer_node_create", + "nodebalancer_node_delete", + "nodebalancer_node_update", + "oauth_client_create", + "oauth_client_delete", + "oauth_client_secret_reset", + "oauth_client_update", + "obj_access_key_create", + "obj_access_key_delete", + "obj_access_key_update", + "password_reset", + "payment_method_add", + "payment_submitted", + "placement_group_assign", + "placement_group_became_compliant", + "placement_group_became_non_compliant", + "placement_group_create", + "placement_group_delete", + "placement_group_unassign", + "placement_group_update", + "profile_update", + "stackscript_create", + "stackscript_delete", + "stackscript_update", + "stackscript_publicize", + "stackscript_revise", + "subnet_create", + "subnet_delete", + "subnet_update", + "tag_create", + "tag_delete", + "tax_id_valid", + "tax_id_invalid", + "tfa_disabled", + "tfa_enabled", + "ticket_attachment_upload", + "ticket_create", + "ticket_update", + "token_create", + "token_delete", + "token_update", + "user_create", + "user_update", + "user_delete", + "user_ssh_key_add", + "user_ssh_key_delete", + "user_ssh_key_update", + "vlan_attach", + "vlan_detach", + "volume_attach", + "volume_clone", + "volume_create", + "volume_delete", + "volume_update", + "volume_detach", + "volume_resize", + "vpc_create", + "vpc_delete", + "vpc_update" + ], + "example": "ticket_create", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3, + "x-linode-filterable": true + }, + "created": { + "description": "__Filterable__, __Read-only__ When this Event was created.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + }, + "duration": { + "description": "__Read-only__ The total duration in seconds that it takes for the Event to complete.", + "example": 300.56, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 7 + }, + "entity": { + "additionalProperties": false, + "description": "__Read-only__ Detailed information about the Event's entity, including ID, type, label, and URL used to access it.", + "properties": { + "id": { + "description": "__Filterable__ The unique ID for an Event's entity.\n\nSome Event entities do not have IDs associated with them, so they will not be returned when filtering by ID. These Events include:\n\n - `account`\n - `profile`\n\nEntities for some Events are assigned the ID of the Linode they correspond to. When filtering by ID for these Events, use the corresponding Linode's ID. These Events include:\n\n - `disks`\n - `backups`\n\nTag Events use a tag's name for the entity ID field. When filtering by ID for tag Events, supply the name of the tag.", + "example": 11111, + "type": "integer", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "label": { + "description": "The current label of this object. The label may reflect changes that occur with this Event.", + "example": "Problem booting my Linode", + "type": "string", + "x-linode-cli-display": 5 + }, + "type": { + "description": "__Filterable__, __Read-only__ The type of entity that is being referenced by the Event.", + "enum": [ + "account", + "backups", + "community", + "disks", + "domain", + "entity_transfer", + "firewall", + "image", + "ipaddress", + "linode", + "longview", + "loadbalancer", + "managed_service", + "nodebalancer", + "oauth_client", + "profile", + "stackscript", + "tag", + "ticket", + "token", + "user", + "user_ssh_key", + "volume" + ], + "example": "ticket", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "url": { + "description": "The URL where you can access the object this Event is for. If a relative URL, it is relative to the domain you retrieved the Event from.", + "example": "/v4/support/tickets/11111", + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "id": { + "description": "__Filterable__, __Read-only__ The unique ID of this Event.", + "example": 123, + "readOnly": true, + "type": "integer", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 1, + "x-linode-filterable": true + }, + "message": { + "description": "Provides additional information about the event. Additional information may include, but is not limited to, a more detailed representation of events which can help diagnose non-obvious failures.", + "example": "None", + "nullable": true, + "type": "string", + "x-linode-cli-display": 9 + }, + "percent_complete": { + "description": "__Read-only__ A percentage estimating the amount of time remaining for an Event. Returns `null` for notification events.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "integer" + }, + "rate": { + "description": "__Read-only__ The rate of completion of the Event. Only some Events will return rate; for example, migration and resize Events.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "string" + }, + "read": { + "description": "__Filterable__, __Read-only__ If this Event has been read.", + "example": true, + "readOnly": true, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "secondary_entity": { + "additionalProperties": false, + "description": "__Read-only__ Detailed information about the Event's secondary entity, which provides additional information for events such as, but not limited to, `linode_boot`, `linode_reboot`, `linode_create`, and `linode_clone` Event actions.", + "properties": { + "id": { + "description": "The ID of the object that is the secondary entity.", + "example": "linode/debian9", + "type": "string" + }, + "label": { + "description": "The label of this object.", + "example": "linode1234", + "type": "string" + }, + "type": { + "description": "__Read-only__ The type of entity that is being referenced by the Event.", + "example": "linode", + "readOnly": true, + "type": "string" + }, + "url": { + "description": "The URL where you can access the object this Event is for. If a relative URL, it is relative to the domain you retrieved the Event from.", + "example": "/v4/linode/instances/1234", + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "seen": { + "description": "__Read-only__ If this Event has been seen.", + "example": true, + "readOnly": true, + "type": "boolean" + }, + "status": { + "description": "__Read-only__ The current status of this Event.", + "enum": [ + "failed", + "finished", + "notification", + "scheduled", + "started" + ], + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "default_": "white", + "failed": "red", + "finished": "green", + "started": "yellow" + }, + "x-linode-cli-display": 8 + }, + "time_remaining": { + "description": "__Read-only__ The estimated time remaining until the completion of this Event. This value is only returned for some in-progress migration events. For all other in-progress events, the `percent_complete` attribute will indicate about how much more work is to be done.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "string" + }, + "username": { + "description": "__Read-only__ The username of the User who caused the Event.", + "example": "exampleUser", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/event.yaml" + } + }, + "google-pay-data": { + "additionalProperties": false, + "description": "Google Pay information.", + "properties": { + "card_type": { + "description": "__Read-only__ The type of credit card.", + "example": "Discover", + "readOnly": true, + "type": "string" + }, + "expiry": { + "description": "__Read-only__ The expiration month and year of the credit card.", + "example": "06/2022", + "format": "MM/YYYY", + "readOnly": true, + "type": "string" + }, + "last_four": { + "description": "__Read-only__ The last four digits of the credit card number.", + "example": "1234", + "readOnly": true, + "type": "string" + } + }, + "title": "Google Pay", + "type": "object", + "x-akamai": { + "file-path": "schemas/google-pay-data.yaml" + } + }, + "grant": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "grants-response": { + "additionalProperties": false, + "description": "A structure representing all grants a restricted User has on the Account. Not available for unrestricted users, as they have access to everything without grants. If retrieved from the `/profile/grants` endpoint, entities to which a User has no access will be omitted.", + "properties": { + "database": { + "description": "The grants this User has for each Database that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "domain": { + "description": "The grants this User has for each Domain that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "firewall": { + "description": "The grants this User has for each Firewall that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "global": { + "additionalProperties": false, + "description": "A structure containing the Account-level grants a User has.", + "properties": { + "account_access": { + "description": "The level of access this User has to Account-level actions, like billing information. A restricted User will never be able to manage users.\n\n__Parent and child accounts__\n\nIn a [parent and child account](https://www.linode.com/docs/guides/parent-child-accounts/) environment, this grant can be added to a child account user, to give the user `read-write` access. This gives the child user unrestricted access to expected management operations, such as creating other child users. However, child users don't have write access to billing operations. The API issues a specific error message if a write operation is attempted by a child user.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + }, + "add_databases": { + "description": "If `true`, this User may add Managed Databases.", + "example": true, + "type": "boolean" + }, + "add_domains": { + "description": "If `true`, this User may add Domains.", + "example": true, + "type": "boolean" + }, + "add_firewalls": { + "description": "If `true`, this User may add Firewalls.", + "example": true, + "type": "boolean" + }, + "add_images": { + "description": "If `true`, this User may add Images.", + "example": true, + "type": "boolean" + }, + "add_linodes": { + "description": "If `true`, this User may create Linodes.", + "example": true, + "type": "boolean" + }, + "add_longview": { + "description": "If `true`, this User may create Longview clients and view the current plan.", + "example": true, + "type": "boolean" + }, + "add_nodebalancers": { + "description": "If `true`, this User may add NodeBalancers.", + "example": true, + "type": "boolean" + }, + "add_stackscripts": { + "description": "If `true`, this User may add StackScripts.", + "example": true, + "type": "boolean" + }, + "add_volumes": { + "description": "If `true`, this User may add Volumes.", + "example": true, + "type": "boolean" + }, + "add_vpcs": { + "description": "If `true`, this User may add VPCs.", + "example": true, + "type": "boolean" + }, + "cancel_account": { + "description": "If `true`, this User may cancel the entire Account.", + "example": false, + "type": "boolean" + }, + "child_account_access": { + "description": "In a [parent and child account](https://www.linode.com/docs/guides/parent-child-accounts/) environment, this gives a parent account access to endpoints that can be used to manage child accounts. Unrestricted parent account users have access to this grant, while restricted parent users don't. An unrestricted parent user can set this to `true` to add this grant to a restricted parent user. Displayed as `null` for all non-parent accounts.", + "example": true, + "nullable": true, + "type": "boolean" + }, + "longview_subscription": { + "description": "If `true`, this User may manage the Account's Longview subscription.", + "example": true, + "type": "boolean" + } + }, + "type": "object" + }, + "image": { + "description": "The grants this User has for each Image that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "linode": { + "description": "The grants this User has for each Linode that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "longview": { + "description": "The grants this User has for each Longview Client that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "nodebalancer": { + "description": "The grants this User has for each NodeBalancer that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "stackscript": { + "description": "The grants this User has for each StackScript that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "volume": { + "description": "The grants this User has for each Block Storage Volume that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + }, + "vpc": { + "description": "The grants this User has for each VPC that is owned by this Account.", + "items": { + "additionalProperties": false, + "description": "Represents the level of access a restricted User has to a specific resource on the Account.", + "properties": { + "id": { + "description": "The ID of the entity this grant applies to.", + "example": 123, + "type": "integer" + }, + "label": { + "description": "__Read-only__ The current label of the entity this grant applies to, for display purposes.", + "example": "example-entity", + "readOnly": true, + "type": "string" + }, + "permissions": { + "description": "The level of access this User has to this entity. If `null`, this User has no access.", + "enum": [ + "read_only", + "read_write" + ], + "example": "read_only", + "nullable": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grant.yaml" + } + }, + "type": "array" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/grants-response.yaml" + } + }, + "id": { + "description": "The unique identifier of the Beta Program.", + "example": "example_open", + "type": "string", + "x-linode-cli-display": 1 + }, + "invoice": { + "additionalProperties": false, + "description": "Account Invoice object.", + "properties": { + "billing_source": { + "description": "__Filterable__, __Read-only__ `akamai`: This Invoice was generated according to the terms of an agreement between the customer and Akamai.\n\n`linode`: This Invoice was generated according to the default terms, prices, and discounts.", + "enum": [ + "akamai", + "linode" + ], + "example": "linode", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3.5, + "x-linode-filterable": true + }, + "date": { + "description": "__Filterable__, __Read-only__ When this Invoice was generated.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "id": { + "description": "__Read-only__ The Invoice's unique ID.", + "example": 123, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__, __Read-only__ The Invoice's display label.", + "example": "Invoice", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 3, + "x-linode-filterable": true + }, + "subtotal": { + "description": "__Read-only__ The amount of the Invoice before taxes in US Dollars.", + "example": 120.25, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "tax": { + "description": "__Read-only__ The amount of tax levied on the Invoice in US Dollars.", + "example": 12.25, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 5 + }, + "tax_summary": { + "description": "__Read-only__ The amount of tax broken down into subtotals by source.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "The source of this tax subtotal.", + "example": "PA STATE TAX", + "type": "string" + }, + "tax": { + "description": "The amount of tax subtotal attributable to this source.", + "example": 12.25, + "type": "number" + } + }, + "type": "object" + }, + "readOnly": true, + "type": "array" + }, + "total": { + "description": "__Filterable__, __Read-only__ The amount of the Invoice after taxes in US Dollars.", + "example": 132.5, + "readOnly": true, + "type": "number", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 6, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/invoice.yaml" + } + }, + "invoice-item": { + "additionalProperties": false, + "description": "An InvoiceItem object.", + "properties": { + "amount": { + "description": "__Read-only__ The price, in US dollars, of the Invoice Item. Equal to the unit price multiplied by quantity.", + "example": 20.2, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 4 + }, + "from": { + "description": "__Read-only__ The date the Invoice Item started, based on month.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "label": { + "description": "__Read-only__ The Invoice Item's display label.", + "example": "Linode 123", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "quantity": { + "description": "__Read-only__ The quantity of this Item for the specified Invoice.", + "example": 4, + "readOnly": true, + "type": "integer" + }, + "region": { + "description": "__Read-only__ The ID of the applicable Region associated with this Invoice Item.\n\n`null` if there is no applicable Region.", + "example": "us-west", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-display": 7 + }, + "tax": { + "description": "__Read-only__ The amount of tax levied on this Item in US Dollars.", + "example": 1.25, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 5 + }, + "to": { + "description": "__Read-only__ The date the Invoice Item ended, based on month.", + "example": "2018-01-31T11:59:59", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "total": { + "description": "__Read-only__ The price of this Item after taxes in US Dollars.", + "example": 21.45, + "readOnly": true, + "type": "number", + "x-linode-cli-display": 6 + }, + "type": { + "description": "__Read-only__ The type of service, ether `hourly` or `misc`.", + "enum": [ + "hourly", + "misc" + ], + "example": "hourly", + "readOnly": true, + "type": "string" + }, + "unit_price": { + "description": "__Read-only__ The monthly service fee in US Dollars for this Item.", + "example": 5.05, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/invoice-item.yaml" + } + }, + "is_default": { + "description": "Whether this Payment Method is the default method for automatically processing service charges.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "label": { + "description": "__Filterable__, __Read-only__ The name of the Beta Program.", + "example": "Example Open Beta", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "login": { + "additionalProperties": false, + "description": "An object representing a previous successful login for a User.", + "properties": { + "datetime": { + "description": "__Read-only__ When the login was initiated.", + "example": "2018-01-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "id": { + "description": "__Read-only__ The unique ID of this login object.", + "example": 1234, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "ip": { + "description": "__Read-only__ The remote IP address that requested the login.", + "example": "192.0.2.0", + "format": "ip", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 3 + }, + "restricted": { + "description": "__Read-only__ True if the User that attempted the login was a restricted User, false otherwise.", + "example": true, + "readOnly": true, + "type": "boolean", + "x-linode-cli-display": 6 + }, + "status": { + "description": "__Read-only__ Whether the login attempt succeeded or failed.", + "enum": [ + "successful", + "failed" + ], + "example": "successful", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 5 + }, + "username": { + "description": "__Read-only__ The username of the User that attempted the login.", + "example": "example_user", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 4 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/login.yaml" + } + }, + "maintenance": { + "additionalProperties": false, + "description": "Information about maintenance affecting an entity.", + "properties": { + "entity": { + "additionalProperties": false, + "description": "The entity being affected by maintenance.", + "properties": { + "id": { + "description": "The id of the entity being affected by maintenance.", + "example": 1234, + "type": "number" + }, + "label": { + "description": "The label of the entity being affected by maintenance.", + "example": "demo-linode", + "type": "string" + }, + "type": { + "description": "The type of entity.", + "example": "Linode", + "type": "string" + }, + "url": { + "description": "The API endpoint prefix to use in combination with the entity id to find specific information about the entity.", + "example": "https://api.linode.com/v4/linode/instances/{linodeId}", + "type": "string" + } + }, + "type": "object" + }, + "reason": { + "description": "The reason maintenance is being performed.", + "example": "This maintenance will allow us to update the BIOS on the host's motherboard.", + "type": "string" + }, + "status": { + "description": "__Filterable__ The maintenance status.\n\nMaintenance progresses in the following sequence: pending, started, then completed.", + "enum": [ + "completed", + "pending", + "started" + ], + "example": "started", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "type": { + "description": "__Filterable__ The type of maintenance.", + "enum": [ + "reboot", + "cold_migration", + "live_migration" + ], + "example": "reboot", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + }, + "when": { + "description": "__Filterable__ When the maintenance will begin.\n\n[Filterable](https://techdocs.akamai.com/linode-api/reference/filtering-and-sorting) with the following parameters:\n\n- A single value in date-time string format (`%Y-%m-%dT%H:%M:%S`), which returns only matches to that value.\n\n- A dictionary containing pairs of inequality operator string keys (`+or`, `+gt`, `+gte`, `+lt`, `+lte`, or `+neq`) and single date-time string format values (`%Y-%m-%dT%H:%M:%S`). `+or` accepts an array of values that may consist of single date-time strings or dictionaries of inequality operator pairs.", + "example": "2020-07-09T00:01:01", + "format": "date-time", + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-filterable": true + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/maintenance.yaml" + } + }, + "notification": { + "additionalProperties": false, + "description": "An important, often time-sensitive item related to your account.", + "properties": { + "body": { + "description": "__Read-only__ A full description of this notification, in markdown format. Not all notifications include a `body`.", + "example": null, + "nullable": true, + "readOnly": true, + "type": "string" + }, + "entity": { + "additionalProperties": false, + "description": "__Read-only__ Detailed information about the notification.", + "properties": { + "id": { + "description": "The unique ID of the notification's entity, based on the entity type. Returns `null` for an `account` or `promotion` entity.", + "example": 3456, + "nullable": true, + "type": "integer" + }, + "label": { + "description": "The current label for this notification's entity.\n\nReturns `null` for the following entity types:\n\n- `entity_transfer`\n- `promotion`\n- `region`", + "example": "Linode not booting.", + "nullable": true, + "type": "string" + }, + "type": { + "description": "The type of entity this is related to.", + "enum": [ + "account", + "entity_transfer", + "linode", + "loadbalancers", + "nodebalancer", + "promotion", + "region", + "ticket", + "volume" + ], + "example": "ticket", + "type": "string" + }, + "url": { + "description": "The URL where you can access the notification's object. The URL is relative to the domain where you retrieved the notification. This value is `null` for the `promotion` entity type.", + "example": "/support/tickets/3456", + "nullable": true, + "type": "string" + } + }, + "readOnly": true, + "type": "object" + }, + "label": { + "description": "__Read-only__ A short description of this notification.", + "example": "You have an important ticket open!", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "message": { + "description": "__Read-only__ A human-readable description of the notification.", + "example": "You have an important ticket open!", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "severity": { + "description": "__Read-only__ The severity of this notification. This field determines how prominently the notification is displayed and the color of the display text.", + "enum": [ + "minor", + "major", + "critical" + ], + "example": "major", + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "critical": "b", + "default_": "white", + "minor": "blue" + }, + "x-linode-cli-display": 3 + }, + "type": { + "description": "__Read-only__ The type of notification.", + "enum": [ + "migration_scheduled", + "migration_imminent", + "migration_pending", + "reboot_scheduled", + "outage", + "payment_due", + "ticket_important", + "ticket_abuse", + "notice", + "maintenance", + "promotion", + "tax_id_verifying" + ], + "example": "ticket_important", + "readOnly": true, + "type": "string" + }, + "until": { + "description": "__Read-only__ If this notification has a duration, this is when the event or action will complete. For example, if there's scheduled maintenance for one of our systems, `until` represents the end of the maintenance window.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "None": "black", + "default_": "white" + }, + "x-linode-cli-display": 5 + }, + "when": { + "description": "__Read-only__ If this notification is for an event in the future, this specifies when the action occurs. For example, if a compute instance needs to migrate in response to a security advisory, this field sets the approximate time the compute instance will be taken offline for migration.", + "example": null, + "format": "date-time", + "nullable": true, + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "None": "black", + "default_": "white" + }, + "x-linode-cli-display": 4 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/notification.yaml" + } + }, + "oauth-client": { + "additionalProperties": false, + "description": "A third-party application registered to Linode that users may log into with their Linode account through our authentication server at [login.linode.com](https://login.linode.com). Using an OAuth Client, a third-party developer may be given access to some, or all, of a User's account for the purposes of their application.", + "properties": { + "id": { + "description": "__Read-only__ The OAuth Client ID. This is used to identify the client, and is a publicly known value (it is not a secret).", + "example": "2737bf16b39ab5d7b4a1", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__ The name of this application. This will be presented to users when they are asked to grant it access to their Account.", + "example": "Test_Client_1", + "maxLength": 512, + "minLength": 1, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 2, + "x-linode-filterable": true + }, + "public": { + "default": false, + "description": "__Filterable__ If this is a public or private OAuth Client. Public clients have a slightly different authentication workflow than private clients. See the [OAuth spec](https://oauth.net/2/) for more details.", + "example": false, + "type": "boolean", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "redirect_uri": { + "description": "The location a successful log in from [login.linode.com](https://login.linode.com) should be redirected to for this client. The receiver of this redirect should be ready to accept an OAuth exchange code and finish the OAuth exchange.", + "example": "https://example.org/oauth/callback", + "format": "url", + "type": "string", + "x-linode-cli-display": 5 + }, + "secret": { + "description": "__Read-only__ The OAuth Client secret, used in the OAuth exchange. This is returned as `` except when an OAuth Client is created or its secret is reset. This is a secret, and should not be shared or disclosed publicly.", + "example": "", + "readOnly": true, + "type": "string" + }, + "status": { + "description": "__Read-only__ The status of this application. `active` by default.", + "enum": [ + "active", + "disabled", + "suspended" + ], + "example": "active", + "readOnly": true, + "type": "string", + "x-linode-cli-color": { + "default_": "white", + "suspended": "red" + }, + "x-linode-cli-display": 3 + }, + "thumbnail_url": { + "description": "__Read-only__ The URL where this client's thumbnail may be viewed, or `null` if this client does not have a thumbnail set.", + "example": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", + "format": "url", + "nullable": true, + "readOnly": true, + "type": "string" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/oauth-client.yaml" + } + }, + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pagination-envelope": { + "additionalProperties": false, + "description": "An envelope for paginated response. When accessing a collection through a GET endpoint, the results are wrapped in this envelope which includes metadata about those results. Results are presented within a `data` array. See [Pagination](https://techdocs.akamai.com/linode-api/reference/pagination) for more information.", + "properties": { + "page": { + "description": "__Read-only__ The current [page](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "pages": { + "description": "__Read-only__ The total number of [pages](https://techdocs.akamai.com/linode-api/reference/pagination).", + "example": 1, + "readOnly": true, + "type": "integer" + }, + "results": { + "description": "__Read-only__ The total number of results.", + "example": 1, + "readOnly": true, + "type": "integer" + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/pagination-envelope.yaml" + } + }, + "payment": { + "additionalProperties": false, + "description": "Payment object response.", + "properties": { + "date": { + "description": "__Read-only__ When the Payment was made.", + "example": "2018-01-15T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 2 + }, + "id": { + "description": "__Read-only__ The unique ID of the Payment.", + "example": 123, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "usd": { + "description": "__Read-only__ The amount, in US dollars, of the Payment.", + "example": "120.50", + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 3 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/payment.yaml" + } + }, + "payment-method": { + "additionalProperties": false, + "description": "Payment Method Response Object.", + "properties": { + "created": { + "description": "__Read-only__ When the Payment Method was added to the Account.", + "example": "2018-01-15T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "data": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Credit card information.", + "properties": { + "card_type": { + "description": "__Read-only__ The type of credit card.", + "example": "Discover", + "readOnly": true, + "type": "string" + }, + "expiry": { + "description": "__Read-only__ The expiration month and year of the credit card.", + "example": "06/2022", + "format": "MM/YYYY", + "readOnly": true, + "type": "string" + }, + "last_four": { + "description": "__Read-only__ The last four digits of the credit card number.", + "example": "1234", + "readOnly": true, + "type": "string" + } + }, + "title": "Credit card", + "type": "object", + "x-akamai": { + "file-path": "schemas/credit-card-data.yaml" + }, + "x-linode-ref-name": "Credit Card" + }, + { + "additionalProperties": false, + "description": "Google Pay information.", + "properties": { + "card_type": { + "description": "__Read-only__ The type of credit card.", + "example": "Discover", + "readOnly": true, + "type": "string" + }, + "expiry": { + "description": "__Read-only__ The expiration month and year of the credit card.", + "example": "06/2022", + "format": "MM/YYYY", + "readOnly": true, + "type": "string" + }, + "last_four": { + "description": "__Read-only__ The last four digits of the credit card number.", + "example": "1234", + "readOnly": true, + "type": "string" + } + }, + "title": "Google Pay", + "type": "object", + "x-akamai": { + "file-path": "schemas/google-pay-data.yaml" + }, + "x-linode-ref-name": "Google Pay" + }, + { + "additionalProperties": false, + "description": "PayPal information.", + "properties": { + "email": { + "description": "__Read-only__ The email address associated with your PayPal account.", + "example": "example@linode.com", + "readOnly": true, + "type": "string" + }, + "paypal_id": { + "description": "__Read-only__ PayPal Merchant ID associated with your PayPal account.", + "example": "ABC1234567890", + "readOnly": true, + "type": "string" + } + }, + "title": "Paypal", + "type": "object", + "x-akamai": { + "file-path": "schemas/paypal-data.yaml" + }, + "x-linode-ref-name": "Paypal" + } + ], + "x-linode-cli-display": 4, + "x-linode-cli-format": "json" + }, + "id": { + "description": "The unique ID of this Payment Method.", + "example": 123, + "type": "integer", + "x-linode-cli-display": 1 + }, + "is_default": { + "description": "Whether this Payment Method is the default method for automatically processing service charges.", + "example": true, + "type": "boolean", + "x-linode-cli-display": 3 + }, + "type": { + "description": "The type of Payment Method.", + "enum": [ + "credit_card", + "google_pay", + "paypal" + ], + "example": "credit_card", + "type": "string", + "x-linode-cli-display": 2 + } + }, + "type": "object", + "x-akamai": { + "file-path": "schemas/payment-method.yaml" + } + }, + "paypal": { + "additionalProperties": false, + "description": "An object representing the staging of a Payment via PayPal.", + "properties": { + "cancel_url": { + "description": "The URL to have PayPal redirect to when Payment is canceled.", + "example": "https://example.org", + "type": "string" + }, + "redirect_url": { + "description": "The URL to have PayPal redirect to when Payment is approved.", + "example": "https://example.org", + "type": "string" + }, + "usd": { + "description": "The payment amount in USD. Minimum accepted value of $5 USD. Maximum accepted value of $500 USD or credit card payment limit; whichever value is highest. PayPal's maximum transaction limit is $10,000 USD.", + "example": "120.50", + "type": "string" + } + }, + "required": [ + "cancel_url", + "redirect_url", + "usd" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/paypal.yaml" + } + }, + "paypal-data": { + "additionalProperties": false, + "description": "PayPal information.", + "properties": { + "email": { + "description": "__Read-only__ The email address associated with your PayPal account.", + "example": "example@linode.com", + "readOnly": true, + "type": "string" + }, + "paypal_id": { + "description": "__Read-only__ PayPal Merchant ID associated with your PayPal account.", + "example": "ABC1234567890", + "readOnly": true, + "type": "string" + } + }, + "title": "Paypal", + "type": "object", + "x-akamai": { + "file-path": "schemas/paypal-data.yaml" + } + }, + "paypal-execute": { + "additionalProperties": false, + "description": "An object representing an execution of Payment to PayPal to capture the funds and credit your Linode Account.", + "properties": { + "payer_id": { + "description": "The PayerID returned by PayPal during the transaction authorization process.", + "example": "ABCDEFGHIJKLM", + "type": "string" + }, + "payment_id": { + "description": "The PaymentID returned from [Stage a PayPal payment](https://techdocs.akamai.com/linode-api/reference/post-pay-pal-payment) that has been approved with PayPal.", + "example": "PAY-1234567890ABCDEFGHIJKLMN", + "type": "string" + } + }, + "required": [ + "payer_id", + "payment_id" + ], + "type": "object", + "x-akamai": { + "file-path": "schemas/paypal-execute.yaml" + } + }, + "promotion": { + "additionalProperties": false, + "description": "__Read-only__ Promotions generally offer a set amount of credit that can be used toward your Linode services, and the promotion expires after a specified date. As well, a monthly cap on the promotional offer is set.\n\nSimply put, a promotion offers a certain amount of credit month, until either the expiration date is passed, or until the total promotional credit is used, whichever comes first.", + "properties": { + "credit_monthly_cap": { + "description": "The amount available to spend per month.", + "example": "10.00", + "type": "string", + "x-linode-cli-display": 5 + }, + "credit_remaining": { + "description": "The total amount of credit left for this promotion.", + "example": "50.00", + "type": "string", + "x-linode-cli-display": 3 + }, + "description": { + "description": "A detailed description of this promotion.", + "example": "Receive up to $10 off your services every month for 6 months! Unused credits will expire once this promotion period ends.", + "type": "string" + }, + "expire_dt": { + "description": "When this promotion's credits expire.", + "example": "2018-01-31T23:59:59", + "type": "string", + "x-linode-cli-display": 2 + }, + "image_url": { + "description": "The location of an image for this promotion.", + "example": "https://linode.com/10_a_month_promotion.svg", + "type": "string" + }, + "service_type": { + "description": "The service to which this promotion applies.", + "enum": [ + "all", + "backup", + "blockstorage", + "db_mysql", + "ip_v4", + "linode", + "linode_disk", + "linode_memory", + "longview", + "managed", + "nodebalancer", + "objectstorage", + "placement_group", + "transfer_tx" + ], + "example": "all", + "type": "string", + "x-linode-cli-display": 1 + }, + "summary": { + "description": "Short details of this promotion.", + "example": "$10 off your Linode a month!", + "type": "string", + "x-linode-cli-display": 10 + }, + "this_month_credit_remaining": { + "description": "The amount of credit left for this month for this promotion.", + "example": "10.00", + "type": "string", + "x-linode-cli-display": 4 + } + }, + "readOnly": true, + "type": "object", + "x-akamai": { + "file-path": "schemas/promotion.yaml" + } + }, + "properties-entities": { + "additionalProperties": false, + "description": "A collection of the services to include in this transfer request, separated by type.", + "properties": { + "linodes": { + "description": "An array containing the IDs of each of the Linodes included in this transfer.", + "example": [ + 111, + 222 + ], + "items": { + "type": "integer" + }, + "type": "array", + "x-linode-cli-display": 5 + } + }, + "type": "object" + }, + "proxy-user-token": { + "additionalProperties": false, + "description": "The token generated manually for a child account so its proxy user can access the API and CLI without going through an OAuth login.", + "properties": { + "created": { + "description": "__Filterable__, __Read-only__ The date and time this token was created.", + "example": "2024-05-01T00:01:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-akamai": { + "labels": [ + "Filterable" + ] + }, + "x-linode-cli-display": 4, + "x-linode-filterable": true + }, + "expiry": { + "description": "__Read-only__ When this token expires. This is default set to 15 minutes from the time of creation. Proxy user tokens can't be renewed. After this time, Akamai revokes the token and you need to generate a new one.", + "example": "2024-05-01T00:16:01", + "format": "date-time", + "readOnly": true, + "type": "string", + "x-linode-cli-display": 6 + }, + "id": { + "description": "__Read-only__ The proxy user token's unique ID, which can be used to revoke it.", + "example": 918, + "readOnly": true, + "type": "integer", + "x-linode-cli-display": 1 + }, + "label": { + "description": "__Filterable__ The name of the token. The API automatically sets this to `__