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 2024-02-08 19:02:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-core (Old) and /work/SRC/openSUSE:Factory/.azure-cli-core.new.1815 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-core" Thu Feb 8 19:02:56 2024 rev:62 rq:1145074 version:2.57.0 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-core/azure-cli-core.changes 2024-01-19 23:00:24.234096270 +0100 +++ /work/SRC/openSUSE:Factory/.azure-cli-core.new.1815/azure-cli-core.changes 2024-02-08 19:03:05.477106656 +0100 @@ -1,0 +2,9 @@ +Wed Feb 7 09:42:58 UTC 2024 - John Paul Adrian Glaubitz <[email protected]> + +- New upstream release + + Version 2.57.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.56.0.tar.gz New: ---- azure-cli-core-2.57.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-core.spec ++++++ --- /var/tmp/diff_new_pack.tkQvOT/_old 2024-02-08 19:03:06.177131961 +0100 +++ /var/tmp/diff_new_pack.tkQvOT/_new 2024-02-08 19:03:06.177131961 +0100 @@ -17,7 +17,7 @@ Name: azure-cli-core -Version: 2.56.0 +Version: 2.57.0 Release: 0 Summary: Microsoft Azure CLI Core Module License: MIT @@ -46,7 +46,7 @@ Requires: python3-knack < 1.0.0 Requires: python3-knack >= 0.11.0 Requires: python3-msal < 2.0.0 -Requires: python3-msal >= 1.24.0~b2 +Requires: python3-msal >= 1.26.0 Requires: python3-msal-extensions < 2.0.0 Requires: python3-msal-extensions >= 1.0.0 Requires: python3-msrestazure < 0.7.0 ++++++ azure-cli-core-2.56.0.tar.gz -> azure-cli-core-2.57.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/HISTORY.rst new/azure-cli-core-2.57.0/HISTORY.rst --- old/azure-cli-core-2.56.0/HISTORY.rst 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/HISTORY.rst 2024-01-31 06:29:21.000000000 +0100 @@ -3,6 +3,11 @@ Release History =============== +2.57.0 +++++++ +* `aaz`: Handle null value when deserialize output (#28253) +* Add warning for customers when there're credentials in cli output if this feature has been turned on through `az config set clients.show_secrets_warning=True` (#27929) + 2.56.0 ++++++ * Minor fixes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/PKG-INFO new/azure-cli-core-2.57.0/PKG-INFO --- old/azure-cli-core-2.56.0/PKG-INFO 2024-01-08 10:08:25.818453800 +0100 +++ new/azure-cli-core-2.57.0/PKG-INFO 2024-01-31 06:29:52.665539000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.56.0 +Version: 2.57.0 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation @@ -27,7 +27,7 @@ Requires-Dist: jmespath Requires-Dist: knack~=0.11.0 Requires-Dist: msal-extensions~=1.0.0 -Requires-Dist: msal[broker]==1.24.0b2 +Requires-Dist: msal[broker]==1.26.0 Requires-Dist: msrestazure~=0.6.4 Requires-Dist: packaging>=20.9 Requires-Dist: paramiko<4.0.0,>=2.0.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/__init__.py new/azure-cli-core-2.57.0/azure/cli/core/__init__.py --- old/azure-cli-core-2.56.0/azure/cli/core/__init__.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/__init__.py 2024-01-31 06:29:21.000000000 +0100 @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long -__version__ = "2.56.0" +__version__ = "2.57.0" import os import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/aaz/_command.py new/azure-cli-core-2.57.0/azure/cli/core/aaz/_command.py --- old/azure-cli-core-2.56.0/azure/cli/core/aaz/_command.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/aaz/_command.py 2024-01-31 06:29:21.000000000 +0100 @@ -194,7 +194,7 @@ def processor(schema, result): """A processor used in AAZBaseValue to serialized data""" - if result == AAZUndefined: + if result == AAZUndefined or result is None: return result if isinstance(schema, AAZObjectType): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/commands/__init__.py new/azure-cli-core-2.57.0/azure/cli/core/commands/__init__.py --- old/azure-cli-core-2.56.0/azure/cli/core/commands/__init__.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/commands/__init__.py 2024-01-31 06:29:21.000000000 +0100 @@ -266,13 +266,14 @@ def __init__(self, loader, name, handler, description=None, table_transformer=None, arguments_loader=None, description_loader=None, - formatter_class=None, deprecate_info=None, validator=None, **kwargs): + formatter_class=None, sensitive_info=None, deprecate_info=None, validator=None, **kwargs): super(AzCliCommand, self).__init__(loader.cli_ctx, name, handler, description=description, table_transformer=table_transformer, arguments_loader=arguments_loader, description_loader=description_loader, formatter_class=formatter_class, deprecate_info=deprecate_info, validator=validator, **kwargs) self.loader = loader self.command_source = None + self.sensitive_info = sensitive_info self.no_wait_param = kwargs.get('no_wait_param', None) self.supports_no_wait = kwargs.get('supports_no_wait', False) self.exception_handler = kwargs.get('exception_handler', None) @@ -710,6 +711,8 @@ result = list(result) result = todict(result, AzCliCommandInvoker.remove_additional_prop_layer) + self._resolve_output_sensitive_data_warning(cmd_copy, result) + event_data = {'result': result} cmd_copy.cli_ctx.raise_event(EVENT_INVOKER_TRANSFORM_RESULT, event_data=event_data) return event_data['result'] @@ -812,6 +815,36 @@ if isinstance(cmd.command_source, ExtensionCommandSource) and cmd.command_source.overrides_command: logger.warning(cmd.command_source.get_command_warn_msg()) + def _resolve_output_sensitive_data_warning(self, cmd, result): + if not cmd.cli_ctx.config.getboolean('clients', 'show_secrets_warning', False): + return + + from ..credential_helper import sensitive_data_detailed_warning_message, sensitive_data_warning_message + sensitive_info = cmd.sensitive_info if hasattr(cmd, 'sensitive_info') else None + if sensitive_info: + message = sensitive_data_warning_message + if sensitive_info.sensitive_keys: + message = sensitive_data_detailed_warning_message.format(', '.join(sensitive_info.sensitive_keys)) + logger.warning(message) + return + + from ..credential_helper import distinguish_credential + from ..telemetry import set_secrets_detected + try: + containing_credential, secret_property_names = distinguish_credential(result) + if not containing_credential: + set_secrets_detected(False) + return + + message = sensitive_data_warning_message + if secret_property_names: + message = sensitive_data_detailed_warning_message.format(', '.join(secret_property_names)) + logger.warning(message) + set_secrets_detected(True) + except Exception: # pylint: disable=broad-except + # ignore all exceptions, as this is just a warning + pass + def resolve_confirmation(self, cmd, parsed_args): confirm = cmd.confirmation and not parsed_args.__dict__.pop('yes', None) \ and not cmd.cli_ctx.config.getboolean('core', 'disable_confirm_prompt', fallback=False) @@ -1424,6 +1457,11 @@ if is_experimental: merged_kwargs['experimental_info'] = ExperimentalItem(self.command_loader.cli_ctx, object_type='command') + def sensitive(self, **kwargs): + from .sensitive import SensitiveItem + kwargs['object_type'] = 'command' + return SensitiveItem(self.command_loader.cli_ctx, **kwargs) + def register_cache_arguments(cli_ctx): from knack import events diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/commands/arm.py new/azure-cli-core-2.57.0/azure/cli/core/commands/arm.py --- old/azure-cli-core-2.56.0/azure/cli/core/commands/arm.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/commands/arm.py 2024-01-31 06:29:21.000000000 +0100 @@ -175,11 +175,14 @@ return str.__new__(cls, val) -def resource_exists(cli_ctx, resource_group, name, namespace, type, **_): # pylint: disable=redefined-builtin +def resource_exists(cli_ctx, subscription, resource_group, name, namespace, type, + **_): # pylint: disable=redefined-builtin ''' Checks if the given resource exists. ''' odata_filter = "resourceGroup eq '{}' and name eq '{}'" \ " and resourceType eq '{}/{}'".format(resource_group, name, namespace, type) - client = get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES).resources + # Support cross subscription resource existence check + client = get_mgmt_service_client( + cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES, subscription_id=subscription).resources existing = len(list(client.list(filter=odata_filter))) == 1 return existing @@ -386,9 +389,9 @@ cli_ctx.register_event(EVENT_INVOKER_PRE_LOAD_ARGUMENTS, add_subscription_parameter) -add_usage = '--add property.listProperty <key=value, string or JSON string>' -set_usage = '--set property1.property2=<value>' -remove_usage = '--remove property.list <indexToRemove> OR --remove propertyToRemove' +add_usage = '`--add property.listProperty <key=value, string or JSON string>`' +set_usage = '`--set property1.property2=<value>`' +remove_usage = '`--remove property.list <indexToRemove>` OR `--remove propertyToRemove`' def _get_operations_tmpl(cmd, custom_command=False): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/commands/constants.py new/azure-cli-core-2.57.0/azure/cli/core/commands/constants.py --- old/azure-cli-core-2.56.0/azure/cli/core/commands/constants.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/commands/constants.py 2024-01-31 06:29:21.000000000 +0100 @@ -12,7 +12,7 @@ CLI_COMMAND_KWARGS = ['transform', 'table_transformer', 'confirmation', 'exception_handler', 'client_factory', 'operations_tmpl', 'no_wait_param', 'supports_no_wait', 'validator', - 'client_arg_name', 'doc_string_source', 'deprecate_info', + 'client_arg_name', 'doc_string_source', 'deprecate_info', 'sensitive_info', 'supports_local_cache', 'model_path'] + CLI_COMMON_KWARGS CLI_PARAM_KWARGS = \ ['id_part', 'completer', 'validator', 'options_list', 'configured_default', 'arg_group', 'arg_type', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/commands/sensitive.py new/azure-cli-core-2.57.0/azure/cli/core/commands/sensitive.py --- old/azure-cli-core-2.56.0/azure/cli/core/commands/sensitive.py 1970-01-01 01:00:00.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/commands/sensitive.py 2024-01-31 06:29:21.000000000 +0100 @@ -0,0 +1,85 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from knack.util import StatusTag + +_SENSITIVE_TAG = '[Sensitive]' +_sensitive_kwarg = 'sensitive_info' +_config_key = 'sensitive' + + +def resolve_sensitive_info(cli_ctx, name): + + def _get_command(name): + return cli_ctx.invocation.commands_loader.command_table[name] + + def _get_command_group(name): + return cli_ctx.invocation.commands_loader.command_group_table.get(name, None) + + sensitive_info = None + try: + command = _get_command(name) + sensitive_info = getattr(command, _sensitive_kwarg, None) + except KeyError: + command_group = _get_command_group(name) + group_kwargs = getattr(command_group, 'group_kwargs', None) + if group_kwargs: + sensitive_info = group_kwargs.get(_sensitive_kwarg, None) + return sensitive_info + + +# pylint: disable=too-many-instance-attributes +class SensitiveItem(StatusTag): + + def __init__(self, cli_ctx, object_type='', redact=True, sensitive_keys=None, + target=None, tag_func=None, message_func=None, **kwargs): + """ Create a collection of sensitive metadata. + + :param cli_ctx: The CLI context associated with the sensitive item. + :type cli_ctx: knack.cli.CLI + :param object_type: A label describing the type of object containing sensitive info. + :type: object_type: str + :param redact: Whether or not to redact the sensitive information. + :type redact: bool + :param target: The name of the object containing sensitive info. + :type target: str + :param tag_func: Callable which returns the desired unformatted tag string for the sensitive item. + Omit to use the default. + :type tag_func: callable + :param message_func: Callable which returns the desired unformatted message string for the sensitive item. + Omit to use the default. + :type message_func: callable + """ + + def _default_get_message(self): + from ..credential_helper import sensitive_data_detailed_warning_message, sensitive_data_warning_message + if self.sensitive_keys: + return sensitive_data_detailed_warning_message.format(', '.join(self.sensitive_keys)) + return sensitive_data_warning_message + + super().__init__( + cli_ctx=cli_ctx, + object_type=object_type, + target=target, + color='\x1b[33m', + tag_func=tag_func or (lambda _: _SENSITIVE_TAG), + message_func=message_func or _default_get_message + ) + self.redact = redact + self.sensitive_keys = sensitive_keys if sensitive_keys else [] + + +class ImplicitSensitiveItem(SensitiveItem): + + def __init__(self, **kwargs): + + def get_implicit_experimental_message(self): + return "{} may contain sensitive data, please take care.".format("Command group '{}'".format(self.target)) + + kwargs.update({ + 'tag_func': lambda _: '', + 'message_func': get_implicit_experimental_message + }) + super().__init__(**kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/credential_helper.py new/azure-cli-core-2.57.0/azure/cli/core/credential_helper.py --- old/azure-cli-core-2.56.0/azure/cli/core/credential_helper.py 1970-01-01 01:00:00.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/credential_helper.py 2024-01-31 06:29:21.000000000 +0100 @@ -0,0 +1,152 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=line-too-long + +import re +import json +from enum import Enum + +sensitive_data_warning_message = '[Warning] This output may compromise security by showing secrets. Learn more at: https://go.microsoft.com/fwlink/?linkid=2258669' +sensitive_data_detailed_warning_message = '[Warning] This output may compromise security by showing the following secrets: {}. Learn more at: https://go.microsoft.com/fwlink/?linkid=2258669' + + +class CredentialType(Enum): + # ([?&;]) - match character '?' or '&' or ';' as group 1, which is the prefix of signature within sas token + # sig= - match the literal string 'sig=' + # [\w%-/]+ - match any word character, '-', '%', or '/' one or more times. This is the signature which needs to be redacted + SAS_TOKEN = (r'([?&;])sig=[\w%-/]+', r'\1sig=_REDACTED_SAS_TOKEN_SIG_', 1, 'SAS token') + # key= - match the literal string 'key=', could be accountkey, primarykey, secondarykey, etc. + # [\w%+/=-]+ - match any word character, '%', '+', '/', '=', or '-' one or more times. + KEY = (r'key=[\w%+/=-]+', r'key=_REDACTED_KEY_', 1, 'Several types of keys/secrets are passed with a query parameter "key"') + # (?:eyJ0eXAi|eyJhbGci) - match the literal string 'eyJ0eXAi' or 'eyJhbGci' as group 1, which is the prefix of JWT token + # [\w\-.~+/%]* - match any word character, '-', '.', '~', '+', '/', '%', or '*' zero or more times. + JWT_TOKEN = (r'(?:eyJ0eXAi|eyJhbGci)[\w\-.~+/%]*', '_REDACTED_JWT_TOKEN_', 0, 'JWT token') + # (bearer |bearer%20) - match the literal string 'bearer ' or 'bearer%20' + # [\w\-.~+/]{100,} - match any word character, '-', '.', '~', '+', or '/' one hundred or more times. + BEARER_TOKEN = (r'(bearer |bearer%20)[\w\-.~+/]{100,}', r'\1_REDACTED_BEARER_TOKEN_', 0, 'Bearer token') + # (ssh-rsa ) - match the literal string 'ssh-rsa ' as group 1, which is the prefix of ssh key + # AAAA[\w\-.~+/]{100,} - match 'AAAA' followed by any word character, '-', '.', '~', '+', or '/' one hundred or more times. + SSH_KEY = (r'(ssh-rsa )AAAA[\w\-.~+/]{100,}', r'\1_REDACTED_SSH_KEY_', 1, 'SSH key') + # [\w.%#+-] - match any word character, '.', '%', '#', '+', or '-' one or more times. + # (%40|@) - match character '@' or '%40' as group 1 + # ([a-z0-9.-]*\.[a-z]{2,}) - match any word character, '.', or '-' zero or more times, followed by a '.' and two or more word characters. + EMAIL_ADDRESS = (r'[\w.%#+-]+(%40|@)([a-z0-9.-]*\.[a-z]{2,})', r'_REDACTED_EMAIL_\1\2', 99, 'Email address') + # [0-9a-f]{8} - match any character in the range '0' to '9' or 'a' to 'f' exactly eight times. + # -? - match character '-' zero or one time. + GUID = (r'([0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})', '_REDACTED_GUID_', 999, 'GUID') + # below regexes are shared by ADO cred scan, see definition: + # https://github.com/microsoft/azure-pipelines-agent/blob/master/src/Microsoft.VisualStudio.Services.Agent/AdditionalMaskingRegexes.CredScan.cs + AAD_CLIENT_APP = (r'[0-9A-Za-z-_~.]{3}7Q~[0-9A-Za-z-_~.]{31}\b|\b[0-9A-Za-z-_~.]{3}8Q~[0-9A-Za-z-_~.]{34}', '_REDACTED_AAD_CLIENT_APP_', 99, 'AAD client app') + SYMMETRIC_KEY_512 = (r'[0-9A-Za-z+/]{76}(APIM|ACDb|\+(ABa|AMC|ASt))[0-9A-Za-z+/]{5}[AQgw]==', '_REDACTED_SYMMETRIC_KEY_', 1, '512-bit symmetric key') + SYMMETRIC_KEY_256 = (r'[0-9A-Za-z+/]{33}(AIoT|\+(ASb|AEh|ARm))[A-P][0-9A-Za-z+/]{5}=', '_REDACTED_SYMMETRIC_KEY_', 1, '256-bit symmetric key') + AZURE_FUNCTION_KEY = (r'[0-9A-Za-z_\-]{44}AzFu[0-9A-Za-z\-_]{5}[AQgw]==', '_REDACTED_AZURE_FUNCTION_KEY_', 1, 'Azure function key') + AZURE_SEARCH_KEY = (r'[0-9A-Za-z]{42}AzSe[A-D][0-9A-Za-z]{5}', '_REDACTED_AZURE_SEARCH_KEY_', 1, 'Azure search key') + AZURE_CONTAINER_REGISTRY_KEY = (r'[0-9A-Za-z+/]{42}\+ACR[A-D][0-9A-Za-z+/]{5}', '_REDACTED_AZURE_CONTAINER_REGISTRY_KEY_', 1, 'Azure container registry key') + AZURE_CACHE_FOR_REDIS_KEY = (r'[0-9A-Za-z]{33}AzCa[A-P][0-9A-Za-z]{5}=', '_REDACTED_AZURE_CACHE_FOR_REDIS_KEY_', 1, 'Azure cache for redis key') + + def __init__(self, regex, replacement, level=0, description=''): + self.regex = regex + self.replacement = replacement + self.level = level + self.description = description + + +def is_containing_credential(content, is_file=False, max_level=9): + """Check if the given content contains credential or not. + + :param content: The content or the file path. + :type content: Any. + :param is_file: flag to clarify the content is file path or not. + :type is_file: bool. + :param max_level: the max level of credential to check. + :type max_level: int. + :returns: bool. + """ + if is_file: + with open(content, 'r') as f: + content = f.read() + elif not isinstance(content, str): + try: + content = json.dumps(content) + except TypeError: + content = str(content) + except ValueError: + raise ValueError('The content is not string or json object.') + return any(re.search(cred_type.regex, content, flags=re.IGNORECASE | re.MULTILINE) and cred_type.level <= max_level + for cred_type in CredentialType) + + +def distinguish_credential(content, is_file=False, max_level=9): + """Distinguish which property contains credential from the given content. + + :param content: The content(can be string or json object) or the file path. + :type content: Any. + :param is_file: flag to clarify the content is file path or not. + :type is_file: bool. + :param max_level: the max level of credential to check. + :type max_level: int. + :returns: bool, set. + """ + containing_credential = False + secret_property_names = set() + if is_file: + with open(content, 'r') as f: + content = json.load(f) + + if isinstance(content, list): + for item in content: + _containing_credential, _secret_property_names = distinguish_credential(item, max_level=max_level) + containing_credential = containing_credential or _containing_credential + secret_property_names.update(_secret_property_names) + return containing_credential, secret_property_names + + if isinstance(content, dict): + for key, value in content.items(): + _containing_credential, _secret_property_names = distinguish_credential(value, max_level=max_level) + containing_credential = containing_credential or _containing_credential + secret_property_names.update(_secret_property_names) + if _containing_credential: + secret_property_names.add(key) + return containing_credential, secret_property_names + + if is_containing_credential(content, max_level=max_level): + containing_credential = True + return containing_credential, secret_property_names + + +def redact_credential(content, is_file=False): + """Redact credential for the given content. + + :param content: The content(can be string or json object) or the file path. + :type content: Any. + :param is_file: flag to clarify the content is file path or not. + :type is_file: bool. + :returns: processed content. + """ + if is_file: + fp = content + with open(fp, 'r') as f: + content = f.read() + content = redact_credential_for_string(content) + with open(fp, 'w') as f: + f.write(content) + return fp + + if isinstance(content, str): + return redact_credential_for_string(content) + + try: + content = json.dumps(content) + content = redact_credential_for_string(content) + return json.loads(content) + except ValueError: + raise ValueError('The content is not string or json object.') + + +def redact_credential_for_string(string): + for cred_type in CredentialType: + string = re.sub(cred_type.regex, cred_type.replacement, string, flags=re.IGNORECASE | re.MULTILINE) + return string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/profiles/_shared.py new/azure-cli-core-2.57.0/azure/cli/core/profiles/_shared.py --- old/azure-cli-core-2.56.0/azure/cli/core/profiles/_shared.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/profiles/_shared.py 2024-01-31 06:29:21.000000000 +0100 @@ -261,7 +261,7 @@ ResourceType.MGMT_ARO: '2023-09-04', ResourceType.MGMT_DATABOXEDGE: '2021-02-01-preview', ResourceType.MGMT_CUSTOMLOCATION: '2021-03-15-preview', - ResourceType.MGMT_CONTAINERSERVICE: SDKProfile('2023-10-01'), + ResourceType.MGMT_CONTAINERSERVICE: SDKProfile('2023-11-01'), ResourceType.MGMT_APPCONTAINERS: '2022-10-01', }, '2020-09-01-hybrid': { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure/cli/core/telemetry.py new/azure-cli-core-2.57.0/azure/cli/core/telemetry.py --- old/azure-cli-core-2.56.0/azure/cli/core/telemetry.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure/cli/core/telemetry.py 2024-01-31 06:29:21.000000000 +0100 @@ -72,6 +72,7 @@ self.poll_end_time = None self.allow_broker = None self.msal_telemetry = None + self.secrets_detected = None def add_event(self, name, properties): for key in self.instrumentation_key: @@ -219,6 +220,8 @@ set_custom_properties(result, 'RegionIdentified', self.region_identified) set_custom_properties(result, 'AllowBroker', str(self.allow_broker)) set_custom_properties(result, 'MsalTelemetry', self.msal_telemetry) + set_custom_properties(result, 'SecretsWarning', _get_secrets_warning_config()) + set_custom_properties(result, 'SecretsDetected', self.secrets_detected) return result @@ -468,6 +471,11 @@ @decorators.suppress_all_exceptions() +def set_secrets_detected(secrets_detected): + _session.secrets_detected = secrets_detected + + [email protected]_all_exceptions() def add_dedicated_instrumentation_key(dedicated_instrumentation_key): if not dedicated_instrumentation_key: return @@ -519,6 +527,14 @@ return _session.application.config [email protected]_all_exceptions() +def _get_secrets_warning_config(): + show_secrets_warning = _get_config().getboolean('clients', 'show_secrets_warning', fallback=None) + if show_secrets_warning is None: + return None + return 'on' if show_secrets_warning else 'off' + + # internal utility functions @decorators.suppress_all_exceptions(fallback_return=None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure_cli_core.egg-info/PKG-INFO new/azure-cli-core-2.57.0/azure_cli_core.egg-info/PKG-INFO --- old/azure-cli-core-2.56.0/azure_cli_core.egg-info/PKG-INFO 2024-01-08 10:08:25.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure_cli_core.egg-info/PKG-INFO 2024-01-31 06:29:52.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.56.0 +Version: 2.57.0 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation @@ -27,7 +27,7 @@ Requires-Dist: jmespath Requires-Dist: knack~=0.11.0 Requires-Dist: msal-extensions~=1.0.0 -Requires-Dist: msal[broker]==1.24.0b2 +Requires-Dist: msal[broker]==1.26.0 Requires-Dist: msrestazure~=0.6.4 Requires-Dist: packaging>=20.9 Requires-Dist: paramiko<4.0.0,>=2.0.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure_cli_core.egg-info/SOURCES.txt new/azure-cli-core-2.57.0/azure_cli_core.egg-info/SOURCES.txt --- old/azure-cli-core-2.56.0/azure_cli_core.egg-info/SOURCES.txt 2024-01-08 10:08:25.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure_cli_core.egg-info/SOURCES.txt 2024-01-31 06:29:52.000000000 +0100 @@ -21,6 +21,7 @@ azure/cli/core/azlogging.py azure/cli/core/cloud.py azure/cli/core/command_recommender.py +azure/cli/core/credential_helper.py azure/cli/core/decorators.py azure/cli/core/file_util.py azure/cli/core/intercept_survey.py @@ -72,6 +73,7 @@ azure/cli/core/commands/events.py azure/cli/core/commands/parameters.py azure/cli/core/commands/progress.py +azure/cli/core/commands/sensitive.py azure/cli/core/commands/template_create.py azure/cli/core/commands/transform.py azure/cli/core/commands/validators.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/azure_cli_core.egg-info/requires.txt new/azure-cli-core-2.57.0/azure_cli_core.egg-info/requires.txt --- old/azure-cli-core-2.56.0/azure_cli_core.egg-info/requires.txt 2024-01-08 10:08:25.000000000 +0100 +++ new/azure-cli-core-2.57.0/azure_cli_core.egg-info/requires.txt 2024-01-31 06:29:52.000000000 +0100 @@ -6,7 +6,7 @@ jmespath knack~=0.11.0 msal-extensions~=1.0.0 -msal[broker]==1.24.0b2 +msal[broker]==1.26.0 msrestazure~=0.6.4 packaging>=20.9 paramiko<4.0.0,>=2.0.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.56.0/setup.py new/azure-cli-core-2.57.0/setup.py --- old/azure-cli-core-2.56.0/setup.py 2024-01-08 10:08:10.000000000 +0100 +++ new/azure-cli-core-2.57.0/setup.py 2024-01-31 06:29:21.000000000 +0100 @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "2.56.0" +VERSION = "2.57.0" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions. @@ -53,7 +53,7 @@ 'jmespath', 'knack~=0.11.0', 'msal-extensions~=1.0.0', - 'msal[broker]==1.24.0b2', + 'msal[broker]==1.26.0', 'msrestazure~=0.6.4', 'packaging>=20.9', 'paramiko>=2.0.8,<4.0.0',
