-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[ACR] Add managed registries, webhooks, AAD auth, and repository delete #3747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3747 +/- ##
==========================================
- Coverage 72.12% 70.98% -1.15%
==========================================
Files 420 424 +4
Lines 26044 26890 +846
Branches 3945 4092 +147
==========================================
+ Hits 18785 19087 +302
- Misses 6042 6565 +523
- Partials 1217 1238 +21
Continue to review full report at Codecov.
|
|
/cc @listonb |
|
LGTM |
|
LGTM! Thanks for adding the docker exec check! Excellent additions to the cli! |
derekbekoe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Questions about use of Docker in the Docker install of the CLI.
Dockerfile
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What scenario is this for? The user could run apk add docker if they need docker.
It adds close to 100MB to our Docker image.
https://pkgs.alpinelinux.org/package/v3.6/community/aarch64/docker
356MB -> 433MB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docker is needed for acr login command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work inside the Docker install of Azure CLI?
I get this:
# docker login --username username --password "mypassword"
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
#
I get that error message for almost all Docker commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will need to run the container with
docker run -it -v /var/run/docker.sock:/var/run/docker.sock azuresdk/azure-cli-python
Also apk add docker if docker is not installed in the container.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay thanks for removing it from the Dockerfile.
derekbekoe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this arg pick up the default registry name if it's configured? The help text below doesn't seem to indicate it does, and it would be ideal to have it be defaulted when the ACR default is set.
|
Please rebase your changes and resolve the conflicts. |
* expose refresh token retrieving mechanism in profile * added unit tests for refresh token operations
troydai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides the questions regarding SDK - API version mechanism, I notice the code is formatted following a narrower line length limitation. The current line limitation is 120, you can fully utilize the room on one line to produce more condense code.
|
|
||
|
|
||
| def get_acr_service_client(): | ||
| def get_acr_service_client(api_version='2017-03-01'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if customized_api_version: | ||
| logger.warning('Customized api-version is used: %s', customized_api_version) | ||
| return customized_api_version | ||
| return get_mgmt_service_client(ContainerRegistryManagementClient, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The line length limitation is 120 so you don't have to break the line here.
| from azure.cli.core.util import CLIError | ||
| from azure.cli.core.commands.parameters import get_resources_in_subscription | ||
|
|
||
| from azure.mgmt.containerregistry.v2017_03_01.models import SkuTier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use
| def get_sdk(resource_type, *attr_args, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are using multiple api-version SDK to direct registry creation calls to different versions based on SKU. Basically, Basic SKU will go to 2017-03-01 version and Managed SKUs will go to 2017-06-01-preview. At this point there is no need to expose multiple api-versions to users and the user specified SKU is enough to determine which api-version to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@derekbekoe
In this case, when user set CLI to be executed on an older version of API profile, will these commands be hidden from users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, this PR is not related to API profile. We simply direct calls to different api-versions based on SKU selection, but I will let @derekbekoe comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some API versions may be missing in Azure Stack or different cloud. Will the command fail in those environments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from azure.cli.core.util import CLIError | ||
| from azure.cli.core.commands.parameters import get_resources_in_subscription | ||
|
|
||
| from azure.mgmt.containerregistry.v2017_03_01.models import SkuTier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@derekbekoe
In this case, when user set CLI to be executed on an older version of API profile, will these commands be hidden from users?
| """ | ||
| arm_resource = _arm_get_resource_by_name(registry_name, ACR_RESOURCE_TYPE) | ||
| return get_resource_group_name_by_resource_id(arm_resource.id) | ||
| if resource_group_name is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not resource_group_name
Unless an empty group name is legal, which I don't think should be the case.
| :param str storage_account_name: The name of storage account | ||
| :param str resource_group_name: The name of resource group | ||
| """ | ||
| if resource_group_name is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
| arm_resource = _arm_get_resource_by_name(registry_name, ACR_RESOURCE_TYPE) | ||
|
|
||
| if arm_resource.sku.tier == SkuTier.basic.value: | ||
| raise CLIError(message if message else "This operation is not supported for registries in Basic SKU.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raise CLIError(message or "This operation is not supported for registries in Basic SKU.")
| ) | ||
| instance.storage_account = storage_account if storage_account_name else None | ||
|
|
||
| if admin_enabled is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if admin_enable. In this case, when admin_enable is empty, it must yield negative result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
admin_enabled has a choice of either true or false and it does yield negative result if it is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. but it is actually weird that a bool parameter is not represented by a "switch" option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, we will need a pair of switch options support both enable and disable admin user. We used to have it implemented that way (in fact in Powershell cmdlets we still have a pair of switch parameters) but was updated to the current implementation as suggested.
| if admin_enabled is not None: | ||
| instance.admin_user_enabled = admin_enabled == 'true' | ||
|
|
||
| if tags is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is tag allowed to be an empty string? Otherwise, use if tags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, empty clears tags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
| """ | ||
| registry, resource_group_name = get_registry_by_name(registry_name, resource_group_name) | ||
|
|
||
| if parameters.storage_account is not None and registry.sku.name != SkuTier.basic.value: # pylint: disable=no-member |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if parameters.storage_account and ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now, if the specified storage account name is empty, we error out by saying that the storage account (with empty name) couldn't be found, which I think is the right behavior. If we make it the way you suggested, the command will go through but ignore the specified storage account. I personally think empty name is a negative scenario and should error out rather than ignore, what is the guideline here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The truthiness of an empty string is False. Both None and empty in my opinion should render the same failed result.
| logger.warning("'%s' SKU are managed registries. " + | ||
| "The specified storage account will be ignored.", registry.sku.name) # pylint: disable=no-member | ||
|
|
||
| if parameters.storage_account is not None and isinstance(parameters.storage_account, dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
|
|
||
| # 1. if username was specified, verify that password was also specified | ||
| if username: | ||
| if not password: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if username and not password:
|
|
||
|
|
||
| def acr_webhook_list(registry_name, | ||
| resource_group_name=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same line.
|
Most of my comments are about the truthiness in the condition when a string is in place. They're all about whether the empty strings should be treated as the legal values. Other than that the one outstanding question is whether the commands with a hard requirement of api version will be hidden when user switch to an older API profile. That is the case in Azure Stack. |
derekbekoe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| from azure.cli.core.util import CLIError | ||
| from azure.cli.core.commands.parameters import get_resources_in_subscription | ||
|
|
||
| from azure.mgmt.containerregistry.v2017_03_01.models import SkuTier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes #2445 Azure/acr#33
Includes #3734
This checklist is used to make sure that common guidelines for a pull request are followed.
General Guidelines
Command Guidelines
(see Authoring Command Modules)