diff --git a/src/azure-cli/azure/cli/command_modules/identity/__init__.py b/src/azure-cli/azure/cli/command_modules/identity/__init__.py index 63f5d8f56a4..c730e0659ee 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/__init__.py +++ b/src/azure-cli/azure/cli/command_modules/identity/__init__.py @@ -19,6 +19,17 @@ def __init__(self, cli_ctx=None): def load_command_table(self, args): from azure.cli.command_modules.identity.commands import load_command_table + from azure.cli.core.aaz import load_aaz_command_table + try: + from . import aaz + except ImportError: + aaz = None + if aaz: + load_aaz_command_table( + loader=self, + aaz_pkg_name=aaz.__name__, + args=args + ) load_command_table(self, args) return self.command_table diff --git a/src/azure-cli/azure/cli/command_modules/identity/_client_factory.py b/src/azure-cli/azure/cli/command_modules/identity/_client_factory.py index a549775369d..ab149ee88ea 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/identity/_client_factory.py @@ -24,7 +24,3 @@ def _msi_user_identities_operations(cli_ctx, _): def _msi_operations_operations(cli_ctx, _): return _msi_client_factory(cli_ctx).operations - - -def _msi_federated_identity_credentials_operations(cli_ctx, _): - return _msi_client_factory(cli_ctx).federated_identity_credentials diff --git a/src/azure-cli/azure/cli/command_modules/identity/_help.py b/src/azure-cli/azure/cli/command_modules/identity/_help.py index 44949e01792..fe7858fb7f7 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/_help.py +++ b/src/azure-cli/azure/cli/command_modules/identity/_help.py @@ -35,53 +35,3 @@ type: command short-summary: List the associated resources for the identity. """ - -helps['identity federated-credential'] = """ -type: group -short-summary: Manage federated identity credentials under user assigned identities. -""" - -helps['identity federated-credential create'] = """ -type: command -short-summary: Create a federated identity credential under an existing user assigned identity. -examples: - - name: Create a federated identity credential under a specific user assigned identity. - text: | - az identity federated-credential create --name myFicName --identity-name myIdentityName --resource-group myResourceGroup --issuer myIssuer --subject mySubject --audiences myAudiences -""" - -helps['identity federated-credential update'] = """ -type: command -short-summary: Update a federated identity credential under an existing user assigned identity. -examples: - - name: Update a federated identity credential under a specific user assigned identity. - text: | - az identity federated-credential update --name myFicName --identity-name myIdentityName --resource-group myResourceGroup --issuer myIssuer --subject mySubject --audiences myAudiences -""" - -helps['identity federated-credential delete'] = """ -type: command -short-summary: Delete a federated identity credential under an existing user assigned identity. -examples: - - name: Delete a federated identity credential under a specific user assigned identity. - text: | - az identity federated-credential delete --name myFicName --identity-name myIdentityName --resource-group myResourceGroup -""" - -helps['identity federated-credential show'] = """ -type: command -short-summary: Show a federated identity credential under an existing user assigned identity. -examples: - - name: Show a federated identity credential under a specific user assigned identity. - text: | - az identity federated-credential show --name myFicName --identity-name myIdentityName --resource-group myResourceGroup -""" - -helps['identity federated-credential list'] = """ -type: command -short-summary: List all federated identity credentials under an existing user assigned identity. -examples: - - name: List all federated identity credentials under an existing user assigned identity. - text: | - az identity federated-credential list --identity-name myIdentityName --resource-group myResourceGroup -""" diff --git a/src/azure-cli/azure/cli/command_modules/identity/_params.py b/src/azure-cli/azure/cli/command_modules/identity/_params.py index 9ff9aaee2bc..1754b44b061 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/_params.py +++ b/src/azure-cli/azure/cli/command_modules/identity/_params.py @@ -8,7 +8,6 @@ from azure.cli.core.commands.parameters import get_location_type, tags_type - name_arg_type = CLIArgumentType(options_list=('--name', '-n'), metavar='NAME', help='The name of the identity resource.') @@ -21,13 +20,3 @@ def load_arguments(self, _): with self.argument_context('identity create') as c: c.argument('location', get_location_type(self.cli_ctx), required=False) c.argument('tags', tags_type) - - with self.argument_context('identity federated-credential', min_api='2022-01-31-preview') as c: - c.argument('federated_credential_name', options_list=('--name', '-n'), help='The name of the federated identity credential resource.') - c.argument('identity_name', help='The name of the identity resource.') - - for scope in ['identity federated-credential create', 'identity federated-credential update']: - with self.argument_context(scope) as c: - c.argument('issuer', help='The openId connect metadata URL of the issuer of the identity provider that Azure AD would use in the token exchange protocol for validating tokens before issuing a token as the user-assigned managed identity.') - c.argument('subject', help='The sub value in the token sent to Azure AD for getting the user-assigned managed identity token. The value configured in the federated credential and the one in the incoming token must exactly match for Azure AD to issue the access token.') - c.argument('audiences', nargs='+', help='The aud value in the token sent to Azure for getting the user-assigned managed identity token. The value configured in the federated credential and the one in the incoming token must exactly match for Azure to issue the access token.') diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/__init__.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/__init__.py new file mode 100644 index 00000000000..5757aea3175 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/__init__.py @@ -0,0 +1,6 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/__init__.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/__init__.py new file mode 100644 index 00000000000..f6acc11aa4e --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/__init__.py @@ -0,0 +1,10 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/__cmd_group.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/__cmd_group.py new file mode 100644 index 00000000000..c64b4d3056b --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/__cmd_group.py @@ -0,0 +1,23 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command_group( + "identity", +) +class __CMDGroup(AAZCommandGroup): + """Manage Managed Identity + """ + pass + + +__all__ = ["__CMDGroup"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/__init__.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/__init__.py new file mode 100644 index 00000000000..5a9d61963d6 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/__init__.py @@ -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. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from .__cmd_group import * diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/__cmd_group.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/__cmd_group.py new file mode 100644 index 00000000000..d6f97e35d52 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/__cmd_group.py @@ -0,0 +1,23 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command_group( + "identity federated-credential", +) +class __CMDGroup(AAZCommandGroup): + """Manage federated identity credentials under user assigned identities. + """ + pass + + +__all__ = ["__CMDGroup"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/__init__.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/__init__.py new file mode 100644 index 00000000000..c401f439385 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/__init__.py @@ -0,0 +1,16 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from .__cmd_group import * +from ._create import * +from ._delete import * +from ._list import * +from ._show import * +from ._update import * diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_create.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_create.py new file mode 100644 index 00000000000..17be02521dc --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_create.py @@ -0,0 +1,307 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "identity federated-credential create", +) +class Create(AAZCommand): + """Create a federated identity credential under an existing user assigned identity. + + :example: Create a federated identity credential under a specific user assigned identity using subject. + az identity federated-credential create --name myFicName --identity-name myIdentityName --resource-group myResourceGroup --issuer myIssuer --subject mySubject --audiences myAudiences + + :example: Create a federated identity credential under a specific user assigned identity using claimsMatchingExpression. + az identity federated-credential create --name myFicName --identity-name myIdentityName --resource-group myResourceGroup --issuer myIssuer --claims-matching-expression-version 1 --claims-matching-expression-value "claims['sub'] eq 'foo'" --audiences myAudiences + """ + + _aaz_info = { + "version": "2025-01-31-preview", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.managedidentity/userassignedidentities/{}/federatedidentitycredentials/{}", "2025-01-31-preview"], + ] + } + + def _handler(self, command_args): + super()._handler(command_args) + self._execute_operations() + return self._output() + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.name = AAZStrArg( + options=["-n", "--name"], + help="The name of the federated identity credential resource.", + required=True, + fmt=AAZStrArgFormat( + pattern="^[a-zA-Z0-9]{1}[a-zA-Z0-9-_]{2,119}$", + ), + ) + _args_schema.resource_group = AAZResourceGroupNameArg( + help="Name of resource group. You can configure the default group using `az configure --defaults group=`.", + required=True, + ) + _args_schema.identity_name = AAZStrArg( + options=["--identity-name"], + help="The name of the identity resource.", + required=True, + ) + + # define Arg Group "ClaimsMatchingExpression" + + _args_schema = cls._args_schema + _args_schema.claims_matching_expression_version = AAZIntArg( + options=["--cme-version", "--claims-matching-expression-version"], + arg_group="ClaimsMatchingExpression", + help="Specifies the version of the claims matching expression used in the expression.", + is_preview=True, + ) + _args_schema.claims_matching_expression_value = AAZStrArg( + options=["--cme-value", "--claims-matching-expression-value"], + arg_group="ClaimsMatchingExpression", + help="The wildcard-based expression for matching incoming claims. Cannot be used with --subject.", + is_preview=True, + ) + + # define Arg Group "Properties" + + _args_schema = cls._args_schema + _args_schema.audiences = AAZListArg( + options=["--audiences"], + arg_group="Properties", + help="The aud value in the token sent to Azure for getting the user-assigned managed identity token. The value configured in the federated credential and the one in the incoming token must exactly match for Azure to issue the access token.", + ) + _args_schema.issuer = AAZStrArg( + options=["--issuer"], + arg_group="Properties", + help="The openId connect metadata URL of the issuer of the identity provider that Azure AD would use in the token exchange protocol for validating tokens before issuing a token as the user-assigned managed identity.", + ) + _args_schema.subject = AAZStrArg( + options=["--subject"], + arg_group="Properties", + help="The sub value in the token sent to Azure AD for getting the user-assigned managed identity token. The value configured in the federated credential and the one in the incoming token must exactly match for Azure AD to issue the access token. Either 'subject' or 'claimsMatchingExpression' must be defined, but not both.", + ) + + audiences = cls._args_schema.audiences + audiences.Element = AAZStrArg() + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.FederatedIdentityCredentialsCreateOrUpdate(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True) + return result + + class FederatedIdentityCredentialsCreateOrUpdate(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200, 201]: + return self.on_200_201(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}", + **self.url_parameters + ) + + @property + def method(self): + return "PUT" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "federatedIdentityCredentialResourceName", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), + **self.serialize_url_param( + "resourceName", self.ctx.args.identity_name, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2025-01-31-preview", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Content-Type", "application/json", + ), + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + @property + def content(self): + _content_value, _builder = self.new_content_builder( + self.ctx.args, + typ=AAZObjectType, + typ_kwargs={"flags": {"required": True, "client_flatten": True}} + ) + _builder.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}}) + + properties = _builder.get(".properties") + if properties is not None: + properties.set_prop("audiences", AAZListType, ".audiences", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("claimsMatchingExpression", AAZObjectType) + properties.set_prop("issuer", AAZStrType, ".issuer", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("subject", AAZStrType, ".subject") + + audiences = _builder.get(".properties.audiences") + if audiences is not None: + audiences.set_elements(AAZStrType, ".") + + claims_matching_expression = _builder.get(".properties.claimsMatchingExpression") + if claims_matching_expression is not None: + claims_matching_expression.set_prop("languageVersion", AAZIntType, ".claims_matching_expression_version", typ_kwargs={"flags": {"required": True}}) + claims_matching_expression.set_prop("value", AAZStrType, ".claims_matching_expression_value", typ_kwargs={"flags": {"required": True}}) + + return self.serialize_content(_content_value) + + def on_200_201(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200_201 + ) + + _schema_on_200_201 = None + + @classmethod + def _build_schema_on_200_201(cls): + if cls._schema_on_200_201 is not None: + return cls._schema_on_200_201 + + cls._schema_on_200_201 = AAZObjectType() + + _schema_on_200_201 = cls._schema_on_200_201 + _schema_on_200_201.id = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200_201.name = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200_201.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _schema_on_200_201.system_data = AAZObjectType( + serialized_name="systemData", + flags={"read_only": True}, + ) + _schema_on_200_201.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200_201.properties + properties.audiences = AAZListType( + flags={"required": True}, + ) + properties.claims_matching_expression = AAZObjectType( + serialized_name="claimsMatchingExpression", + ) + properties.issuer = AAZStrType( + flags={"required": True}, + ) + properties.subject = AAZStrType() + + audiences = cls._schema_on_200_201.properties.audiences + audiences.Element = AAZStrType() + + claims_matching_expression = cls._schema_on_200_201.properties.claims_matching_expression + claims_matching_expression.language_version = AAZIntType( + serialized_name="languageVersion", + flags={"required": True}, + ) + claims_matching_expression.value = AAZStrType( + flags={"required": True}, + ) + + system_data = cls._schema_on_200_201.system_data + system_data.created_at = AAZStrType( + serialized_name="createdAt", + ) + system_data.created_by = AAZStrType( + serialized_name="createdBy", + ) + system_data.created_by_type = AAZStrType( + serialized_name="createdByType", + ) + system_data.last_modified_at = AAZStrType( + serialized_name="lastModifiedAt", + ) + system_data.last_modified_by = AAZStrType( + serialized_name="lastModifiedBy", + ) + system_data.last_modified_by_type = AAZStrType( + serialized_name="lastModifiedByType", + ) + + return cls._schema_on_200_201 + + +class _CreateHelper: + """Helper class for Create""" + + +__all__ = ["Create"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_delete.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_delete.py new file mode 100644 index 00000000000..f6ec60344b4 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_delete.py @@ -0,0 +1,151 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "identity federated-credential delete", + confirmation="Are you sure you want to perform this operation?", +) +class Delete(AAZCommand): + """Delete a federated identity credential under an existing user assigned identity. + + :example: Delete a federated identity credential under a specific user assigned identity. + az identity federated-credential delete --name myFicName --identity-name myIdentityName --resource-group myResourceGroup + """ + + _aaz_info = { + "version": "2025-01-31-preview", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.managedidentity/userassignedidentities/{}/federatedidentitycredentials/{}", "2025-01-31-preview"], + ] + } + + def _handler(self, command_args): + super()._handler(command_args) + self._execute_operations() + return None + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.name = AAZStrArg( + options=["-n", "--name"], + help="The name of the federated identity credential resource.", + required=True, + fmt=AAZStrArgFormat( + pattern="^[a-zA-Z0-9]{1}[a-zA-Z0-9-_]{2,119}$", + ), + ) + _args_schema.resource_group = AAZResourceGroupNameArg( + help="Name of resource group. You can configure the default group using `az configure --defaults group=`.", + required=True, + ) + _args_schema.identity_name = AAZStrArg( + options=["--identity-name"], + help="The name of the identity resource.", + required=True, + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.FederatedIdentityCredentialsDelete(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + class FederatedIdentityCredentialsDelete(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200]: + return self.on_200(session) + if session.http_response.status_code in [204]: + return self.on_204(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}", + **self.url_parameters + ) + + @property + def method(self): + return "DELETE" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "federatedIdentityCredentialResourceName", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), + **self.serialize_url_param( + "resourceName", self.ctx.args.identity_name, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2025-01-31-preview", + required=True, + ), + } + return parameters + + def on_200(self, session): + pass + + def on_204(self, session): + pass + + +class _DeleteHelper: + """Helper class for Delete""" + + +__all__ = ["Delete"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_list.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_list.py new file mode 100644 index 00000000000..09da3eeffe5 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_list.py @@ -0,0 +1,252 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "identity federated-credential list", +) +class List(AAZCommand): + """List all federated identity credentials under an existing user assigned identity. + + :example: List all federated identity credentials under an existing user assigned identity. + az identity federated-credential list --identity-name myIdentityName --resource-group myResourceGroup + """ + + _aaz_info = { + "version": "2025-01-31-preview", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.managedidentity/userassignedidentities/{}/federatedidentitycredentials", "2025-01-31-preview"], + ] + } + + AZ_SUPPORT_PAGINATION = True + + def _handler(self, command_args): + super()._handler(command_args) + return self.build_paging(self._execute_operations, self._output) + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.resource_group = AAZResourceGroupNameArg( + help="Name of resource group. You can configure the default group using `az configure --defaults group=`.", + required=True, + ) + _args_schema.identity_name = AAZStrArg( + options=["--identity-name"], + help="The name of the identity resource.", + required=True, + ) + _args_schema.skiptoken = AAZStrArg( + options=["--skiptoken"], + help="A skip token is used to continue retrieving items after an operation returns a partial result. If a previous response contains a nextLink element, the value of the nextLink element will include a skipToken parameter that specifies a starting point to use for subsequent calls.", + ) + _args_schema.top = AAZIntArg( + options=["--top"], + help="Number of records to return.", + fmt=AAZIntArgFormat( + minimum=1, + ), + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.FederatedIdentityCredentialsList(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance.value, client_flatten=True) + next_link = self.deserialize_output(self.ctx.vars.instance.next_link) + return result, next_link + + class FederatedIdentityCredentialsList(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200]: + return self.on_200(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), + **self.serialize_url_param( + "resourceName", self.ctx.args.identity_name, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "$skiptoken", self.ctx.args.skiptoken, + ), + **self.serialize_query_param( + "$top", self.ctx.args.top, + ), + **self.serialize_query_param( + "api-version", "2025-01-31-preview", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + def on_200(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200 + ) + + _schema_on_200 = None + + @classmethod + def _build_schema_on_200(cls): + if cls._schema_on_200 is not None: + return cls._schema_on_200 + + cls._schema_on_200 = AAZObjectType() + + _schema_on_200 = cls._schema_on_200 + _schema_on_200.next_link = AAZStrType( + serialized_name="nextLink", + ) + _schema_on_200.value = AAZListType() + + value = cls._schema_on_200.value + value.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"read_only": True}, + ) + _element.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _element.system_data = AAZObjectType( + serialized_name="systemData", + flags={"read_only": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.value.Element.properties + properties.audiences = AAZListType( + flags={"required": True}, + ) + properties.claims_matching_expression = AAZObjectType( + serialized_name="claimsMatchingExpression", + ) + properties.issuer = AAZStrType( + flags={"required": True}, + ) + properties.subject = AAZStrType() + + audiences = cls._schema_on_200.value.Element.properties.audiences + audiences.Element = AAZStrType() + + claims_matching_expression = cls._schema_on_200.value.Element.properties.claims_matching_expression + claims_matching_expression.language_version = AAZIntType( + serialized_name="languageVersion", + flags={"required": True}, + ) + claims_matching_expression.value = AAZStrType( + flags={"required": True}, + ) + + system_data = cls._schema_on_200.value.Element.system_data + system_data.created_at = AAZStrType( + serialized_name="createdAt", + ) + system_data.created_by = AAZStrType( + serialized_name="createdBy", + ) + system_data.created_by_type = AAZStrType( + serialized_name="createdByType", + ) + system_data.last_modified_at = AAZStrType( + serialized_name="lastModifiedAt", + ) + system_data.last_modified_by = AAZStrType( + serialized_name="lastModifiedBy", + ) + system_data.last_modified_by_type = AAZStrType( + serialized_name="lastModifiedByType", + ) + + return cls._schema_on_200 + + +class _ListHelper: + """Helper class for List""" + + +__all__ = ["List"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_show.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_show.py new file mode 100644 index 00000000000..3075bba420d --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_show.py @@ -0,0 +1,236 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "identity federated-credential show", +) +class Show(AAZCommand): + """Show a federated identity credential under an existing user assigned identity. + + :example: Show a federated identity credential under a specific user assigned identity. + az identity federated-credential show --name myFicName --identity-name myIdentityName --resource-group myResourceGroup + """ + + _aaz_info = { + "version": "2025-01-31-preview", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.managedidentity/userassignedidentities/{}/federatedidentitycredentials/{}", "2025-01-31-preview"], + ] + } + + def _handler(self, command_args): + super()._handler(command_args) + self._execute_operations() + return self._output() + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.name = AAZStrArg( + options=["-n", "--name"], + help="The name of the federated identity credential resource.", + required=True, + fmt=AAZStrArgFormat( + pattern="^[a-zA-Z0-9]{1}[a-zA-Z0-9-_]{2,119}$", + ), + ) + _args_schema.resource_group = AAZResourceGroupNameArg( + help="Name of resource group. You can configure the default group using `az configure --defaults group=`.", + required=True, + ) + _args_schema.identity_name = AAZStrArg( + options=["--identity-name"], + help="The name of the identity resource.", + required=True, + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.FederatedIdentityCredentialsGet(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True) + return result + + class FederatedIdentityCredentialsGet(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200]: + return self.on_200(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "federatedIdentityCredentialResourceName", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), + **self.serialize_url_param( + "resourceName", self.ctx.args.identity_name, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2025-01-31-preview", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + def on_200(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200 + ) + + _schema_on_200 = None + + @classmethod + def _build_schema_on_200(cls): + if cls._schema_on_200 is not None: + return cls._schema_on_200 + + cls._schema_on_200 = AAZObjectType() + + _schema_on_200 = cls._schema_on_200 + _schema_on_200.id = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.name = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _schema_on_200.system_data = AAZObjectType( + serialized_name="systemData", + flags={"read_only": True}, + ) + _schema_on_200.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties + properties.audiences = AAZListType( + flags={"required": True}, + ) + properties.claims_matching_expression = AAZObjectType( + serialized_name="claimsMatchingExpression", + ) + properties.issuer = AAZStrType( + flags={"required": True}, + ) + properties.subject = AAZStrType() + + audiences = cls._schema_on_200.properties.audiences + audiences.Element = AAZStrType() + + claims_matching_expression = cls._schema_on_200.properties.claims_matching_expression + claims_matching_expression.language_version = AAZIntType( + serialized_name="languageVersion", + flags={"required": True}, + ) + claims_matching_expression.value = AAZStrType( + flags={"required": True}, + ) + + system_data = cls._schema_on_200.system_data + system_data.created_at = AAZStrType( + serialized_name="createdAt", + ) + system_data.created_by = AAZStrType( + serialized_name="createdBy", + ) + system_data.created_by_type = AAZStrType( + serialized_name="createdByType", + ) + system_data.last_modified_at = AAZStrType( + serialized_name="lastModifiedAt", + ) + system_data.last_modified_by = AAZStrType( + serialized_name="lastModifiedBy", + ) + system_data.last_modified_by_type = AAZStrType( + serialized_name="lastModifiedByType", + ) + + return cls._schema_on_200 + + +class _ShowHelper: + """Helper class for Show""" + + +__all__ = ["Show"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_update.py b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_update.py new file mode 100644 index 00000000000..69ddd9f1e89 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/identity/aaz/latest/identity/federated_credential/_update.py @@ -0,0 +1,454 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "identity federated-credential update", +) +class Update(AAZCommand): + """Update a federated identity credential under an existing user assigned identity. + + :example: Update a federated identity credential under a specific user assigned identity using subject. + az identity federated-credential update --identity-name myIdentityName --name myFicName --resource-group myResourceGroup --issuer myIssuer --subject mySubject --audiences myAudiences + + :example: Update a federated identity credential under a specific user assigned identity using claimsMatchingExpression. + az identity federated-credential update --identity-name myIdentityName --name myFicName --resource-group myResourceGroup --issuer myIssuer --claims-matching-expression-version 1 --claims-matching-expression-value "claims['sub'] eq 'foo'" --audiences myAudiences + """ + + _aaz_info = { + "version": "2025-01-31-preview", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.managedidentity/userassignedidentities/{}/federatedidentitycredentials/{}", "2025-01-31-preview"], + ] + } + + AZ_SUPPORT_GENERIC_UPDATE = True + + def _handler(self, command_args): + super()._handler(command_args) + self._execute_operations() + return self._output() + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.name = AAZStrArg( + options=["-n", "--name"], + help="The name of the federated identity credential resource.", + required=True, + fmt=AAZStrArgFormat( + pattern="^[a-zA-Z0-9]{1}[a-zA-Z0-9-_]{2,119}$", + ), + ) + _args_schema.resource_group = AAZResourceGroupNameArg( + help="Name of resource group. You can configure the default group using `az configure --defaults group=`.", + required=True, + ) + _args_schema.identity_name = AAZStrArg( + options=["--identity-name"], + help="The name of the identity resource.", + required=True, + ) + + # define Arg Group "ClaimsMatchingExpression" + + _args_schema = cls._args_schema + _args_schema.claims_matching_expression_version = AAZIntArg( + options=["--cme-version", "--claims-matching-expression-version"], + arg_group="ClaimsMatchingExpression", + help="Specifies the version of the claims matching expression used in the expression.", + is_preview=True, + ) + _args_schema.claims_matching_expression_value = AAZStrArg( + options=["--cme-value", "--claims-matching-expression-value"], + arg_group="ClaimsMatchingExpression", + help="The wildcard-based expression for matching incoming claims. Cannot be used with --subject.", + is_preview=True, + ) + + # define Arg Group "Properties" + + _args_schema = cls._args_schema + _args_schema.audiences = AAZListArg( + options=["--audiences"], + arg_group="Properties", + help="The aud value in the token sent to Azure for getting the user-assigned managed identity token. The value configured in the federated credential and the one in the incoming token must exactly match for Azure to issue the access token.", + ) + _args_schema.issuer = AAZStrArg( + options=["--issuer"], + arg_group="Properties", + help="The openId connect metadata URL of the issuer of the identity provider that Azure AD would use in the token exchange protocol for validating tokens before issuing a token as the user-assigned managed identity.", + ) + _args_schema.subject = AAZStrArg( + options=["--subject"], + arg_group="Properties", + help="The sub value in the token sent to Azure AD for getting the user-assigned managed identity token. The value configured in the federated credential and the one in the incoming token must exactly match for Azure AD to issue the access token. Either 'subject' or 'claimsMatchingExpression' must be defined, but not both.", + nullable=True, + ) + + audiences = cls._args_schema.audiences + audiences.Element = AAZStrArg( + nullable=True, + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.FederatedIdentityCredentialsGet(ctx=self.ctx)() + self.pre_instance_update(self.ctx.vars.instance) + self.InstanceUpdateByJson(ctx=self.ctx)() + self.InstanceUpdateByGeneric(ctx=self.ctx)() + self.post_instance_update(self.ctx.vars.instance) + self.FederatedIdentityCredentialsCreateOrUpdate(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + @register_callback + def pre_instance_update(self, instance): + pass + + @register_callback + def post_instance_update(self, instance): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True) + return result + + class FederatedIdentityCredentialsGet(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200]: + return self.on_200(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "federatedIdentityCredentialResourceName", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), + **self.serialize_url_param( + "resourceName", self.ctx.args.identity_name, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2025-01-31-preview", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + def on_200(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200 + ) + + _schema_on_200 = None + + @classmethod + def _build_schema_on_200(cls): + if cls._schema_on_200 is not None: + return cls._schema_on_200 + + cls._schema_on_200 = AAZObjectType() + _UpdateHelper._build_schema_federated_identity_credential_read(cls._schema_on_200) + + return cls._schema_on_200 + + class FederatedIdentityCredentialsCreateOrUpdate(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200, 201]: + return self.on_200_201(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}", + **self.url_parameters + ) + + @property + def method(self): + return "PUT" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "federatedIdentityCredentialResourceName", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), + **self.serialize_url_param( + "resourceName", self.ctx.args.identity_name, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2025-01-31-preview", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Content-Type", "application/json", + ), + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + @property + def content(self): + _content_value, _builder = self.new_content_builder( + self.ctx.args, + value=self.ctx.vars.instance, + ) + + return self.serialize_content(_content_value) + + def on_200_201(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200_201 + ) + + _schema_on_200_201 = None + + @classmethod + def _build_schema_on_200_201(cls): + if cls._schema_on_200_201 is not None: + return cls._schema_on_200_201 + + cls._schema_on_200_201 = AAZObjectType() + _UpdateHelper._build_schema_federated_identity_credential_read(cls._schema_on_200_201) + + return cls._schema_on_200_201 + + class InstanceUpdateByJson(AAZJsonInstanceUpdateOperation): + + def __call__(self, *args, **kwargs): + self._update_instance(self.ctx.vars.instance) + + def _update_instance(self, instance): + _instance_value, _builder = self.new_content_builder( + self.ctx.args, + value=instance, + typ=AAZObjectType + ) + _builder.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}}) + + properties = _builder.get(".properties") + if properties is not None: + properties.set_prop("audiences", AAZListType, ".audiences", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("claimsMatchingExpression", AAZObjectType) + properties.set_prop("issuer", AAZStrType, ".issuer", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("subject", AAZStrType, ".subject") + + audiences = _builder.get(".properties.audiences") + if audiences is not None: + audiences.set_elements(AAZStrType, ".") + + claims_matching_expression = _builder.get(".properties.claimsMatchingExpression") + if claims_matching_expression is not None: + claims_matching_expression.set_prop("languageVersion", AAZIntType, ".claims_matching_expression_version", typ_kwargs={"flags": {"required": True}}) + claims_matching_expression.set_prop("value", AAZStrType, ".claims_matching_expression_value", typ_kwargs={"flags": {"required": True}}) + + return _instance_value + + class InstanceUpdateByGeneric(AAZGenericInstanceUpdateOperation): + + def __call__(self, *args, **kwargs): + self._update_instance_by_generic( + self.ctx.vars.instance, + self.ctx.generic_update_args + ) + + +class _UpdateHelper: + """Helper class for Update""" + + _schema_federated_identity_credential_read = None + + @classmethod + def _build_schema_federated_identity_credential_read(cls, _schema): + if cls._schema_federated_identity_credential_read is not None: + _schema.id = cls._schema_federated_identity_credential_read.id + _schema.name = cls._schema_federated_identity_credential_read.name + _schema.properties = cls._schema_federated_identity_credential_read.properties + _schema.system_data = cls._schema_federated_identity_credential_read.system_data + _schema.type = cls._schema_federated_identity_credential_read.type + return + + cls._schema_federated_identity_credential_read = _schema_federated_identity_credential_read = AAZObjectType() + + federated_identity_credential_read = _schema_federated_identity_credential_read + federated_identity_credential_read.id = AAZStrType( + flags={"read_only": True}, + ) + federated_identity_credential_read.name = AAZStrType( + flags={"read_only": True}, + ) + federated_identity_credential_read.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + federated_identity_credential_read.system_data = AAZObjectType( + serialized_name="systemData", + flags={"read_only": True}, + ) + federated_identity_credential_read.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = _schema_federated_identity_credential_read.properties + properties.audiences = AAZListType( + flags={"required": True}, + ) + properties.claims_matching_expression = AAZObjectType( + serialized_name="claimsMatchingExpression", + ) + properties.issuer = AAZStrType( + flags={"required": True}, + ) + properties.subject = AAZStrType() + + audiences = _schema_federated_identity_credential_read.properties.audiences + audiences.Element = AAZStrType() + + claims_matching_expression = _schema_federated_identity_credential_read.properties.claims_matching_expression + claims_matching_expression.language_version = AAZIntType( + serialized_name="languageVersion", + flags={"required": True}, + ) + claims_matching_expression.value = AAZStrType( + flags={"required": True}, + ) + + system_data = _schema_federated_identity_credential_read.system_data + system_data.created_at = AAZStrType( + serialized_name="createdAt", + ) + system_data.created_by = AAZStrType( + serialized_name="createdBy", + ) + system_data.created_by_type = AAZStrType( + serialized_name="createdByType", + ) + system_data.last_modified_at = AAZStrType( + serialized_name="lastModifiedAt", + ) + system_data.last_modified_by = AAZStrType( + serialized_name="lastModifiedBy", + ) + system_data.last_modified_by_type = AAZStrType( + serialized_name="lastModifiedByType", + ) + + _schema.id = cls._schema_federated_identity_credential_read.id + _schema.name = cls._schema_federated_identity_credential_read.name + _schema.properties = cls._schema_federated_identity_credential_read.properties + _schema.system_data = cls._schema_federated_identity_credential_read.system_data + _schema.type = cls._schema_federated_identity_credential_read.type + + +__all__ = ["Update"] diff --git a/src/azure-cli/azure/cli/command_modules/identity/commands.py b/src/azure-cli/azure/cli/command_modules/identity/commands.py index d43da6df438..efb08ab5307 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/commands.py +++ b/src/azure-cli/azure/cli/command_modules/identity/commands.py @@ -3,11 +3,9 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- - from azure.cli.core.commands import CliCommandType -from ._client_factory import _msi_user_identities_operations, _msi_operations_operations, \ - _msi_federated_identity_credentials_operations +from ._client_factory import _msi_user_identities_operations, _msi_operations_operations from ._validators import process_msi_namespace @@ -22,11 +20,6 @@ def load_command_table(self, _): operations_tmpl='azure.mgmt.msi.operations#Operations.{}', client_factory=_msi_operations_operations ) - federated_identity_credentials_sdk = CliCommandType( - operations_tmpl='azure.mgmt.msi.operations#FederatedIdentityCredentialsOperations.{}', - client_factory=_msi_federated_identity_credentials_operations - ) - with self.command_group('identity', identity_sdk, client_factory=_msi_user_identities_operations) as g: g.custom_command('create', 'create_identity', validator=process_msi_namespace) g.show_command('show', 'get') @@ -36,12 +29,3 @@ def load_command_table(self, _): with self.command_group('identity', msi_operations_sdk, client_factory=_msi_operations_operations) as g: g.command('list-operations', 'list') - - with self.command_group('identity federated-credential', federated_identity_credentials_sdk, - client_factory=_msi_federated_identity_credentials_operations, - min_api='2022-01-31-preview') as g: - g.custom_command('create', 'create_or_update_federated_credential') - g.custom_command('update', 'create_or_update_federated_credential') - g.custom_show_command('show', 'show_federated_credential') - g.custom_command('delete', 'delete_federated_credential', confirmation=True) - g.custom_command('list', 'list_federated_credential') diff --git a/src/azure-cli/azure/cli/command_modules/identity/custom.py b/src/azure-cli/azure/cli/command_modules/identity/custom.py index c1b80cb8848..b63af796af4 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/custom.py +++ b/src/azure-cli/azure/cli/command_modules/identity/custom.py @@ -3,11 +3,6 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from azure.cli.core.profiles import ResourceType -from azure.cli.core.azclierror import ( - RequiredArgumentMissingError -) - def list_user_assigned_identities(cmd, resource_group_name=None): from azure.cli.command_modules.identity._client_factory import _msi_client_factory @@ -32,33 +27,3 @@ def list_identity_resources(cmd, resource_group_name, resource_name): client = _msi_list_resources_client(cmd.cli_ctx) return client.list_associated_resources(resource_group_name=resource_group_name, resource_name=resource_name) - - -def create_or_update_federated_credential(cmd, client, resource_group_name, identity_name, federated_credential_name, - issuer=None, subject=None, audiences=None): - _default_audiences = ['api://AzureADTokenExchange'] - audiences = _default_audiences if not audiences else audiences - if not issuer or not subject: - raise RequiredArgumentMissingError('usage error: please provide both --issuer and --subject parameters') - - FederatedIdentityCredential = cmd.get_models('FederatedIdentityCredential', resource_type=ResourceType.MGMT_MSI, - operation_group='federated_identity_credentials') - parameters = FederatedIdentityCredential(issuer=issuer, subject=subject, audiences=audiences) - - return client.create_or_update(resource_group_name=resource_group_name, resource_name=identity_name, - federated_identity_credential_resource_name=federated_credential_name, - parameters=parameters) - - -def delete_federated_credential(client, resource_group_name, identity_name, federated_credential_name): - return client.delete(resource_group_name=resource_group_name, resource_name=identity_name, - federated_identity_credential_resource_name=federated_credential_name) - - -def show_federated_credential(client, resource_group_name, identity_name, federated_credential_name): - return client.get(resource_group_name=resource_group_name, resource_name=identity_name, - federated_identity_credential_resource_name=federated_credential_name) - - -def list_federated_credential(client, resource_group_name, identity_name): - return client.list(resource_group_name=resource_group_name, resource_name=identity_name) diff --git a/src/azure-cli/azure/cli/command_modules/identity/tests/latest/recordings/test_federated_identity_credential.yaml b/src/azure-cli/azure/cli/command_modules/identity/tests/latest/recordings/test_federated_identity_credential.yaml index df9646ee994..25f7c0c9790 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/tests/latest/recordings/test_federated_identity_credential.yaml +++ b/src/azure-cli/azure/cli/command_modules/identity/tests/latest/recordings/test_federated_identity_credential.yaml @@ -13,37 +13,40 @@ interactions: ParameterSetName: - -n -g User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-resource/22.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001?api-version=2022-09-01 response: body: - string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001","name":"cli_test_federated_identity_credential_000001","type":"Microsoft.Resources/resourceGroups","location":"eastus2euap","tags":{"product":"azurecli","cause":"automation","date":"2023-03-13T11:09:47Z"},"properties":{"provisioningState":"Succeeded"}}' + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001","name":"cli_test_federated_identity_credential_000001","type":"Microsoft.Resources/resourceGroups","location":"centraluseuap","tags":{"product":"azurecli","cause":"automation","test":"test_federated_identity_credential","date":"2025-05-13T16:18:30Z","module":"identity"},"properties":{"provisioningState":"Succeeded"}}' headers: cache-control: - no-cache content-length: - - '373' + - '439' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:47 GMT + - Tue, 13 May 2025 16:18:32 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains - vary: - - Accept-Encoding + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: CCDEC4CB1BA74117A191612CD926C25E Ref B: SN4AA2022303023 Ref C: 2025-05-13T16:18:32Z' status: code: 200 message: OK - request: - body: '{"location": "eastus2euap"}' + body: '{"location": "centraluseuap"}' headers: Accept: - application/json @@ -54,28 +57,27 @@ interactions: Connection: - keep-alive Content-Length: - - '27' + - '29' Content-Type: - application/json ParameterSetName: - -n -g User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: PUT uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide?api-version=2023-01-31 response: body: - string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide","name":"ide","type":"Microsoft.ManagedIdentity/userAssignedIdentities","location":"eastus2euap","tags":{},"properties":{"tenantId":"54826b22-38d6-4fb2-bad9-b7b93a3e9c5a","principalId":"ef8d816a-b3c1-4c46-b6b4-165744b66522","clientId":"35cf13b5-bb51-4634-b257-4a13bdfd706b"}}' + string: '{"location":"centraluseuap","tags":{},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide","name":"ide","type":"Microsoft.ManagedIdentity/userAssignedIdentities","properties":{"tenantId":"abd8daee-d393-4239-9377-883adda3d40f","principalId":"bfec20f8-b4cc-44db-8490-d2bf8ece6cbe","clientId":"d5a162ad-ae2d-460f-a791-bce75b9b777b"}}' headers: cache-control: - no-cache content-length: - - '458' + - '460' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:49 GMT + - Tue, 13 May 2025 16:18:35 GMT expires: - '-1' location: @@ -84,16 +86,24 @@ interactions: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/8e4232a0-3a2f-4513-8787-ed011ff9f349 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' x-ms-ratelimit-remaining-subscription-writes: - - '1194' + - '199' + x-msedge-ref: + - 'Ref A: 5BEC40721B534EE48F95CFDC61E297AE Ref B: SN4AA2022302049 Ref C: 2025-05-13T16:18:32Z' status: code: 201 message: Created - request: - body: '{"properties": {"issuer": "https://oidc.prod-aks.azure.com/IssuerGUID", - "subject": "system:serviceaccount:ns:svcaccount1", "audiences": ["api://AzureADTokenExchange"]}}' + body: '{"properties": {"audiences": ["api://AzureADTokenExchange"], "issuer": + "https://token.actions.githubusercontent.com", "subject": "system:serviceaccount:ns:svcaccount1"}}' headers: Accept: - application/json @@ -104,28 +114,27 @@ interactions: Connection: - keep-alive Content-Length: - - '168' + - '169' Content-Type: - application/json ParameterSetName: - --name --identity-name --resource-group --subject --issuer --audiences User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: PUT - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2025-01-31-preview response: body: - string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}}' + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}}' headers: cache-control: - no-cache content-length: - - '480' + - '481' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:49 GMT + - Tue, 13 May 2025 16:18:37 GMT expires: - '-1' location: @@ -134,16 +143,24 @@ interactions: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/ead4f916-d2b7-4a2d-aad2-8b104e4ca7ad + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' x-ms-ratelimit-remaining-subscription-writes: - - '1195' + - '199' + x-msedge-ref: + - 'Ref A: AC05F81CFB884EDA9C04760EA65EFB0C Ref B: SN4AA2022302011 Ref C: 2025-05-13T16:18:36Z' status: code: 201 message: Created - request: - body: '{"properties": {"issuer": "https://oidc.prod-aks.azure.com/IssuerGUID", - "subject": "system:serviceaccount:ns:svcaccount2", "audiences": ["api://AzureADTokenExchange"]}}' + body: '{"properties": {"audiences": ["api://AzureADTokenExchange"], "issuer": + "https://token.actions.githubusercontent.com", "subject": "system:serviceaccount:ns:svcaccount2"}}' headers: Accept: - application/json @@ -154,28 +171,27 @@ interactions: Connection: - keep-alive Content-Length: - - '168' + - '169' Content-Type: - application/json ParameterSetName: - --name --identity-name --resource-group --subject --issuer --audiences User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: PUT - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2?api-version=2025-01-31-preview response: body: - string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2","name":"fic2","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount2","audiences":["api://AzureADTokenExchange"]}}' + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2","name":"fic2","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount2","audiences":["api://AzureADTokenExchange"]}}' headers: cache-control: - no-cache content-length: - - '480' + - '481' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:50 GMT + - Tue, 13 May 2025 16:18:38 GMT expires: - '-1' location: @@ -184,10 +200,77 @@ interactions: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/4f8fffd4-2f5c-4cb0-a667-f784122538a5 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + x-msedge-ref: + - 'Ref A: A93DAA3348284E46A2AE39B370178BA2 Ref B: SN4AA2022304029 Ref C: 2025-05-13T16:18:38Z' + status: + code: 201 + message: Created +- request: + body: '{"properties": {"audiences": ["api://AzureADTokenExchange"], "claimsMatchingExpression": + {"languageVersion": 1, "value": "claims[''sub''] eq ''foo''"}, "issuer": "https://token.actions.githubusercontent.com"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity federated-credential create + Connection: + - keep-alive + Content-Length: + - '205' + Content-Type: + - application/json + ParameterSetName: + - --name --identity-name --resource-group --claims-matching-expression-version + --claims-matching-expression-value --issuer --audiences + User-Agent: + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3?api-version=2025-01-31-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3","name":"fic3","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","audiences":["api://AzureADTokenExchange"],"claimsMatchingExpression":{"languageVersion":1,"value":"claims[''sub''] + eq ''foo''"}}}' + headers: + cache-control: + - no-cache + content-length: + - '514' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 13 May 2025 16:18:40 GMT + expires: + - '-1' + location: + - /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3 + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/63dbb151-d6fa-42a1-b2a3-19aeef95b52e + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' x-ms-ratelimit-remaining-subscription-writes: - - '1196' + - '199' + x-msedge-ref: + - 'Ref A: 51EB7DB4C96B4AC6AFEE3E0622FFE23E Ref B: SN4AA2022305019 Ref C: 2025-05-13T16:18:39Z' status: code: 201 message: Created @@ -205,34 +288,86 @@ interactions: ParameterSetName: - --name --identity-name --resource-group User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2025-01-31-preview response: body: - string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}}' + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}}' headers: cache-control: - no-cache content-length: - - '480' + - '481' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:51 GMT + - Tue, 13 May 2025 16:18:41 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains - transfer-encoding: - - chunked - vary: - - Accept-Encoding + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/4166165a-a785-491a-b027-a8747890fa8a + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: CD93FEF490A5403C84B89CB03BCDAA6A Ref B: SN4AA2022305037 Ref C: 2025-05-13T16:18:41Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity federated-credential show + Connection: + - keep-alive + ParameterSetName: + - --name --identity-name --resource-group + User-Agent: + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3?api-version=2025-01-31-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3","name":"fic3","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","audiences":["api://AzureADTokenExchange"],"claimsMatchingExpression":{"languageVersion":1,"value":"claims[''sub''] + eq ''foo''"}}}' + headers: + cache-control: + - no-cache + content-length: + - '514' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 13 May 2025 16:18:41 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/961ea5d4-2590-4a35-b39d-84a63f731475 + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: 5EB5BA63F1AD4DD8920708F0691EA337 Ref B: SN4AA2022302017 Ref C: 2025-05-13T16:18:42Z' status: code: 200 message: OK @@ -250,40 +385,92 @@ interactions: ParameterSetName: - --identity-name --resource-group User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials?api-version=2025-01-31-preview response: body: - string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2","name":"fic2","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount2","audiences":["api://AzureADTokenExchange"]}}]}' + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2","name":"fic2","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount2","audiences":["api://AzureADTokenExchange"]}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3","name":"fic3","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","audiences":["api://AzureADTokenExchange"],"claimsMatchingExpression":{"languageVersion":1,"value":"claims[''sub''] + eq ''foo''"}}}]}' headers: cache-control: - no-cache content-length: - - '973' + - '1490' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:52 GMT + - Tue, 13 May 2025 16:18:42 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains - transfer-encoding: - - chunked - vary: - - Accept-Encoding + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/6d55f60f-3454-461a-ad07-e34066cc29c8 + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: A8C06687DCA8436BB8B104FE4BD618E7 Ref B: SN4AA2022302027 Ref C: 2025-05-13T16:18:42Z' status: code: 200 message: OK - request: - body: '{"properties": {"issuer": "https://oidc.prod-aks.azure.com/IssuerGUID", - "subject": "system:serviceaccount:ns:svcaccount3", "audiences": ["api://AzureADTokenExchange"]}}' + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity federated-credential update + Connection: + - keep-alive + ParameterSetName: + - --name --identity-name --resource-group --subject --issuer --audiences + User-Agent: + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2025-01-31-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount1","audiences":["api://AzureADTokenExchange"]}}' + headers: + cache-control: + - no-cache + content-length: + - '481' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 13 May 2025 16:18:43 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/fa21b6bb-6659-4d4c-8f7e-ac053c7f906d + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: 73D9EB3C7CA6451AAE0B6A127F322D19 Ref B: SN4AA2022303053 Ref C: 2025-05-13T16:18:43Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"audiences": ["api://AzureADTokenExchange"], "issuer": + "https://token.actions.githubusercontent.com", "subject": "system:serviceaccount:ns:newaccount"}}' headers: Accept: - application/json @@ -300,13 +487,12 @@ interactions: ParameterSetName: - --name --identity-name --resource-group --subject --issuer --audiences User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: PUT - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2025-01-31-preview response: body: - string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount3","audiences":["api://AzureADTokenExchange"]}}' + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1","name":"fic1","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:newaccount","audiences":["api://AzureADTokenExchange"]}}' headers: cache-control: - no-cache @@ -315,21 +501,25 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:52 GMT + - Tue, 13 May 2025 16:18:44 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains - transfer-encoding: - - chunked - vary: - - Accept-Encoding + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/352e8bfa-6ea8-465b-8b16-68f1b32f7015 + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' x-ms-ratelimit-remaining-subscription-writes: - - '1197' + - '199' + x-msedge-ref: + - 'Ref A: 6DA129A82AAC44A79C9BACA957AB83E0 Ref B: SN4AA2022303031 Ref C: 2025-05-13T16:18:44Z' status: code: 200 message: OK @@ -341,6 +531,114 @@ interactions: Accept-Encoding: - gzip, deflate CommandName: + - identity federated-credential update + Connection: + - keep-alive + ParameterSetName: + - --name --identity-name --resource-group --claims-matching-expression-version + --claims-matching-expression-value --issuer --audiences + User-Agent: + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3?api-version=2025-01-31-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3","name":"fic3","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","audiences":["api://AzureADTokenExchange"],"claimsMatchingExpression":{"languageVersion":1,"value":"claims[''sub''] + eq ''foo''"}}}' + headers: + cache-control: + - no-cache + content-length: + - '514' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 13 May 2025 16:18:44 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/88ade9b1-e6d0-4809-9253-74e667162b9f + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: B86BD6EAC6764B858CACE80918ECE442 Ref B: SN4AA2022305047 Ref C: 2025-05-13T16:18:45Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"audiences": ["api://AzureADTokenExchange"], "claimsMatchingExpression": + {"languageVersion": 1, "value": "claims[''sub''] eq ''updatedFoo''"}, "issuer": + "https://token.actions.githubusercontent.com"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity federated-credential update + Connection: + - keep-alive + Content-Length: + - '212' + Content-Type: + - application/json + ParameterSetName: + - --name --identity-name --resource-group --claims-matching-expression-version + --claims-matching-expression-value --issuer --audiences + User-Agent: + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3?api-version=2025-01-31-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3","name":"fic3","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","audiences":["api://AzureADTokenExchange"],"claimsMatchingExpression":{"languageVersion":1,"value":"claims[''sub''] + eq ''updatedFoo''"}}}' + headers: + cache-control: + - no-cache + content-length: + - '521' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 13 May 2025 16:18:46 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/36d49a46-9dd3-4d37-b800-1a431267fe2d + x-ms-ratelimit-remaining-subscription-global-writes: + - '2999' + x-ms-ratelimit-remaining-subscription-writes: + - '199' + x-msedge-ref: + - 'Ref A: 0DC0B4BF5AB84302A58D3D021AF081F8 Ref B: SN4AA2022305029 Ref C: 2025-05-13T16:18:46Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: - identity federated-credential delete Connection: - keep-alive @@ -349,10 +647,9 @@ interactions: ParameterSetName: - --name --identity-name --resource-group --yes User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: DELETE - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic1?api-version=2025-01-31-preview response: body: string: '' @@ -362,17 +659,25 @@ interactions: content-length: - '0' date: - - Mon, 13 Mar 2023 11:09:54 GMT + - Tue, 13 May 2025 16:18:48 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/f539478d-fe8e-44e1-bc87-4799843cf085 x-ms-ratelimit-remaining-subscription-deletes: - - '14999' + - '199' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '2999' + x-msedge-ref: + - 'Ref A: C179BAFA65834744BA794DCD21A329D4 Ref B: SN4AA2022305045 Ref C: 2025-05-13T16:18:47Z' status: code: 200 message: OK @@ -390,34 +695,38 @@ interactions: ParameterSetName: - --identity-name --resource-group User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials?api-version=2025-01-31-preview response: body: - string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2","name":"fic2","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://oidc.prod-aks.azure.com/IssuerGUID","subject":"system:serviceaccount:ns:svcaccount2","audiences":["api://AzureADTokenExchange"]}}]}' + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2","name":"fic2","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"system:serviceaccount:ns:svcaccount2","audiences":["api://AzureADTokenExchange"]}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3","name":"fic3","type":"Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials","properties":{"issuer":"https://token.actions.githubusercontent.com","audiences":["api://AzureADTokenExchange"],"claimsMatchingExpression":{"languageVersion":1,"value":"claims[''sub''] + eq ''updatedFoo''"}}}]}' headers: cache-control: - no-cache content-length: - - '492' + - '1015' content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:54 GMT + - Tue, 13 May 2025 16:18:49 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains - transfer-encoding: - - chunked - vary: - - Accept-Encoding + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/967155cd-af24-4617-9cec-c38453f03b1a + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: 18AB4822A0224850A818A8168F20FBD0 Ref B: SN4AA2022303025 Ref C: 2025-05-13T16:18:48Z' status: code: 200 message: OK @@ -425,7 +734,57 @@ interactions: body: null headers: Accept: - - application/json + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - identity federated-credential delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - --name --identity-name --resource-group --yes + User-Agent: + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2?api-version=2025-01-31-preview + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Tue, 13 May 2025 16:18:50 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/54091a22-ec01-442a-9f87-62802d9febb1 + x-ms-ratelimit-remaining-subscription-deletes: + - '199' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '2999' + x-msedge-ref: + - 'Ref A: 810689F43B7E4D5A8D160ADE214A9BAF Ref B: SN4AA2022304025 Ref C: 2025-05-13T16:18:49Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' Accept-Encoding: - gzip, deflate CommandName: @@ -437,10 +796,9 @@ interactions: ParameterSetName: - --name --identity-name --resource-group --yes User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: DELETE - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic2?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials/fic3?api-version=2025-01-31-preview response: body: string: '' @@ -450,17 +808,25 @@ interactions: content-length: - '0' date: - - Mon, 13 Mar 2023 11:09:54 GMT + - Tue, 13 May 2025 16:18:50 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/dc2f032a-8e0f-46e9-9bc8-9254b931be04 x-ms-ratelimit-remaining-subscription-deletes: - - '14996' + - '199' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '2999' + x-msedge-ref: + - 'Ref A: 3E3367223BA642438CD3E36E69DFD270 Ref B: SN4AA2022305047 Ref C: 2025-05-13T16:18:50Z' status: code: 200 message: OK @@ -478,10 +844,9 @@ interactions: ParameterSetName: - --identity-name --resource-group User-Agent: - - AZURECLI/2.46.0 azsdk-python-azure-mgmt-msi/7.0.0 Python/3.10.10 (Linux-5.15.0-1033-azure-x86_64-with-glibc2.31) - VSTS_7b238909-6802-4b65-b90d-184bca47f458_build_220_0 + - AZURECLI/2.72.0 azsdk-python-core/1.34.0 Python/3.12.10 (Windows-11-10.0.26100-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials?api-version=2023-01-31 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_federated_identity_credential_000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ide/federatedIdentityCredentials?api-version=2025-01-31-preview response: body: string: '{"value":[]}' @@ -493,15 +858,23 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Mon, 13 Mar 2023 11:09:55 GMT + - Tue, 13 May 2025 16:18:51 GMT expires: - '-1' pragma: - no-cache strict-transport-security: - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE x-content-type-options: - nosniff + x-ms-operation-identifier: + - tenantId=abd8daee-d393-4239-9377-883adda3d40f,objectId=7d2472ba-902d-407c-ae0d-72c7f66f95c6/southcentralus/446defe4-15ac-48c8-8662-f25509af958b + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: D41D27B044F74CA28A4E0D72736649F8 Ref B: SN4AA2022303047 Ref C: 2025-05-13T16:18:51Z' status: code: 200 message: OK diff --git a/src/azure-cli/azure/cli/command_modules/identity/tests/latest/test_identity.py b/src/azure-cli/azure/cli/command_modules/identity/tests/latest/test_identity.py index 9367a106f03..3ffb87e5901 100644 --- a/src/azure-cli/azure/cli/command_modules/identity/tests/latest/test_identity.py +++ b/src/azure-cli/azure/cli/command_modules/identity/tests/latest/test_identity.py @@ -29,22 +29,25 @@ def test_identity_management(self, resource_group): self.cmd('identity list -g {rg}', checks=self.check('length(@)', 1)) self.cmd('identity delete -n {identity} -g {rg}') - @ResourceGroupPreparer(name_prefix='cli_test_federated_identity_credential_', location='eastus2euap') + @ResourceGroupPreparer(name_prefix='cli_test_federated_identity_credential_', location='centraluseuap') def test_federated_identity_credential(self, resource_group): self.kwargs.update({ 'identity': 'ide', 'fic1': 'fic1', 'fic2': 'fic2', + 'fic3': 'fic3', 'subject1': 'system:serviceaccount:ns:svcaccount1', 'subject2': 'system:serviceaccount:ns:svcaccount2', 'subject3': 'system:serviceaccount:ns:svcaccount3', - 'issuer': 'https://oidc.prod-aks.azure.com/IssuerGUID', + 'issuer': 'https://token.actions.githubusercontent.com', 'audience': 'api://AzureADTokenExchange', + 'cme_version': '1', + 'cme_value': "claims['sub'] eq 'foo'", }) self.cmd('identity create -n {identity} -g {rg}') - # create a federated identity credential + # create a federated identity credential using subject self.cmd('identity federated-credential create --name {fic1} --identity-name {identity} --resource-group {rg} ' '--subject {subject1} --issuer {issuer} --audiences {audience}', checks=[ @@ -54,7 +57,7 @@ def test_federated_identity_credential(self, resource_group): self.check('subject', '{subject1}') ]) - # create a federated identity credential + # create another federated identity credential using subject self.cmd('identity federated-credential create --name {fic2} --identity-name {identity} --resource-group {rg} ' '--subject {subject2} --issuer {issuer} --audiences {audience}', checks=[ @@ -64,7 +67,20 @@ def test_federated_identity_credential(self, resource_group): self.check('subject', '{subject2}') ]) - # show the federated identity credential + # create a federated identity credential using claims matching expression + self.cmd('identity federated-credential create --name {fic3} --identity-name {identity} --resource-group {rg} ' + '--claims-matching-expression-version {cme_version} ' + '--claims-matching-expression-value "{cme_value}" ' + '--issuer {issuer} --audiences {audience}', + checks=[ + self.check('length(audiences)', 1), + self.check('audiences[0]', '{audience}'), + self.check('issuer', '{issuer}'), + self.check('claimsMatchingExpression.languageVersion', 1), + self.check('claimsMatchingExpression.value', "{cme_value}") + ]) + + # show the federated identity credential with subject self.cmd('identity federated-credential show --name {fic1} --identity-name {identity} --resource-group {rg}', checks=[ self.check('length(audiences)', 1), @@ -73,11 +89,21 @@ def test_federated_identity_credential(self, resource_group): self.check('subject', '{subject1}') ]) - # list the federated identity credential + # show the federated identity credential with claims matching expression + self.cmd('identity federated-credential show --name {fic3} --identity-name {identity} --resource-group {rg}', + checks=[ + self.check('length(audiences)', 1), + self.check('audiences[0]', '{audience}'), + self.check('issuer', '{issuer}'), + self.check('claimsMatchingExpression.languageVersion', 1), + self.check('claimsMatchingExpression.value', "{cme_value}") + ]) + + # list the federated identity credentials self.cmd('identity federated-credential list --identity-name {identity} --resource-group {rg}', checks=[ self.check('type(@)', 'array'), - self.check('length(@)', 2), + self.check('length(@)', 3), self.check('length([0].audiences)', '1'), self.check('[0].audiences[0]', '{audience}'), self.check('[0].issuer', '{issuer}'), @@ -86,33 +112,56 @@ def test_federated_identity_credential(self, resource_group): self.check('[1].audiences[0]', '{audience}'), self.check('[1].issuer', '{issuer}'), self.check('[1].subject', '{subject2}'), + self.check('length([2].audiences)', '1'), + self.check('[2].audiences[0]', '{audience}'), + self.check('[2].issuer', '{issuer}'), + self.check('[2].claimsMatchingExpression.languageVersion', 1), + self.check('[2].claimsMatchingExpression.value', "{cme_value}") ]) - # update a federated identity credential + # update a federated identity credential with subject to a different subject + self.kwargs['new_subject'] = 'system:serviceaccount:ns:newaccount' self.cmd('identity federated-credential update --name {fic1} --identity-name {identity} --resource-group {rg} ' - '--subject {subject3} --issuer {issuer} --audiences {audience}', + '--subject {new_subject} --issuer {issuer} --audiences {audience}', checks=[ self.check('name', '{fic1}'), - self.check('subject', '{subject3}') + self.check('subject', '{new_subject}') + ]) + + # update a federated identity credential with claims matching expression to a different expression + self.kwargs['new_cme_value'] = "claims['sub'] eq 'updatedFoo'" + self.cmd('identity federated-credential update --name {fic3} --identity-name {identity} --resource-group {rg} ' + '--claims-matching-expression-version {cme_version} ' + '--claims-matching-expression-value "{new_cme_value}" ' + '--issuer {issuer} --audiences {audience}', + checks=[ + self.check('name', '{fic3}'), + self.check('claimsMatchingExpression.languageVersion', 1), + self.check('claimsMatchingExpression.value', "{new_cme_value}") ]) - # delete a federated identity credential + # delete first federated identity credential self.cmd('identity federated-credential delete --name {fic1}' ' --identity-name {identity} --resource-group {rg} --yes') + + # verify remaining credentials after first deletion self.cmd('identity federated-credential list --identity-name {identity} --resource-group {rg}', checks=[ self.check('type(@)', 'array'), - self.check('length(@)', 1), + self.check('length(@)', 2), self.check('[0].name', '{fic2}'), - self.check('length([0].audiences)', '1'), - self.check('[0].audiences[0]', '{audience}'), - self.check('[0].issuer', '{issuer}'), self.check('[0].subject', '{subject2}'), + self.check('[1].name', '{fic3}'), + self.check('[1].claimsMatchingExpression.value', "{new_cme_value}") ]) - # delete a federated identity credential + # delete remaining federated identity credentials self.cmd('identity federated-credential delete --name {fic2}' ' --identity-name {identity} --resource-group {rg} --yes') + self.cmd('identity federated-credential delete --name {fic3}' + ' --identity-name {identity} --resource-group {rg} --yes') + + # verify all are deleted self.cmd('identity federated-credential list --identity-name {identity} --resource-group {rg}', checks=[ self.check('type(@)', 'array'),