-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[Spring-cloud] Add support for AppMSI #4598
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
Merged
zhoxing-ms
merged 48 commits into
Azure:main
from
jiec-msft:mason/appmsi-on-cli_sdk_2022_03_01_pre_only
Mar 31, 2022
Merged
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
c7cb17f
use 2022-03-01-preview sdk for app command and app identity command,…
jiec-msft de0e5b5
Add a temp version number
jiec-msft 55c648b
Add params definition for identity remove
jiec-msft 32bc31a
refine help and example for command group
jiec-msft 1970509
refine help and example for command group
jiec-msft b3489f8
refine help and example for command group
jiec-msft 7ee755a
add support to remove user-assigned managed identities.
jiec-msft f580a8b
mark user-assigned as preview for identity remove
jiec-msft a6887c3
refine identity remove
jiec-msft 5ef4853
For identity assign
jiec-msft 65b56dc
For identity assign: implement
jiec-msft f5f6ecf
refactor and add UT and add scenario test
jiec-msft 0c87272
refine help info for app identity
jiec-msft ec22e89
hide role and scope from help info
jiec-msft 9e7341d
For app create with managed identity:
jiec-msft 94256b8
For app create with managed identity:
jiec-msft a0b7553
For app create with managed identity:
jiec-msft 29df6b3
For app create with managed identity:
jiec-msft 9ba7038
For app create with managed identity:
jiec-msft 7a72f2d
For app create with managed identity:
jiec-msft 310160e
For app identity force-set managed identity:
jiec-msft 6202d84
For app identity force-set managed identity:
jiec-msft 467ccf9
For app identity force-set managed identity:
jiec-msft 4fc72df
remove not used import
jiec-msft 243f0c4
fix role assignment bugs
jiec-msft 71e3b0e
refine payload for force-set identities
jiec-msft 3d6d9de
switch app show to use 2022-03-01-preview api version
jiec-msft 8c0a61b
update deprecation info for role param
jiec-msft 7b2eca7
refactor code
jiec-msft 6d9975a
simplify force-set
jiec-msft 125b6de
add version number
jiec-msft 041b50a
refactor "updating" and "deleting"
jiec-msft 218ca02
fix bug for async operation
jiec-msft 4b74aaf
update version info
jiec-msft 77ad4a2
Update version number
jiec-msft f5bf0cd
Update version to build a extension for testing team
jiec-msft 69e9b17
refine warning: in the future -> in future
jiec-msft 06a2cb3
refine help info for force-set params
jiec-msft 16de216
refine example description for command force-set
jiec-msft 37e67a2
refactor _format_identity in _app_factory
jiec-msft 6510f0c
add scope and role from deprecated back to supported status in help i…
jiec-msft 4906437
add example for role assignment for system-assigned managed identity.
jiec-msft 0ff6f55
update version number for testing
jiec-msft 50e7280
update version number and history.
jiec-msft 5e3e36e
fix lint
jiec-msft d7a9b04
refine the CLIError, and categorize into different types
jiec-msft 30b56dd
refine the CLIError, and categorize into different types
jiec-msft 64b93ff
fix lint 2
jiec-msft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
src/spring-cloud/azext_spring_cloud/_app_managed_identity_validator.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
|
|
||
|
|
||
| from azure.cli.core.azclierror import InvalidArgumentValueError | ||
| from azure.mgmt.core.tools import is_valid_resource_id | ||
| from knack.log import get_logger | ||
|
|
||
|
|
||
| logger = get_logger(__name__) | ||
|
|
||
|
|
||
| OBSOLETE_APP_IDENTITY_REMOVE = "Remove managed identities without \"system-assigned\" or \"user-assigned\" parameters is obsolete, will only remove system-assigned managed identity, and will not be supported in a future release." | ||
| WARNING_NO_USER_IDENTITY_RESOURCE_ID = "No resource ID of user-assigned managed identity is given for parameter \"user-assigned\", will remove ALL user-assigned managed identities." | ||
| OBSOLETE_APP_IDENTITY_ASSIGN = "Assign managed identities without \"system-assigned\" or \"user-assigned\" parameters is obsolete, will only enable system-assigned managed identity, and will not be supported in a future release." | ||
| ENABLE_LOWER = "enable" | ||
| DISABLE_LOWER = "disable" | ||
|
|
||
|
|
||
| def validate_app_identity_remove_or_warning(namespace): | ||
| if namespace.system_assigned is None and namespace.user_assigned is None: | ||
| logger.warning(OBSOLETE_APP_IDENTITY_REMOVE) | ||
| if namespace.user_assigned is not None: | ||
| if not isinstance(namespace.user_assigned, list): | ||
| raise InvalidArgumentValueError("Parameter value for \"user-assigned\" should be empty or a list of space-separated managed identity resource ID.") | ||
| if len(namespace.user_assigned) == 0: | ||
| logger.warning(WARNING_NO_USER_IDENTITY_RESOURCE_ID) | ||
| namespace.user_assigned = _normalized_user_identitiy_resource_id_list(namespace.user_assigned) | ||
| for resource_id in namespace.user_assigned: | ||
| is_valid = _is_valid_user_assigned_managed_identity_resource_id(resource_id) | ||
| if not is_valid: | ||
| raise InvalidArgumentValueError("Invalid user-assigned managed identity resource ID \"{}\".".format(resource_id)) | ||
|
|
||
|
|
||
| def _normalized_user_identitiy_resource_id_list(user_identity_resource_id_list): | ||
| result = [] | ||
| if not user_identity_resource_id_list: | ||
| return result | ||
| for id in user_identity_resource_id_list: | ||
| result.append(id.strip().lower()) | ||
| return result | ||
|
|
||
|
|
||
| def _is_valid_user_assigned_managed_identity_resource_id(resource_id): | ||
| if not is_valid_resource_id(resource_id.lower()): | ||
| return False | ||
| if "/providers/Microsoft.ManagedIdentity/userAssignedIdentities/".lower() not in resource_id.lower(): | ||
| return False | ||
| return True | ||
|
|
||
|
|
||
| def validate_app_identity_assign_or_warning(namespace): | ||
| _warn_if_no_identity_type_params(namespace) | ||
| _validate_role_and_scope_should_use_together(namespace) | ||
| _validate_role_and_scope_should_not_use_with_user_identity(namespace) | ||
| _validate_user_identity_resource_id(namespace) | ||
| _normalize_user_identity_resource_id(namespace) | ||
|
|
||
|
|
||
| def _warn_if_no_identity_type_params(namespace): | ||
| if namespace.system_assigned is None and namespace.user_assigned is None: | ||
| logger.warning(OBSOLETE_APP_IDENTITY_ASSIGN) | ||
|
|
||
|
|
||
| def _validate_role_and_scope_should_use_together(namespace): | ||
| if _has_role_or_scope(namespace) and not _has_role_and_scope(namespace): | ||
| raise InvalidArgumentValueError("Parameter \"role\" and \"scope\" should be used together.") | ||
|
|
||
|
|
||
| def _validate_role_and_scope_should_not_use_with_user_identity(namespace): | ||
| if _has_role_and_scope(namespace) and _only_has_user_assigned(namespace): | ||
| raise InvalidArgumentValueError("Invalid to use parameter \"role\" and \"scope\" with \"user-assigned\" parameter.") | ||
|
|
||
|
|
||
| def _has_role_and_scope(namespace): | ||
| return namespace.role and namespace.scope | ||
|
|
||
|
|
||
| def _has_role_or_scope(namespace): | ||
| return namespace.role or namespace.scope | ||
|
|
||
|
|
||
| def _only_has_user_assigned(namespace): | ||
| return (namespace.user_assigned) and (not namespace.system_assigned) | ||
|
|
||
|
|
||
| def _validate_user_identity_resource_id(namespace): | ||
| if namespace.user_assigned: | ||
| for resource_id in namespace.user_assigned: | ||
| if not _is_valid_user_assigned_managed_identity_resource_id(resource_id): | ||
| raise InvalidArgumentValueError("Invalid user-assigned managed identity resource ID \"{}\".".format(resource_id)) | ||
|
|
||
|
|
||
| def _normalize_user_identity_resource_id(namespace): | ||
| if namespace.user_assigned: | ||
| namespace.user_assigned = _normalized_user_identitiy_resource_id_list(namespace.user_assigned) | ||
|
|
||
|
|
||
| def validate_create_app_with_user_identity_or_warning(namespace): | ||
| _validate_user_identity_resource_id(namespace) | ||
| _normalize_user_identity_resource_id(namespace) | ||
|
|
||
|
|
||
| def validate_create_app_with_system_identity_or_warning(namespace): | ||
| """ | ||
| Note: assign_identity is deprecated, use system_assigned instead. | ||
| """ | ||
| if namespace.system_assigned is not None and namespace.assign_identity is not None: | ||
| raise InvalidArgumentValueError('Parameter "system-assigned" should not use together with "assign-identity".') | ||
| if namespace.assign_identity is not None: | ||
| namespace.system_assigned = namespace.assign_identity | ||
|
|
||
|
|
||
| def validate_app_force_set_system_identity_or_warning(namespace): | ||
| if namespace.system_assigned is None: | ||
| raise InvalidArgumentValueError('Parameter "system-assigned" expected at least one argument.') | ||
| namespace.system_assigned = namespace.system_assigned.strip().lower() | ||
| if namespace.system_assigned.strip().lower() not in (ENABLE_LOWER, DISABLE_LOWER): | ||
| raise InvalidArgumentValueError('Allowed values for "system-assigned" are: {}, {}.'.format(ENABLE_LOWER, DISABLE_LOWER)) | ||
|
|
||
|
|
||
| def validate_app_force_set_user_identity_or_warning(namespace): | ||
| if namespace.user_assigned is None or len(namespace.user_assigned) == 0: | ||
| raise InvalidArgumentValueError('Parameter "user-assigned" expected at least one argument.') | ||
| if len(namespace.user_assigned) == 1: | ||
| single_element = namespace.user_assigned[0].strip().lower() | ||
| if single_element != DISABLE_LOWER and not _is_valid_user_assigned_managed_identity_resource_id(single_element): | ||
| raise InvalidArgumentValueError('Allowed values for "user-assigned" are: {}, space-separated user-assigned managed identity resource IDs.'.format(DISABLE_LOWER)) | ||
| elif single_element == DISABLE_LOWER: | ||
| namespace.user_assigned = [DISABLE_LOWER] | ||
| else: | ||
| _normalize_user_identity_resource_id(namespace) | ||
| else: | ||
| _validate_user_identity_resource_id(namespace) | ||
| _normalize_user_identity_resource_id(namespace) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
|
|
||
| from azure.cli.core.azclierror import UserFault | ||
|
|
||
|
|
||
| class ConflictRequestError(UserFault): | ||
| """ Conflict request: 409 error """ | ||
| pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 do we need this command? Can its function be replaced by the
spring-cloud app identity removecommand?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.
Normally we don't need these commands. It's related to a data consistency problem among managed identity RP and my RP. There can be case when user identity is assigned to an app in my side, but deleted in managed identity RP due to data in-consistency. These commands leverage put method to reset data back with one command.
app identity remove/assign is done with patch http method, there can be case, there is no identity assigned to an app in my RP, but managed identity RP still has some identity assigned to the app.
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.
Got it, thanks~