Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package azure-cli-core for openSUSE:Factory checked in at 2022-12-07 17:34:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-core (Old) and /work/SRC/openSUSE:Factory/.azure-cli-core.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-core" Wed Dec 7 17:34:50 2022 rev:46 rq:1040745 version:2.43.0 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-core/azure-cli-core.changes 2022-11-10 14:24:24.079068552 +0100 +++ /work/SRC/openSUSE:Factory/.azure-cli-core.new.1835/azure-cli-core.changes 2022-12-07 17:36:10.872938692 +0100 @@ -1,0 +2,9 @@ +Tue Dec 6 08:26:50 UTC 2022 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- New upstream release + + Version 2.43.0 + + For detailed information about changes see the + HISTORY.rst file provided with this package +- Update Requires from setup.py + +------------------------------------------------------------------- Old: ---- azure-cli-core-2.42.0.tar.gz New: ---- azure-cli-core-2.43.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-core.spec ++++++ --- /var/tmp/diff_new_pack.gx6TKV/_old 2022-12-07 17:36:11.316941123 +0100 +++ /var/tmp/diff_new_pack.gx6TKV/_new 2022-12-07 17:36:11.320941145 +0100 @@ -17,7 +17,7 @@ Name: azure-cli-core -Version: 2.42.0 +Version: 2.43.0 Release: 0 Summary: Microsoft Azure CLI Core Module License: MIT ++++++ azure-cli-core-2.42.0.tar.gz -> azure-cli-core-2.43.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/HISTORY.rst new/azure-cli-core-2.43.0/HISTORY.rst --- old/azure-cli-core-2.42.0/HISTORY.rst 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/HISTORY.rst 2022-12-02 07:07:20.000000000 +0100 @@ -3,6 +3,15 @@ Release History =============== +2.43.0 +++++++ +* `aaz`: Fix `has_value` function for list, dict and object arg types (#24625) +* `aaz`: Support argument preview and experimental (#24637) +* `aaz`: Add registered property for `AAZBaseArg` (#24640) +* `aaz`: Add aazlist and aazdict args transform help functions (#24690) +* `aaz`: Support camel case key in `AAZObjectType` (#24771) +* Disable removing and updating system extension in Cloud Shell (#24361) + 2.42.0 ++++++ * `aaz`: Support `FreeFormDictType` and `FreeFormDictArg` (#24183) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/PKG-INFO new/azure-cli-core-2.43.0/PKG-INFO --- old/azure-cli-core-2.42.0/PKG-INFO 2022-10-28 05:24:43.010562700 +0200 +++ new/azure-cli-core-2.43.0/PKG-INFO 2022-12-02 07:07:41.304211400 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.42.0 +Version: 2.43.0 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/__init__.py new/azure-cli-core-2.43.0/azure/cli/core/__init__.py --- old/azure-cli-core-2.42.0/azure/cli/core/__init__.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/__init__.py 2022-12-02 07:07:20.000000000 +0100 @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long -__version__ = "2.42.0" +__version__ = "2.43.0" import os import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/_arg.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/_arg.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/_arg.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/_arg.py 2022-12-02 07:07:20.000000000 +0100 @@ -7,16 +7,20 @@ from azure.cli.core import azclierror from knack.arguments import CLICommandArgument, CaseInsensitiveList +from knack.preview import PreviewItem +from knack.experimental import ExperimentalItem +from knack.util import status_tag_messages from ._arg_action import AAZSimpleTypeArgAction, AAZObjectArgAction, AAZDictArgAction, AAZFreeFormDictArgAction, \ AAZListArgAction, AAZGenericUpdateAction, AAZGenericUpdateForceStringAction -from ._base import AAZBaseType, AAZUndefined +from ._base import AAZBaseType, AAZUndefined, AAZBaseValue from ._field_type import AAZObjectType, AAZStrType, AAZIntType, AAZBoolType, AAZFloatType, AAZListType, AAZDictType, \ AAZSimpleType, AAZFreeFormDictType from ._field_value import AAZObject from ._arg_fmt import AAZObjectArgFormat, AAZListArgFormat, AAZDictArgFormat, AAZFreeFormDictArgFormat, \ AAZSubscriptionIdArgFormat, AAZResourceLocationArgFormat, AAZResourceIdArgFormat, AAZUuidFormat, AAZDateFormat, \ AAZTimeFormat, AAZDateTimeFormat, AAZDurationFormat +from .exceptions import AAZUnregisteredArg # pylint: disable=redefined-builtin, protected-access, too-few-public-methods @@ -72,7 +76,7 @@ """Base argument""" def __init__(self, options=None, required=False, help=None, arg_group=None, is_preview=False, is_experimental=False, - id_part=None, default=AAZUndefined, blank=AAZUndefined, nullable=False, fmt=None): + id_part=None, default=AAZUndefined, blank=AAZUndefined, nullable=False, fmt=None, registered=True): """ :param options: argument optional names. @@ -87,6 +91,7 @@ :param blank: when the argument flag is used without value data, the blank value will be used. :param nullable: argument can accept `None` as value :param fmt: argument format + :param registered: control whether register argument into command display """ super().__init__(options=options, nullable=nullable) self._help = {} # the key in self._help can be 'name', 'short-summary', 'long-summary', 'populator-commands' @@ -106,12 +111,18 @@ self._default = default self._blank = blank self._fmt = fmt + self._registered = registered - def to_cmd_arg(self, name): + def to_cmd_arg(self, name, **kwargs): """ convert AAZArg to CLICommandArgument """ + if not self._registered: + # argument will not registered in command display + raise AAZUnregisteredArg() + + options_list = [*self._options] if self._options else None arg = CLICommandArgument( dest=name, - options_list=[*self._options] if self._options else None, + options_list=options_list, # if default is not None, arg is not required. required=self._required if self._default == AAZUndefined else False, help=self._help.get('short-summary', None), @@ -124,6 +135,42 @@ if self._blank != AAZUndefined: arg.nargs = '?' + cli_ctx = kwargs.get('cli_ctx', None) + if cli_ctx is None: + # define mock cli_ctx for PreviewItem and ExperimentalItem + class _CLI_CTX: + enable_color = False + cli_ctx = _CLI_CTX + + if options_list is None: + target = f"--{name.replace('_', '-')}" + else: + target = sorted(options_list, key=len)[-1] + + if self._is_preview: + def _get_preview_arg_message(self): + subject = "{} '{}'".format(self.object_type.capitalize(), self.target) + return status_tag_messages['preview'].format(subject) + arg.preview_info = PreviewItem( + cli_ctx=cli_ctx, + target=target, + object_type="argument", + message_func=_get_preview_arg_message + ) + + if self._is_experimental: + def _get_experimental_arg_message(self): + # "Argument xxx" + subject = "{} '{}'".format(self.object_type.capitalize(), self.target) + return status_tag_messages['experimental'].format(subject) + + arg.experimental_info = ExperimentalItem( + cli_ctx=cli_ctx, + target=target, + object_type="argument", + message_func=_get_experimental_arg_message + ) + action = self._build_cmd_action() # call sub class's implementation to build CLICommandArgument action if action: arg.action = action @@ -148,8 +195,8 @@ super().__init__(**kwargs) self.enum = AAZArgEnum(enum, case_sensitive=enum_case_sensitive) if enum else None - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) if self.enum: arg.choices = self.enum.to_choices() # convert it's enum value into choices in arg return arg @@ -260,9 +307,9 @@ def _build_cmd_action(self): raise NotImplementedError() - def to_cmd_arg(self, name): + def to_cmd_arg(self, name, **kwargs): from ._help import shorthand_help_messages - arg = super().to_cmd_arg(name) + arg = super().to_cmd_arg(name, **kwargs) short_summary = arg.type.settings.get('help', None) or '' if short_summary: short_summary += ' ' @@ -281,8 +328,8 @@ fmt = fmt or AAZObjectArgFormat() super().__init__(fmt=fmt, **kwargs) - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) if self._blank != AAZUndefined: arg.nargs = '*' else: @@ -306,8 +353,8 @@ fmt = fmt or AAZDictArgFormat() super().__init__(fmt=fmt, **kwargs) - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) if self._blank != AAZUndefined: arg.nargs = '*' else: @@ -331,9 +378,8 @@ fmt = fmt or AAZFreeFormDictArgFormat() super().__init__(fmt=fmt, **kwargs) - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) - + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) short_summary = arg.type.settings.get('help', None) or '' if short_summary: short_summary += ' ' @@ -359,8 +405,8 @@ super().__init__(fmt=fmt, **kwargs) self.singular_options = singular_options - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) if self.singular_options: assert arg.options_list arg.options_list.extend(self.singular_options) # support to parse singular options @@ -396,11 +442,10 @@ **kwargs ) - def to_cmd_arg(self, name): + def to_cmd_arg(self, name, **kwargs): from azure.cli.core.commands.parameters import get_resource_group_completion_list from azure.cli.core.local_context import LocalContextAttribute, LocalContextAction, ALL - arg = super().to_cmd_arg(name) - + arg = super().to_cmd_arg(name, **kwargs) arg.completer = get_resource_group_completion_list arg.configured_default = 'group' arg.local_context_attribute = LocalContextAttribute( @@ -427,10 +472,10 @@ **kwargs ) - def to_cmd_arg(self, name): + def to_cmd_arg(self, name, **kwargs): from azure.cli.core.commands.parameters import get_location_completion_list from azure.cli.core.local_context import LocalContextAttribute, LocalContextAction, ALL - arg = super().to_cmd_arg(name) + arg = super().to_cmd_arg(name, **kwargs) if self._required and \ isinstance(self._fmt, AAZResourceLocationArgFormat) and self._fmt._resource_group_arg is not None: # when location is required and it will be retrived from resource group by default, arg is not required. @@ -468,9 +513,9 @@ **kwargs ) - def to_cmd_arg(self, name): + def to_cmd_arg(self, name, **kwargs): from azure.cli.core._completers import get_subscription_id_list - arg = super().to_cmd_arg(name) + arg = super().to_cmd_arg(name, **kwargs) arg.completer = get_subscription_id_list return arg @@ -521,8 +566,8 @@ **kwargs, ) - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) arg.nargs = '+' arg.metavar = 'KEY=VALUE' return arg @@ -548,8 +593,8 @@ **kwargs, ) - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) arg.nargs = '+' arg.metavar = 'LIST KEY=VALUE' return arg @@ -575,8 +620,8 @@ **kwargs, ) - def to_cmd_arg(self, name): - arg = super().to_cmd_arg(name) + def to_cmd_arg(self, name, **kwargs): + arg = super().to_cmd_arg(name, **kwargs) arg.nargs = '+' arg.metavar = 'LIST INDEX' return arg @@ -588,4 +633,7 @@ def has_value(arg_value): + if isinstance(arg_value, AAZBaseValue): + # handle patch value for list, object, dict + return arg_value.to_serialized_data() != AAZUndefined return arg_value != AAZUndefined diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/_command.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/_command.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/_command.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/_command.py 2022-12-02 07:07:20.000000000 +0100 @@ -22,7 +22,7 @@ from ._paging import AAZPaged from ._poller import AAZLROPoller from ._command_ctx import AAZCommandCtx -from .exceptions import AAZUnknownFieldError +from .exceptions import AAZUnknownFieldError, AAZUnregisteredArg class AAZCommandGroup: @@ -160,7 +160,10 @@ args = {} for name, field in schema._fields.items(): # generate command arguments from argument schema. - args[name] = field.to_cmd_arg(name) + try: + args[name] = field.to_cmd_arg(name, cli_ctx=self.cli_ctx) + except AAZUnregisteredArg: + continue return list(args.items()) def update_argument(self, param_name, argtype): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/_field_type.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/_field_type.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/_field_type.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/_field_type.py 2022-12-02 07:07:20.000000000 +0100 @@ -7,6 +7,7 @@ from collections import OrderedDict from ._base import AAZBaseType, AAZValuePatch, AAZUndefined from ._field_value import AAZObject, AAZDict, AAZFreeFormDict, AAZList, AAZSimpleValue +from ._utils import to_snack_case from .exceptions import AAZUnknownFieldError, AAZConflictFieldDefinitionError, AAZValuePrecisionLossError, \ AAZInvalidFieldError @@ -164,6 +165,11 @@ return key if key in self._fields_alias_map: return self._fields_alias_map[key] + if isinstance(key, str) and key != key.lower(): + # if key is not found convert camel case key to snack case key + key = to_snack_case(key) + if key in self._fields: + return key return None def process_data(self, data, **kwargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/_help.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/_help.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/_help.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/_help.py 2022-12-02 07:07:20.000000000 +0100 @@ -109,6 +109,10 @@ max_header_len = 0 for prop_schema in schema._fields.values(): + if not prop_schema._registered: + # ignore unregistered args + continue + prop_tags = cls._build_schema_tags(prop_schema) prop_name = ' '.join(prop_schema._options) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/_utils.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/_utils.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/_utils.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/_utils.py 2022-12-02 07:07:20.000000000 +0100 @@ -10,6 +10,13 @@ from ._base import AAZBlankArgValue +def to_snack_case(name, separator='_'): + assert isinstance(name, str) + name = re.sub('(.)([A-Z][a-z]+)', r'\1' + separator + r'\2', name) + name = re.sub('([a-z0-9])([A-Z])', r'\1' + separator + r'\2', name).lower() + return name.replace('-', separator).replace('_', separator) + + class AAZShortHandSyntaxParser: NULL_EXPRESSIONS = ('null',) # user can use "null" string to pass `None` value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/exceptions.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/exceptions.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/exceptions.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/exceptions.py 2022-12-02 07:07:20.000000000 +0100 @@ -77,3 +77,7 @@ idx += i return f"InvalidArgumentValue: {idx}: {self.msg}" return f"InvalidArgumentValue: {self.msg}" + + +class AAZUnregisteredArg(NotImplementedError): + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/aaz/utils.py new/azure-cli-core-2.43.0/azure/cli/core/aaz/utils.py --- old/azure-cli-core-2.42.0/azure/cli/core/aaz/utils.py 1970-01-01 01:00:00.000000000 +0100 +++ new/azure-cli-core-2.43.0/azure/cli/core/aaz/utils.py 2022-12-02 07:07:20.000000000 +0100 @@ -0,0 +1,116 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +# pylint: disable=protected-access + +from ._arg import AAZListArg, AAZDictArg, has_value +from ._field_value import AAZList, AAZDict +from ._base import AAZBaseValue + + +def assign_aaz_list_arg(target: AAZList, source: AAZList, element_transformer=None): + """ an convenience function to transform from a source AAZListArg to a target AAZListArg + Example: + + args.target = assign_aaz_list_arg(args.target, args.source, lambda idx, e: {'idx': idx, "prop": e}) + """ + assert isinstance(target, AAZBaseValue) + assert isinstance(source, AAZBaseValue) + + target_schema = target._schema + source_schema = source._schema + assert isinstance(target_schema, AAZListArg) + assert isinstance(source_schema, AAZListArg) + + assert target_schema._nullable == source_schema._nullable, "Inconsist nullable property between target and " \ + "source args" + assert target_schema.Element._nullable == source_schema.Element._nullable, "Inconsist nullable property between " \ + "target element and source arg element" + + if not has_value(source): + return target + + if source == None: # noqa: E711, pylint: disable=singleton-comparison + return None + + if not source._is_patch: + # return the whole array + data = [] + for idx, element in enumerate(source): + if not has_value(element): + continue + if element == None: # noqa: E711, pylint: disable=singleton-comparison + data.append(None) + elif element_transformer: + data.append(element_transformer(idx, element)) + else: + data.append(element) + return data + + # assign by patch way + for idx, element in enumerate(source): + if not has_value(element): + continue + if element == None: # noqa: E711, pylint: disable=singleton-comparison + target[idx] = None + elif element_transformer: + target[idx] = element_transformer(idx, element) + else: + target[idx] = element + + return target + + +def assign_aaz_dict_arg(target: AAZDict, source: AAZDict, element_transformer=None): + """ an convenience function to transform from a source AAZDictArg to a target AAZDictArg + Example: + + args.target = assign_aaz_dict_arg(args.target, args.source, lambda key, e: {'name': key, "prop": e}) + """ + + assert isinstance(target, AAZBaseValue) + assert isinstance(source, AAZBaseValue) + + target_schema = target._schema + source_schema = source._schema + assert isinstance(target_schema, AAZDictArg) + assert isinstance(source_schema, AAZDictArg) + + assert target_schema._nullable == source_schema._nullable, "Inconsist nullable property between target and " \ + "source args" + assert target_schema.Element._nullable == source_schema.Element._nullable, "Inconsist nullable property between " \ + "target element and source arg element" + + if not has_value(source): + return target + + if source == None: # noqa: E711, pylint: disable=singleton-comparison + return None + + if not source._is_patch: + # return the whole array + data = {} + for key, element in source.items(): + if not has_value(element): + continue + if element == None: # noqa: E711, pylint: disable=singleton-comparison + data[key] = None + elif element_transformer: + data[key] = element_transformer(key, element) + else: + data[key] = element + return data + + # assign by patch way + for key, element in source.items(): + if not has_value(element): + continue + if element == None: # noqa: E711, pylint: disable=singleton-comparison + target[key] = None + elif element_transformer: + target[key] = element_transformer(key, element) + else: + target[key] = element + + return target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/auth/msal_authentication.py new/azure-cli-core-2.43.0/azure/cli/core/auth/msal_authentication.py --- old/azure-cli-core-2.42.0/azure/cli/core/auth/msal_authentication.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/auth/msal_authentication.py 2022-12-02 07:07:20.000000000 +0100 @@ -6,8 +6,14 @@ """ Credentials defined in this module are alternative implementations of credentials provided by Azure Identity. -These credentials implement azure.core.credentials.TokenCredential by exposing get_token method for Track 2 +These credentials implement azure.core.credentials.TokenCredential by exposing `get_token` method for Track 2 SDK invocation. + +If you want to implement your own credential, the credential must also expose `get_token` method. + +`get_token` method takes `scopes` as positional arguments and other optional `kwargs`, such as `claims`, `data`. +The return value should be a named tuple containing two elements: token (str), expires_on (int). You may simply use +azure.cli.core.auth.util.AccessToken to build the return value. See below credentials as examples. """ from knack.log import get_logger diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/commands/client_factory.py new/azure-cli-core-2.43.0/azure/cli/core/commands/client_factory.py --- old/azure-cli-core-2.42.0/azure/cli/core/commands/client_factory.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/commands/client_factory.py 2022-12-02 07:07:20.000000000 +0100 @@ -48,10 +48,23 @@ def get_mgmt_service_client(cli_ctx, client_or_resource_type, subscription_id=None, api_version=None, - aux_subscriptions=None, aux_tenants=None, **kwargs): - """ - :params subscription_id: the current account's subscription - :param aux_subscriptions: mainly for cross tenant scenarios, say vnet peering. + aux_subscriptions=None, aux_tenants=None, credential=None, **kwargs): + """Create Python SDK mgmt-plane client. In addition to directly creating the client instance, this centralized + client factory adds more features to the client instance: + - multi-API + - server telemetry + - safe logging + - cross-tenant authentication + + :param cli_ctx: AzCli instance + :param client_or_resource_type: Python SDK mgmt-plane client type or a member of + azure.cli.core.profiles._shared.ResourceType + :param subscription_id: Override the current login context's subscription + :param api_version: Override the client or resource type's default API version + :param aux_subscriptions: For cross-tenant authentication, such as vnet peering + :param aux_tenants: For cross-tenant authentication, such as vnet peering + :param credential: Custom credential to override the current login context's credential + For more information, see src/azure-cli-core/azure/cli/core/auth/msal_authentication.py """ if not subscription_id and 'subscription_id' in cli_ctx.data: subscription_id = cli_ctx.data['subscription_id'] @@ -70,7 +83,7 @@ client, _ = _get_mgmt_service_client(cli_ctx, client_type, subscription_id=subscription_id, api_version=api_version, sdk_profile=sdk_profile, aux_subscriptions=aux_subscriptions, - aux_tenants=aux_tenants, + aux_tenants=aux_tenants, credential=credential, **kwargs) return client @@ -201,6 +214,7 @@ sdk_profile=None, aux_subscriptions=None, aux_tenants=None, + credential=None, **kwargs): from azure.cli.core._profile import Profile logger.debug('Getting management service client client_type=%s', client_type.__name__) @@ -208,10 +222,17 @@ # Track 1 SDK doesn't maintain the `resource`. The `resource` of the token is the one passed to # get_login_credentials. resource = resource or cli_ctx.cloud.endpoints.active_directory_resource_id - profile = Profile(cli_ctx=cli_ctx) - cred, subscription_id, _ = profile.get_login_credentials(subscription_id=subscription_id, resource=resource, - aux_subscriptions=aux_subscriptions, - aux_tenants=aux_tenants) + + if credential: + # Use a custom credential + if not subscription_id: + raise ValueError('credential and subscription_id must be specified at the same time.') + else: + # Get a credential for the current `az login` context + profile = Profile(cli_ctx=cli_ctx) + credential, subscription_id, _ = profile.get_login_credentials( + subscription_id=subscription_id, resource=resource, + aux_subscriptions=aux_subscriptions, aux_tenants=aux_tenants) client_kwargs = {} if base_url_bound: @@ -224,12 +245,12 @@ client_kwargs.update(kwargs) if is_track2(client_type): - client_kwargs.update(_prepare_mgmt_client_kwargs_track2(cli_ctx, cred)) + client_kwargs.update(_prepare_mgmt_client_kwargs_track2(cli_ctx, credential)) if subscription_bound: - client = client_type(cred, subscription_id, **client_kwargs) + client = client_type(credential, subscription_id, **client_kwargs) else: - client = client_type(cred, **client_kwargs) + client = client_type(credential, **client_kwargs) if not is_track2(client): configure_common_settings(cli_ctx, client) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/extension/operations.py new/azure-cli-core-2.43.0/azure/cli/core/extension/operations.py --- old/azure-cli-core-2.42.0/azure/cli/core/extension/operations.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/extension/operations.py 2022-12-02 07:07:20.000000000 +0100 @@ -308,37 +308,39 @@ pip_extra_index_urls=None, pip_proxy=None, system=None, version=None, cli_ctx=None, upgrade=None): ext_sha256 = None + update_to_latest = version == 'latest' and not source version = None if version == 'latest' else version cmd_cli_ctx = cli_ctx or cmd.cli_ctx if extension_name: cmd_cli_ctx.get_progress_controller().add(message='Searching') - ext = None - set_extension_management_detail(extension_name, version) - try: - ext = get_extension(extension_name) - except ExtensionNotInstalledException: - pass - if ext: - if isinstance(ext, WheelExtension): - if not upgrade: - logger.warning("Extension '%s' is already installed.", extension_name) - return - logger.warning("Extension '%s' %s is already installed.", extension_name, ext.get_version()) - if version and version == ext.get_version(): - return - logger.warning("It will be overridden with version {}.".format(version) if version else "It will be updated if available.") - update_extension(cmd=cmd, extension_name=extension_name, index_url=index_url, pip_extra_index_urls=pip_extra_index_urls, pip_proxy=pip_proxy, cli_ctx=cli_ctx, version=version) - return - logger.warning("Overriding development version of '%s' with production version.", extension_name) try: source, ext_sha256 = resolve_from_index(extension_name, index_url=index_url, target_version=version, cli_ctx=cmd_cli_ctx) except NoExtensionCandidatesError as err: logger.debug(err) err = "{}\n\nUse --debug for more information".format(err.args[0]) raise CLIError(err) - ext_name, ext_version = _get_extension_info_from_source(source) - set_extension_management_detail(extension_name if extension_name else ext_name, ext_version) + extension_name, ext_version = _get_extension_info_from_source(source) + set_extension_management_detail(extension_name, ext_version) + ext = None + try: + ext = get_extension(extension_name) + except ExtensionNotInstalledException: + pass + if ext: + if isinstance(ext, WheelExtension): + logger.warning("Extension '%s' %s is already installed.", extension_name, ext.get_version()) + if not upgrade: + return + if ext_version == ext.get_version(): + if update_to_latest: + logger.warning("Latest version of '%s' is already installed.", extension_name) + return + + logger.warning("It will be overridden with version %s.", ext_version) + update_extension(cmd=cmd, extension_name=extension_name, index_url=index_url, pip_extra_index_urls=pip_extra_index_urls, pip_proxy=pip_proxy, cli_ctx=cli_ctx, version=ext_version, download_url=source, ext_sha256=ext_sha256) + return + logger.warning("Overriding development version of '%s' with production version.", extension_name) extension_name = _add_whl_ext(cli_ctx=cmd_cli_ctx, source=source, ext_sha256=ext_sha256, pip_extra_index_urls=pip_extra_index_urls, pip_proxy=pip_proxy, system=system) try: @@ -353,6 +355,14 @@ pass +def is_cloud_shell_system_extension(ext_path): + from azure.cli.core.util import in_cloud_console + if in_cloud_console(): + if ext_path.startswith('/usr/lib/python3'): + return True + return False + + def remove_extension(extension_name): try: # Get the extension and it will raise an error if it doesn't exist @@ -361,6 +371,8 @@ raise CLIError( "Extension '{name}' was installed in development mode. Remove using " "`azdev extension remove {name}`".format(name=extension_name)) + if is_cloud_shell_system_extension(ext.path): + raise CLIError(f"Cannot remove system extension {extension_name} in Cloud Shell.") # We call this just before we remove the extension so we can get the metadata before it is gone _augment_telemetry_with_ext_info(extension_name, ext) rmtree_with_retry(ext.path) @@ -387,13 +399,17 @@ raise CLIError(e) -def update_extension(cmd=None, extension_name=None, index_url=None, pip_extra_index_urls=None, pip_proxy=None, cli_ctx=None, version=None): +def update_extension(cmd=None, extension_name=None, index_url=None, pip_extra_index_urls=None, pip_proxy=None, cli_ctx=None, version=None, download_url=None, ext_sha256=None): try: cmd_cli_ctx = cli_ctx or cmd.cli_ctx ext = get_extension(extension_name, ext_type=WheelExtension) + if is_cloud_shell_system_extension(ext.path): + raise CLIError( + f"Cannot update system extension {extension_name}, please wait until Cloud Shell updates it in the next release.") cur_version = ext.get_version() try: - download_url, ext_sha256 = resolve_from_index(extension_name, cur_version=cur_version, index_url=index_url, target_version=version, cli_ctx=cmd_cli_ctx) + if not download_url: + download_url, ext_sha256 = resolve_from_index(extension_name, cur_version=cur_version, index_url=index_url, target_version=version, cli_ctx=cmd_cli_ctx) _, ext_version = _get_extension_info_from_source(download_url) set_extension_management_detail(extension_name, ext_version) except NoExtensionCandidatesError as err: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure/cli/core/profiles/_shared.py new/azure-cli-core-2.43.0/azure/cli/core/profiles/_shared.py --- old/azure-cli-core-2.42.0/azure/cli/core/profiles/_shared.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure/cli/core/profiles/_shared.py 2022-12-02 07:07:20.000000000 +0100 @@ -152,7 +152,7 @@ AZURE_API_PROFILES = { 'latest': { - ResourceType.MGMT_STORAGE: '2022-05-01', + ResourceType.MGMT_STORAGE: '2022-09-01', ResourceType.MGMT_NETWORK: '2022-01-01', ResourceType.MGMT_COMPUTE: SDKProfile('2022-08-01', { 'resource_skus': '2019-04-01', @@ -178,9 +178,7 @@ ResourceType.MGMT_RESOURCE_TEMPLATESPECS: '2021-05-01', ResourceType.MGMT_RESOURCE_PRIVATELINKS: '2020-05-01', ResourceType.MGMT_NETWORK_DNS: '2018-05-01', - ResourceType.MGMT_KEYVAULT: SDKProfile('2021-04-01-preview', { - 'vaults': '2022-07-01' - }), + ResourceType.MGMT_KEYVAULT: '2022-07-01', ResourceType.MGMT_AUTHORIZATION: SDKProfile('2020-04-01-preview', { 'classic_administrators': '2015-06-01', 'role_definitions': '2018-01-01-preview', @@ -243,7 +241,7 @@ }), ResourceType.MGMT_MSI: '2022-01-31-preview', ResourceType.MGMT_APPSERVICE: '2022-03-01', - ResourceType.MGMT_IOTHUB: '2021-07-02', + ResourceType.MGMT_IOTHUB: '2022-04-30-preview', ResourceType.MGMT_IOTDPS: '2021-10-15', ResourceType.MGMT_IOTCENTRAL: '2021-11-01-preview', ResourceType.MGMT_ARO: '2022-04-01', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure_cli_core.egg-info/PKG-INFO new/azure-cli-core-2.43.0/azure_cli_core.egg-info/PKG-INFO --- old/azure-cli-core-2.42.0/azure_cli_core.egg-info/PKG-INFO 2022-10-28 05:24:42.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure_cli_core.egg-info/PKG-INFO 2022-12-02 07:07:40.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.42.0 +Version: 2.43.0 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure_cli_core.egg-info/SOURCES.txt new/azure-cli-core-2.43.0/azure_cli_core.egg-info/SOURCES.txt --- old/azure-cli-core-2.42.0/azure_cli_core.egg-info/SOURCES.txt 2022-10-28 05:24:42.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure_cli_core.egg-info/SOURCES.txt 2022-12-02 07:07:40.000000000 +0100 @@ -51,6 +51,7 @@ azure/cli/core/aaz/_poller.py azure/cli/core/aaz/_utils.py azure/cli/core/aaz/exceptions.py +azure/cli/core/aaz/utils.py azure/cli/core/auth/__init__.py azure/cli/core/auth/adal_authentication.py azure/cli/core/auth/binary_cache.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/azure_cli_core.egg-info/requires.txt new/azure-cli-core-2.43.0/azure_cli_core.egg-info/requires.txt --- old/azure-cli-core-2.42.0/azure_cli_core.egg-info/requires.txt 2022-10-28 05:24:42.000000000 +0200 +++ new/azure-cli-core-2.43.0/azure_cli_core.egg-info/requires.txt 2022-12-02 07:07:40.000000000 +0100 @@ -4,7 +4,7 @@ cryptography humanfriendly~=10.0 jmespath -knack~=0.10.0 +knack~=0.10.1 msal-extensions~=1.0.0 msal[broker]==1.20.0 msrestazure~=0.6.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.42.0/setup.py new/azure-cli-core-2.43.0/setup.py --- old/azure-cli-core-2.42.0/setup.py 2022-10-28 05:24:17.000000000 +0200 +++ new/azure-cli-core-2.43.0/setup.py 2022-12-02 07:07:20.000000000 +0100 @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "2.42.0" +VERSION = "2.43.0" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions. @@ -49,7 +49,7 @@ 'cryptography', 'humanfriendly~=10.0', 'jmespath', - 'knack~=0.10.0', + 'knack~=0.10.1', 'msal-extensions~=1.0.0', 'msal[broker]==1.20.0', 'msrestazure~=0.6.4',