1# --------------------------------------------------------------------------------------------
2# Copyright (c) Microsoft Corporation. All rights reserved.
3# Licensed under the MIT License. See License.txt in the project root for license information.
4# --------------------------------------------------------------------------------------------
5
6# pylint: disable=line-too-long
7import argparse
8from argcomplete.completers import FilesCompleter
9from knack.arguments import CLIArgumentType
10
11from azure.cli.core.commands.parameters import (
12    tags_type,
13    get_resource_name_completion_list,
14    quotes,
15    get_three_state_flag,
16    get_enum_type
17)
18from azure.cli.core.commands.validators import get_default_location_from_resource_group
19
20from ._constants import (
21    STORAGE_RESOURCE_TYPE,
22    REGISTRY_RESOURCE_TYPE,
23    WEBHOOK_RESOURCE_TYPE,
24    REPLICATION_RESOURCE_TYPE,
25    TASK_RESOURCE_TYPE
26)
27from ._validators import (
28    validate_headers,
29    validate_arg,
30    validate_secret_arg,
31    validate_set,
32    validate_set_secret
33)
34
35image_by_tag_or_digest_type = CLIArgumentType(
36    options_list=['--image', '-t'],
37    help="The name of the image. May include a tag in the format 'name:tag' or digest in the format 'name@digest'."
38)
39
40
41def load_arguments(self, _):  # pylint: disable=too-many-statements
42    SkuName, PasswordName, DefaultAction, PolicyStatus, WebhookAction, WebhookStatus, TaskStatus, BaseImageTriggerType, RunStatus, SourceRegistryLoginMode = self.get_models('SkuName', 'PasswordName', 'DefaultAction', 'PolicyStatus', 'WebhookAction', 'WebhookStatus', 'TaskStatus', 'BaseImageTriggerType', 'RunStatus', 'SourceRegistryLoginMode')
43    with self.argument_context('acr') as c:
44        c.argument('tags', arg_type=tags_type)
45        c.argument('registry_name', options_list=['--name', '-n'], help='The name of the container registry. You can configure the default registry name using `az configure --defaults acr=<registry name>`', completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE), configured_default='acr')
46        c.argument('tenant_suffix', options_list=['--suffix'], help="The tenant suffix in registry login server. You may specify '--suffix tenant' if your registry login server is in the format 'registry-tenant.azurecr.io'. Applicable if you\'re accessing the registry from a different subscription or you have permission to access images but not the permission to manage the registry resource.")
47        c.argument('storage_account_name', help='Provide the name of an existing storage account if you\'re recreating a container registry over a previous registry created storage account. Only applicable to Classic SKU.', completer=get_resource_name_completion_list(STORAGE_RESOURCE_TYPE))
48        c.argument('sku', help='The SKU of the container registry', arg_type=get_enum_type(SkuName))
49        c.argument('admin_enabled', help='Indicates whether the admin user is enabled', arg_type=get_three_state_flag())
50        c.argument('password_name', help='The name of password to regenerate', arg_type=get_enum_type(PasswordName))
51        c.argument('username', options_list=['--username', '-u'], help='The username used to log into a container registry')
52        c.argument('password', options_list=['--password', '-p'], help='The password used to log into a container registry')
53        c.argument('yes', options_list=['--yes', '-y'], help='Do not prompt for confirmation.', action='store_true')
54        c.argument('image_names', options_list=['--image', '-t'], help="The name and tag of the image using the format: '-t repo/image:tag'. Multiple tags are supported by passing -t multiple times.", action='append')
55        c.argument('timeout', type=int, help='The timeout in seconds.')
56        c.argument('docker_file_path', options_list=['--file', '-f'], help="The relative path of the the docker file to the source code root folder. Default to 'Dockerfile'.")
57        c.argument('no_logs', help="Do not show logs after successfully queuing the build.", action='store_true')
58        c.argument('no_wait', help="Do not wait for the run to complete and return immediately after queuing the run.", action='store_true')
59        c.argument('no_format', help="Indicates whether the logs should be displayed in raw format", action='store_true')
60        c.argument('platform', options_list=['--platform', c.deprecate(target='--os', redirect='--platform', hide=True)], help="The platform where build/task is run, Eg, 'windows' and 'linux'. When it's used in build commands, it also can be specified in 'os/arch/variant' format for the resulting image. Eg, linux/arm/v7. The 'arch' and 'variant' parts are optional.")
61        c.argument('target', help='The name of the target build stage.')
62        c.argument('auth_mode', help='Auth mode of the source registry.', arg_type=get_enum_type(SourceRegistryLoginMode))
63        # Overwrite default shorthand of cmd to make availability for acr usage
64        c.argument('cmd', options_list=['--__cmd__'])
65        c.argument('cmd_value', help="Commands to execute.", options_list=['--cmd'])
66
67    for scope in ['acr create', 'acr update']:
68        with self.argument_context(scope, arg_group='Network Rule') as c:
69            c.argument('default_action', arg_type=get_enum_type(DefaultAction),
70                       help='Default action to apply when no rule matches. Only applicable to Premium SKU.')
71
72    with self.argument_context('acr import') as c:
73        c.argument('source_image', options_list=['--source'], help="The source identifier will be either a source image name or a fully qualified source.")
74        c.argument('source_registry', options_list=['--registry', '-r'], help='The source container registry can be name, login server or resource ID of the source registry.')
75        c.argument('source_registry_username', options_list=['--username', '-u'], help='The username of source container registry')
76        c.argument('source_registry_password', options_list=['--password', '-p'], help='The password of source container registry')
77        c.argument('target_tags', options_list=['--image', '-t'], help="The name and tag of the image using the format: '-t repo/image:tag'. Multiple tags are supported by passing -t multiple times.", action='append')
78        c.argument('repository', help='The repository name for a manifest-only copy of images. Multiple copies supported by passing --repository multiple times.', action='append')
79        c.argument('force', help='Overwrite the existing tag of the image to be imported.', action='store_true')
80
81    with self.argument_context('acr config content-trust') as c:
82        c.argument('status', help="Indicates whether content-trust is enabled or disabled.", arg_type=get_enum_type(PolicyStatus))
83
84    with self.argument_context('acr login') as c:
85        c.argument('resource_group_name', deprecate_info=c.deprecate(hide=True))
86
87    with self.argument_context('acr repository') as c:
88        c.argument('resource_group_name', deprecate_info=c.deprecate(hide=True))
89        c.argument('repository', help="The name of the repository.")
90        c.argument('image', arg_type=image_by_tag_or_digest_type)
91        c.argument('top', type=int, help='Limit the number of items in the results.')
92        c.argument('orderby', help='Order the items in the results. Default to alphabetical order of names.', arg_type=get_enum_type(['time_asc', 'time_desc']))
93        c.argument('detail', help='Show detailed information.', action='store_true')
94        c.argument('delete_enabled', help='Indicates whether delete operation is allowed.', arg_type=get_three_state_flag())
95        c.argument('list_enabled', help='Indicates whether this item shows in list operation results.', arg_type=get_three_state_flag())
96        c.argument('read_enabled', help='Indicates whether read operation is allowed.', arg_type=get_three_state_flag())
97        c.argument('write_enabled', help='Indicates whether write or delete operation is allowed.', arg_type=get_three_state_flag())
98
99    with self.argument_context('acr repository untag') as c:
100        c.argument('image', options_list=['--image', '-t'], help="The name of the image. May include a tag in the format 'name:tag'.")
101
102    with self.argument_context('acr create') as c:
103        c.argument('registry_name', completer=None)
104        c.argument('deployment_name', validator=None)
105        c.argument('location', validator=get_default_location_from_resource_group)
106
107    with self.argument_context('acr check-name') as c:
108        c.argument('registry_name', completer=None)
109
110    with self.argument_context('acr webhook') as c:
111        c.argument('registry_name', options_list=['--registry', '-r'])
112        c.argument('webhook_name', options_list=['--name', '-n'], help='The name of the webhook', completer=get_resource_name_completion_list(WEBHOOK_RESOURCE_TYPE))
113        c.argument('uri', help='The service URI for the webhook to post notifications.')
114        c.argument('headers', nargs='+', help="Space-separated custom headers in 'key[=value]' format that will be added to the webhook notifications. Use {} to clear existing headers.".format(quotes), validator=validate_headers)
115        c.argument('actions', nargs='+', help='Space-separated list of actions that trigger the webhook to post notifications.', arg_type=get_enum_type(WebhookAction))
116        c.argument('status', help='Indicates whether the webhook is enabled.', arg_type=get_enum_type(WebhookStatus))
117        c.argument('scope', help="The scope of repositories where the event can be triggered. For example, 'foo:*' means events for all tags under repository 'foo'. 'foo:bar' means events for 'foo:bar' only. 'foo' is equivalent to 'foo:latest'. Empty means events for all repositories.")
118
119    with self.argument_context('acr webhook create') as c:
120        c.argument('webhook_name', completer=None)
121
122    with self.argument_context('acr replication') as c:
123        c.argument('registry_name', options_list=['--registry', '-r'])
124        c.argument('replication_name', options_list=['--name', '-n'], help='The name of the replication.', completer=get_resource_name_completion_list(REPLICATION_RESOURCE_TYPE))
125
126    with self.argument_context('acr replication create') as c:
127        c.argument('replication_name', help='The name of the replication. Default to the location name.', completer=None)
128
129    with self.argument_context('acr run') as c:
130        c.argument('registry_name', options_list=['--registry', '-r'])
131        c.positional('source_location', help="The local source code directory path (e.g., './src') or the URL to a git repository (e.g., 'https://github.com/Azure-Samples/acr-build-helloworld-node.git') or a remote tarball (e.g., 'http://server/context.tar.gz'). If '/dev/null' is specified, the value will be set to None and ignored.", completer=FilesCompleter())
132        c.argument('file', options_list=['--file', '-f'], help="The task template/definition file path relative to the source context. It can be '-' to pipe a file from the standard input.")
133        c.argument('values', help="The task values file path relative to the source context.")
134        c.argument('set_value', options_list=['--set'], help="Value in 'name[=value]' format. Multiples supported by passing --set multiple times.", action='append', validator=validate_set)
135        c.argument('set_secret', help="Secret value in '--set name[=value]' format. Multiples supported by passing --set multiple times.", action='append', validator=validate_set_secret)
136
137    with self.argument_context('acr pack build') as c:
138        c.argument('registry_name', options_list=['--registry', '-r'])
139        c.argument('image_name', options_list=['--image', '-t'], help="The name and tag of the image using the format: '-t repo/image:tag'.")
140        c.argument('builder', options_list=['--builder', '-b'], help="The name and tag of a Buildpack builder image.")
141        c.argument('pull', options_list=['--pull'], help="Pull the latest builder and run images before use.", action='store_true')
142        c.positional('source_location', help="The local source code directory path (e.g., './src') or the URL to a git repository (e.g., 'https://github.com/Azure-Samples/acr-build-helloworld-node.git') or a remote tarball (e.g., 'http://server/context.tar.gz').", completer=FilesCompleter())
143
144    with self.argument_context('acr build') as c:
145        c.argument('registry_name', options_list=['--registry', '-r'])
146        c.positional('source_location', help="The local source code directory path (e.g., './src') or the URL to a git repository (e.g., 'https://github.com/Azure-Samples/acr-build-helloworld-node.git') or a remote tarball (e.g., 'http://server/context.tar.gz').", completer=FilesCompleter())
147        c.argument('no_push', help="Indicates whether the image built should be pushed to the registry.", action='store_true')
148        c.argument('no_wait', help="Do not wait for the build to complete and return immediately after queuing the build.", action='store_true')
149        c.argument('arg', options_list=['--build-arg'], help="Build argument in '--build-arg name[=value]' format. Multiples supported by passing --build-arg multiple times.", action='append', validator=validate_arg)
150        c.argument('secret_arg', options_list=['--secret-build-arg'], help="Secret build argument in '--secret-build-arg name[=value]' format. Multiples supported by passing '--secret-build-arg name[=value]' multiple times.", action='append', validator=validate_secret_arg)
151
152    with self.argument_context('acr task') as c:
153        c.argument('registry_name', options_list=['--registry', '-r'])
154        c.argument('task_name', options_list=['--name', '-n'], help='The name of the task.', completer=get_resource_name_completion_list(TASK_RESOURCE_TYPE))
155        c.argument('status', help='The current status of task.', arg_type=get_enum_type(TaskStatus))
156        c.argument('with_secure_properties', help="Indicates whether the secure properties of a task should be returned.", action='store_true')
157
158        # DockerBuildStep, FileTaskStep parameters
159        c.argument('file', options_list=['--file', '-f'], help="The relative path of the the task/docker file to the source code root folder. Task files must be suffixed with '.yaml' or piped from the standard input using '-'.")
160        c.argument('image', arg_type=image_by_tag_or_digest_type)
161        c.argument('no_push', help="Indicates whether the image built should be pushed to the registry.", arg_type=get_three_state_flag())
162        c.argument('no_cache', help='Indicates whether the image cache is enabled.', arg_type=get_three_state_flag())
163        c.argument('values', help="The task values/parameters file path relative to the source context.")
164
165        # common to DockerBuildStep, FileTaskStep and RunTaskStep
166        c.argument('context_path', options_list=['--context', '-c'], help="The full URL to the source code repository (Requires '.git' suffix for a github repo). If '/dev/null' is specified, the value will be set to None and ignored.")
167        c.argument('arg', help="Build argument in '--arg name[=value]' format. Multiples supported by passing '--arg` multiple times.", action='append', validator=validate_arg)
168        c.argument('secret_arg', help="Secret build argument in '--secret-arg name[=value]' format. Multiples supported by passing --secret-arg multiple times.", action='append', validator=validate_secret_arg)
169        c.argument('set_value', options_list=['--set'], help="Task value in '--set name[=value]' format. Multiples supported by passing --set multiple times.", action='append', validator=validate_set)
170        c.argument('set_secret', help="Secret task value in '--set-secret name[=value]' format. Multiples supported by passing --set-secret multiple times.", action='append', validator=validate_set_secret)
171
172        # Source Trigger parameters
173        c.argument('source_trigger_name', help="The name of the source trigger.")
174        c.argument('commit_trigger_enabled', help="Indicates whether the source control commit trigger is enabled.", arg_type=get_three_state_flag())
175        c.argument('pull_request_trigger_enabled', help="Indicates whether the source control pull request trigger is enabled.", arg_type=get_three_state_flag())
176        c.argument('git_access_token', help="The access token used to access the source control provider.")
177        c.argument('branch', help="The source control branch name.")
178        c.argument('base_image_trigger_name', help="The name of the base image trigger.")
179        c.argument('base_image_trigger_enabled', help="Indicates whether the base image trigger is enabled.", arg_type=get_three_state_flag())
180        c.argument('base_image_trigger_type', help="The type of the auto trigger for base image dependency updates.", arg_type=get_enum_type(BaseImageTriggerType))
181
182        # Run related parameters
183        c.argument('top', help='Limit the number of latest runs in the results.')
184        c.argument('run_id', help='The unique run identifier.')
185        c.argument('run_status', help='The current status of run.', arg_type=get_enum_type(RunStatus))
186        c.argument('no_archive', help='Indicates whether the run should be archived.', arg_type=get_three_state_flag())
187
188        # Run agent parameters
189        c.argument('cpu', type=int, help='The CPU configuration in terms of number of cores required for the run.')
190
191        # MSI parameter
192        c.argument('assign_identity', nargs='*', help="Assigns managed identities to the task. Use '[system]' to refer to the system-assigned identity or a resource ID to refer to a user-assigned identity.")
193
194    with self.argument_context('acr task create') as c:
195        c.argument('task_name', completer=None)
196
197    with self.argument_context('acr task identity') as c:
198        c.argument('identities', options_list=['--identities'], nargs='*', help="Assigns managed identities to the task. Use '[system]' to refer to the system-assigned identity or a resource ID to refer to a user-assigned identity.")
199
200    with self.argument_context('acr task credential') as c:
201        # Custom registry credentials
202        c.argument('login_server', help="The login server of the custom registry. For instance, 'myregistry.azurecr.io'.", required=True)
203
204    for scope in ['acr task credential add', 'acr task credential update']:
205        with self.argument_context(scope) as c:
206            c.argument('username', options_list=['--username', '-u'], help="The username to login to the custom registry. This can be plain text or a key vault secret URI.")
207            c.argument('password', options_list=['--password', '-p'], help="The password to login to the custom registry. This can be plain text or a key vault secret URI.")
208            c.argument('use_identity', help="The task managed identity used for the credential. Use '[system]' to refer to the system-assigned identity or a client id to refer to a user-assigned identity.")
209
210    with self.argument_context('acr helm') as c:
211        c.argument('resource_group_name', deprecate_info=c.deprecate(hide=True))
212        c.argument('repository', help=argparse.SUPPRESS)
213        c.argument('version', help='The helm chart version.')
214
215    with self.argument_context('acr helm show') as c:
216        c.positional('chart', help='The helm chart name.')
217
218    with self.argument_context('acr helm delete') as c:
219        c.positional('chart', help='The helm chart name.')
220        c.argument('prov', help='Only delete the provenance file.', action='store_true')
221
222    with self.argument_context('acr helm push') as c:
223        c.positional('chart_package', help="The helm chart package.", completer=FilesCompleter())
224        c.argument('force', help='Overwrite the existing chart package.', action='store_true')
225
226    with self.argument_context('acr network-rule') as c:
227        c.argument('subnet', help='Name or ID of subnet. If name is supplied, `--vnet-name` must be supplied.')
228        c.argument('vnet_name', help='Name of a virtual network.')
229        c.argument('ip_address', help='IPv4 address or CIDR range.')
230
231    with self.argument_context('acr check-health') as c:
232        c.argument('ignore_errors', options_list=['--ignore-errors'], help='Ignore errors, displaying them only at the final', action='store_true', required=False)
233