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-01-19 23:00:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-core (Old) and /work/SRC/openSUSE:Factory/.azure-cli-core.new.16006 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-core" Fri Jan 19 23:00:21 2024 rev:61 rq:1139799 version:2.56.0 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-core/azure-cli-core.changes 2024-01-08 23:46:25.948864740 +0100 +++ /work/SRC/openSUSE:Factory/.azure-cli-core.new.16006/azure-cli-core.changes 2024-01-19 23:00:24.234096270 +0100 @@ -1,0 +2,8 @@ +Thu Jan 18 14:21:30 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- New upstream release + + Version 2.56.0 + + For detailed information about changes see the + HISTORY.rst file provided with this package + +------------------------------------------------------------------- Old: ---- azure-cli-core-2.55.0.tar.gz New: ---- azure-cli-core-2.56.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-core.spec ++++++ --- /var/tmp/diff_new_pack.K2NMqJ/_old 2024-01-19 23:00:26.874192778 +0100 +++ /var/tmp/diff_new_pack.K2NMqJ/_new 2024-01-19 23:00:26.874192778 +0100 @@ -17,7 +17,7 @@ Name: azure-cli-core -Version: 2.55.0 +Version: 2.56.0 Release: 0 Summary: Microsoft Azure CLI Core Module License: MIT ++++++ azure-cli-core-2.55.0.tar.gz -> azure-cli-core-2.56.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/HISTORY.rst new/azure-cli-core-2.56.0/HISTORY.rst --- old/azure-cli-core-2.55.0/HISTORY.rst 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/HISTORY.rst 2024-01-08 10:08:10.000000000 +0100 @@ -3,6 +3,10 @@ Release History =============== +2.56.0 +++++++ +* Minor fixes + 2.55.0 ++++++ * Minor fixes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/PKG-INFO new/azure-cli-core-2.56.0/PKG-INFO --- old/azure-cli-core-2.55.0/PKG-INFO 2023-11-29 04:41:38.031669900 +0100 +++ new/azure-cli-core-2.56.0/PKG-INFO 2024-01-08 10:08:25.818453800 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.55.0 +Version: 2.56.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.55.0/azure/cli/core/__init__.py new/azure-cli-core-2.56.0/azure/cli/core/__init__.py --- old/azure-cli-core-2.55.0/azure/cli/core/__init__.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/__init__.py 2024-01-08 10:08:10.000000000 +0100 @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long -__version__ = "2.55.0" +__version__ = "2.56.0" import os import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure/cli/core/aaz/_client.py new/azure-cli-core-2.56.0/azure/cli/core/aaz/_client.py --- old/azure-cli-core-2.55.0/azure/cli/core/aaz/_client.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/aaz/_client.py 2024-01-08 10:08:10.000000000 +0100 @@ -2,14 +2,18 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- - +from knack.log import get_logger from azure.core import PipelineClient from azure.core.configuration import Configuration from azure.core.polling.base_polling import LocationPolling, StatusCheckPolling from abc import abstractmethod from ._poller import AAZNoPolling, AAZBasePolling -from azure.cli.core.cloud import CloudNameEnum as _CloudNameEnum +from azure.cli.core.cloud import (CloudEndpointNotSetException, CloudSuffixNotSetException, + CloudNameEnum as _CloudNameEnum) + + +logger = get_logger(__name__) registered_clients = {} CloudNameEnum = _CloudNameEnum # redefine CloudNameEnum in aaz to decouple with cloud for aaz generated commands. @@ -66,8 +70,11 @@ """Base Client""" def __init__(self, ctx, credential, **kwargs): + base_url = self._build_base_url(ctx, **kwargs) + if not base_url: + raise CloudEndpointNotSetException() super().__init__( - base_url=self._build_base_url(ctx, **kwargs), + base_url=base_url, config=self._build_configuration(ctx, credential, **kwargs), per_call_policies=self._build_per_call_policies(ctx, **kwargs) ) @@ -122,6 +129,81 @@ ) return polling + @classmethod + def get_cloud_endpoint(cls, ctx, arm_idx): + from azure.cli.core.cloud import CloudEndpoints + endpoints = None + # retrieve by indexes mapping + for property_name, value in CloudEndpoints.ARM_METADATA_INDEX.items(): + if value == arm_idx: + try: + endpoints = getattr(ctx.cli_ctx.cloud.endpoints, property_name) + except CloudEndpointNotSetException: + break + + # retrieve from arm response + if not endpoints: + endpoints = cls._retrieve_value_in_arm_cloud_metadata(ctx, arm_idx) + return endpoints + + @classmethod + def get_cloud_suffix(cls, ctx, arm_idx): + from azure.cli.core.cloud import CloudSuffixes + # retrieve by indexes mapping + suffixes = None + for property_name, value in CloudSuffixes.ARM_METADATA_INDEX.items(): + if value == arm_idx: + try: + suffixes = getattr(ctx.cli_ctx.cloud.suffixes, property_name) + except CloudSuffixNotSetException: + break + + if not suffixes: + # retrieve from arm response + suffixes = cls._retrieve_value_in_arm_cloud_metadata(ctx, arm_idx) + if suffixes and not suffixes.startswith('.'): + # always add '.' when suffixes is not None + suffixes = '.' + suffixes + return suffixes + + @staticmethod + def _retrieve_value_in_arm_cloud_metadata(ctx, arm_idx): + from azure.cli.core.cloud import retrieve_arm_cloud_metadata, get_active_cloud_name + from ._utils import AAZShortHandSyntaxParser, AAZInvalidShorthandSyntaxError + + cloud_name = get_active_cloud_name(ctx.cli_ctx) + arm_cloud = None + try: + arm_cloud_metadata = retrieve_arm_cloud_metadata() + for cloud in arm_cloud_metadata: + if cloud.get('name', None) == cloud_name: + arm_cloud = cloud + break + if not arm_cloud: + return None + except Exception: # pylint: disable=broad-except + return None + + try: + value = arm_cloud + for key in AAZShortHandSyntaxParser.parse_partial_value_key(arm_idx): + value = value[key] + except AAZInvalidShorthandSyntaxError as err: + logger.warning('Invalid metadata index: %s', err) + raise err + except LookupError: + logger.debug( + "Failed to retrieve '%s' property in cloud metadata from the url specified by ARM_CLOUD_METADATA_URL", + arm_idx + ) + return None + if not isinstance(value, str): + logger.debug( + "Failed to retrieve '%s' property in cloud metadata from the url specified by ARM_CLOUD_METADATA_URL: " + "property is not a string", arm_idx) + return None + return value + @register_client("MgmtClient") class AAZMgmtClient(AAZBaseClient): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure/cli/core/cloud.py new/azure-cli-core-2.56.0/azure/cli/core/cloud.py --- old/azure-cli-core-2.55.0/azure/cli/core/cloud.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/cloud.py 2024-01-08 10:08:10.000000000 +0100 @@ -59,49 +59,73 @@ class CloudEndpoints: # pylint: disable=too-few-public-methods,too-many-instance-attributes + ARM_METADATA_INDEX = { + "active_directory": "authentication.loginEndpoint", + "active_directory_data_lake_resource_id": "activeDirectoryDataLake", + "active_directory_graph_resource_id": "graphAudience", + "active_directory_resource_id": "authentication.audiences[0]", + "app_insights_resource_id": "appInsightsResourceId", + "app_insights_telemetry_channel_resource_id": "appInsightsTelemetryChannelResourceId", + "attestation_resource_id": "attestationResourceId", + "azmirror_storage_account_resource_id": "azmirrorStorageAccountResourceId", + "batch_resource_id": "batch", + "gallery": "gallery", + "log_analytics_resource_id": "logAnalyticsResourceId", + "management": "authentication.audiences[0]", + "media_resource_id": "media", + "microsoft_graph_resource_id": "microsoftGraphResourceId", + "ossrdbms_resource_id": "ossrdbmsResourceId", + "portal": "portal", + "resource_manager": "resourceManager", + "sql_management": "sqlManagement", + "synapse_analytics_resource_id": "synapseAnalyticsResourceId", + "vm_image_alias_doc": "vmImageAliasDoc", + } # Please keep the endpoints in alphabetical order + def __init__(self, # pylint: disable=unused-argument - management=None, - resource_manager=None, - sql_management=None, - batch_resource_id=None, - gallery=None, active_directory=None, - active_directory_resource_id=None, - active_directory_graph_resource_id=None, - microsoft_graph_resource_id=None, active_directory_data_lake_resource_id=None, - vm_image_alias_doc=None, - media_resource_id=None, - ossrdbms_resource_id=None, - log_analytics_resource_id=None, + active_directory_graph_resource_id=None, + active_directory_resource_id=None, app_insights_resource_id=None, app_insights_telemetry_channel_resource_id=None, - synapse_analytics_resource_id=None, attestation_resource_id=None, - portal=None, azmirror_storage_account_resource_id=None, + batch_resource_id=None, + gallery=None, + log_analytics_resource_id=None, + management=None, + media_resource_id=None, + microsoft_graph_resource_id=None, + ossrdbms_resource_id=None, + portal=None, + resource_manager=None, + sql_management=None, + synapse_analytics_resource_id=None, + vm_image_alias_doc=None, **kwargs): # To support init with __dict__ for deserialization # Attribute names are significant. They are used when storing/retrieving clouds from config - self.management = management - self.resource_manager = resource_manager - self.sql_management = sql_management - self.batch_resource_id = batch_resource_id - self.gallery = gallery self.active_directory = active_directory - self.active_directory_resource_id = active_directory_resource_id - self.active_directory_graph_resource_id = active_directory_graph_resource_id - self.microsoft_graph_resource_id = microsoft_graph_resource_id self.active_directory_data_lake_resource_id = active_directory_data_lake_resource_id - self.vm_image_alias_doc = vm_image_alias_doc - self.media_resource_id = media_resource_id - self.ossrdbms_resource_id = ossrdbms_resource_id - self.log_analytics_resource_id = log_analytics_resource_id + self.active_directory_graph_resource_id = active_directory_graph_resource_id + self.active_directory_resource_id = active_directory_resource_id self.app_insights_resource_id = app_insights_resource_id self.app_insights_telemetry_channel_resource_id = app_insights_telemetry_channel_resource_id - self.synapse_analytics_resource_id = synapse_analytics_resource_id self.attestation_resource_id = attestation_resource_id - self.portal = portal self.azmirror_storage_account_resource_id = azmirror_storage_account_resource_id + self.batch_resource_id = batch_resource_id + self.gallery = gallery + self.log_analytics_resource_id = log_analytics_resource_id + self.management = management + self.media_resource_id = media_resource_id + self.microsoft_graph_resource_id = microsoft_graph_resource_id + self.ossrdbms_resource_id = ossrdbms_resource_id + self.portal = portal + self.resource_manager = resource_manager + self.sql_management = sql_management + self.synapse_analytics_resource_id = synapse_analytics_resource_id + self.vm_image_alias_doc = vm_image_alias_doc + # Please keep the endpoints in alphabetical order def has_endpoint_set(self, endpoint_name): try: @@ -125,35 +149,52 @@ class CloudSuffixes: # pylint: disable=too-few-public-methods,too-many-instance-attributes + ARM_METADATA_INDEX = { + "acr_login_server_endpoint": "suffixes.acrLoginServer", + "attestation_endpoint": "suffixes.attestationEndpoint", + "azure_datalake_analytics_catalog_and_job_endpoint": "suffixes.azureDataLakeAnalyticsCatalogAndJob", + "azure_datalake_store_file_system_endpoint": "suffixes.azureDataLakeStoreFileSystem", + "keyvault_dns": "suffixes.keyVaultDns", + "mariadb_server_endpoint": "suffixes.mariadbServerEndpoint", + "mhsm_dns": "suffixes.mhsmDns", + "mysql_server_endpoint": "suffixes.mysqlServerEndpoint", + "postgresql_server_endpoint": "suffixes.postgresqlServerEndpoint", + "sql_server_hostname": "suffixes.sqlServerHostname", + "storage_endpoint": "suffixes.storage", + "storage_sync_endpoint": "suffixes.storageSyncEndpointSuffix", + "synapse_analytics_endpoint": "suffixes.synapseAnalytics" + } # Please keep the suffixes in alphabetical order + def __init__(self, # pylint: disable=unused-argument - storage_endpoint=None, - storage_sync_endpoint=None, + acr_login_server_endpoint=None, + attestation_endpoint=None, + azure_datalake_analytics_catalog_and_job_endpoint=None, + azure_datalake_store_file_system_endpoint=None, keyvault_dns=None, + mariadb_server_endpoint=None, mhsm_dns=None, - sql_server_hostname=None, - azure_datalake_store_file_system_endpoint=None, - azure_datalake_analytics_catalog_and_job_endpoint=None, - acr_login_server_endpoint=None, mysql_server_endpoint=None, postgresql_server_endpoint=None, - mariadb_server_endpoint=None, + sql_server_hostname=None, + storage_endpoint=None, + storage_sync_endpoint=None, synapse_analytics_endpoint=None, - attestation_endpoint=None, **kwargs): # To support init with __dict__ for deserialization # Attribute names are significant. They are used when storing/retrieving clouds from config - self.storage_endpoint = storage_endpoint - self.storage_sync_endpoint = storage_sync_endpoint + self.acr_login_server_endpoint = acr_login_server_endpoint + self.attestation_endpoint = attestation_endpoint + self.azure_datalake_analytics_catalog_and_job_endpoint = azure_datalake_analytics_catalog_and_job_endpoint + self.azure_datalake_store_file_system_endpoint = azure_datalake_store_file_system_endpoint self.keyvault_dns = keyvault_dns + self.mariadb_server_endpoint = mariadb_server_endpoint self.mhsm_dns = mhsm_dns - self.sql_server_hostname = sql_server_hostname self.mysql_server_endpoint = mysql_server_endpoint self.postgresql_server_endpoint = postgresql_server_endpoint - self.mariadb_server_endpoint = mariadb_server_endpoint - self.azure_datalake_store_file_system_endpoint = azure_datalake_store_file_system_endpoint - self.azure_datalake_analytics_catalog_and_job_endpoint = azure_datalake_analytics_catalog_and_job_endpoint - self.acr_login_server_endpoint = acr_login_server_endpoint + self.sql_server_hostname = sql_server_hostname + self.storage_endpoint = storage_endpoint + self.storage_sync_endpoint = storage_sync_endpoint self.synapse_analytics_endpoint = synapse_analytics_endpoint - self.attestation_endpoint = attestation_endpoint + # Please keep the suffixes in alphabetical order def __getattribute__(self, name): val = object.__getattribute__(self, name) @@ -223,40 +264,54 @@ return Cloud( arm_dict['name'], endpoints=CloudEndpoints( # please add fallback_value if the endpoint is not added to https://management.azure.com/metadata/endpoints?api-version=2019-05-01 yet - management=arm_dict['authentication']['audiences'][0], - resource_manager=get_endpoint('resourceManager'), - sql_management=get_endpoint('sqlManagement'), - batch_resource_id=get_endpoint('batch'), - gallery=get_endpoint('gallery'), active_directory=arm_dict['authentication']['loginEndpoint'], - active_directory_resource_id=arm_dict['authentication']['audiences'][0], + active_directory_data_lake_resource_id=get_endpoint('activeDirectoryDataLake'), active_directory_graph_resource_id=get_endpoint('graphAudience'), - microsoft_graph_resource_id=get_endpoint('microsoftGraphResourceId', fallback_value=get_endpoint_fallback_value('microsoft_graph_resource_id')), # change once microsoft_graph_resource_id is fixed in ARM - vm_image_alias_doc=get_endpoint('vmImageAliasDoc'), + active_directory_resource_id=arm_dict['authentication']['audiences'][0], + app_insights_resource_id=get_endpoint('appInsightsResourceId', + fallback_value=get_endpoint_fallback_value('app_insights_resource_id')), + app_insights_telemetry_channel_resource_id=get_endpoint('appInsightsTelemetryChannelResourceId', + fallback_value=get_endpoint_fallback_value('app_insights_telemetry_channel_resource_id')), + attestation_resource_id=get_endpoint('attestationResourceId', + fallback_value=get_endpoint_fallback_value('attestation_resource_id')), + azmirror_storage_account_resource_id=get_endpoint('azmirrorStorageAccountResourceId'), + batch_resource_id=get_endpoint('batch'), + gallery=get_endpoint('gallery'), + log_analytics_resource_id=get_endpoint('logAnalyticsResourceId', + fallback_value=get_endpoint_fallback_value('log_analytics_resource_id')), + management=arm_dict['authentication']['audiences'][0], media_resource_id=get_endpoint('media'), - ossrdbms_resource_id=get_endpoint('ossrdbmsResourceId', fallback_value=get_endpoint_fallback_value('ossrdbms_resource_id')), # change once ossrdbms_resource_id is available via ARM - active_directory_data_lake_resource_id=get_endpoint('activeDirectoryDataLake'), - app_insights_resource_id=get_endpoint('appInsightsResourceId', fallback_value=get_endpoint_fallback_value('app_insights_resource_id')), - log_analytics_resource_id=get_endpoint('logAnalyticsResourceId', fallback_value=get_endpoint_fallback_value('log_analytics_resource_id')), - synapse_analytics_resource_id=get_endpoint('synapseAnalyticsResourceId', fallback_value=get_endpoint_fallback_value('synapse_analytics_resource_id')), - app_insights_telemetry_channel_resource_id=get_endpoint('appInsightsTelemetryChannelResourceId', fallback_value=get_endpoint_fallback_value('app_insights_telemetry_channel_resource_id')), - attestation_resource_id=get_endpoint('attestationResourceId', fallback_value=get_endpoint_fallback_value('attestation_resource_id')), + microsoft_graph_resource_id=get_endpoint('microsoftGraphResourceId', + fallback_value=get_endpoint_fallback_value('microsoft_graph_resource_id')), # change once microsoft_graph_resource_id is fixed in ARM + ossrdbms_resource_id=get_endpoint('ossrdbmsResourceId', + fallback_value=get_endpoint_fallback_value('ossrdbms_resource_id')), # change once ossrdbms_resource_id is available via ARM portal=get_endpoint('portal'), - azmirror_storage_account_resource_id=get_endpoint('azmirrorStorageAccountResourceId')), + resource_manager=get_endpoint('resourceManager'), + sql_management=get_endpoint('sqlManagement'), + synapse_analytics_resource_id=get_endpoint('synapseAnalyticsResourceId', + fallback_value=get_endpoint_fallback_value('synapse_analytics_resource_id')), + vm_image_alias_doc=get_endpoint('vmImageAliasDoc'), + ), # Please keep the endpoints in alphabetical order suffixes=CloudSuffixes( - storage_endpoint=get_suffix('storage'), - storage_sync_endpoint=get_suffix('storageSyncEndpointSuffix', fallback_value=get_suffix_fallback_value('storage_sync_endpoint')), + acr_login_server_endpoint=get_suffix('acrLoginServer', add_dot=True), + attestation_endpoint=get_suffix('attestationEndpoint', add_dot=True, + fallback_value=get_suffix_fallback_value('attestation_endpoint')), + azure_datalake_analytics_catalog_and_job_endpoint=get_suffix('azureDataLakeAnalyticsCatalogAndJob'), + azure_datalake_store_file_system_endpoint=get_suffix('azureDataLakeStoreFileSystem'), keyvault_dns=get_suffix('keyVaultDns', add_dot=True), + mariadb_server_endpoint=get_suffix('mariadbServerEndpoint', add_dot=True, + fallback_value=get_db_server_endpoint('.mariadb')), mhsm_dns=get_suffix('mhsmDns', add_dot=True, fallback_value=get_suffix_fallback_value('mhsm_dns')), + mysql_server_endpoint=get_suffix('mysqlServerEndpoint', add_dot=True, + fallback_value=get_db_server_endpoint('.mysql')), + postgresql_server_endpoint=get_suffix('postgresqlServerEndpoint', add_dot=True, + fallback_value=get_db_server_endpoint('.postgres')), sql_server_hostname=sql_server_hostname, - mysql_server_endpoint=get_suffix('mysqlServerEndpoint', add_dot=True, fallback_value=get_db_server_endpoint('.mysql')), - postgresql_server_endpoint=get_suffix('postgresqlServerEndpoint', add_dot=True, fallback_value=get_db_server_endpoint('.postgres')), - mariadb_server_endpoint=get_suffix('mariadbServerEndpoint', add_dot=True, fallback_value=get_db_server_endpoint('.mariadb')), - azure_datalake_store_file_system_endpoint=get_suffix('azureDataLakeStoreFileSystem'), - azure_datalake_analytics_catalog_and_job_endpoint=get_suffix('azureDataLakeAnalyticsCatalogAndJob'), + storage_endpoint=get_suffix('storage'), + storage_sync_endpoint=get_suffix('storageSyncEndpointSuffix', fallback_value=get_suffix_fallback_value('storage_sync_endpoint')), synapse_analytics_endpoint=get_suffix('synapseAnalytics', add_dot=True, fallback_value=get_suffix_fallback_value('synapse_analytics_endpoint')), - acr_login_server_endpoint=get_suffix('acrLoginServer', add_dot=True), - attestation_endpoint=get_suffix('attestationEndpoint', add_dot=True, fallback_value=get_suffix_fallback_value('attestation_endpoint')))) + ) # Please keep the suffixes in alphabetical order + ) class Cloud: # pylint: disable=too-few-public-methods @@ -429,6 +484,12 @@ HARD_CODED_CLOUD_LIST = [AZURE_PUBLIC_CLOUD, AZURE_CHINA_CLOUD, AZURE_US_GOV_CLOUD, AZURE_GERMAN_CLOUD] +def retrieve_arm_cloud_metadata(): + """ Retrieve Cloud metadata from ARM endpoint api defined in ARM_CLOUD_METADATA_URL""" + if 'ARM_CLOUD_METADATA_URL' in os.environ: + return json.loads(urlretrieve(os.getenv('ARM_CLOUD_METADATA_URL'))) + + def get_known_clouds(refresh=False): if 'ARM_CLOUD_METADATA_URL' in os.environ: from azure.cli.core._session import CLOUD_ENDPOINTS @@ -449,7 +510,7 @@ if not CLOUD_ENDPOINTS['clouds']: try: - arm_cloud_dict = json.loads(urlretrieve(os.getenv('ARM_CLOUD_METADATA_URL'))) + arm_cloud_dict = retrieve_arm_cloud_metadata() cli_cloud_dict = _convert_arm_to_cli(arm_cloud_dict) if 'AzureCloud' in cli_cloud_dict: cli_cloud_dict['AzureCloud'].endpoints.active_directory = 'https://login.microsoftonline.com' # change once active_directory is fixed in ARM for the public cloud diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure/cli/core/extension/__init__.py new/azure-cli-core-2.56.0/azure/cli/core/extension/__init__.py --- old/azure-cli-core-2.55.0/azure/cli/core/extension/__init__.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/extension/__init__.py 2024-01-08 10:08:10.000000000 +0100 @@ -101,7 +101,7 @@ """ try: if not isinstance(self._preview, bool): - self._preview = bool(self.metadata.get(EXT_METADATA_ISPREVIEW)) + self._preview = is_preview_from_extension_meta(self.metadata) except Exception: # pylint: disable=broad-except logger.debug("Unable to get extension preview status: %s", traceback.format_exc()) return self._preview @@ -109,15 +109,9 @@ @property def experimental(self): """ - Lazy load experimental status. - Returns the experimental status of the extension. + In extension semantic versioning, experimental = preview, experimental deprecated """ - try: - if not isinstance(self._experimental, bool): - self._experimental = bool(self.metadata.get(EXT_METADATA_ISEXPERIMENTAL)) - except Exception: # pylint: disable=broad-except - logger.debug("Unable to get extension experimental status: %s", traceback.format_exc()) - return self._experimental + return False def get_version(self): raise NotImplementedError() @@ -359,3 +353,30 @@ Returns the extension names of extensions installed in the extensions directory. """ return [ext.name for ext in get_extensions(ext_type=ext_type)] + + +def is_preview_from_extension_meta(extension_meta): + return (bool(extension_meta.get(EXT_METADATA_ISPREVIEW, False)) or + bool(extension_meta.get(EXT_METADATA_ISEXPERIMENTAL, False)) or + is_preview_from_semantic_version(extension_meta.get('version'))) + + +def is_preview_from_semantic_version(version): + """ + pre = [a, b] -> preview + >>> print(parse("1.2.3").pre) + None + >>> parse("1.2.3a1").pre + ('a', 1) + >>> parse("1.2.3b1").pre + ('b', 1) + """ + from packaging.version import parse + parsed_version = parse(version) + return bool(parsed_version.pre and parsed_version.pre[0] in ["a", "b"]) + + +def is_stable_from_metadata(item): + return not (item["metadata"].get(EXT_METADATA_ISPREVIEW, False) or + item["metadata"].get(EXT_METADATA_ISEXPERIMENTAL, False) or + is_preview_from_semantic_version(item["metadata"]['version'])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure/cli/core/extension/_resolve.py new/azure-cli-core-2.56.0/azure/cli/core/extension/_resolve.py --- old/azure-cli-core-2.55.0/azure/cli/core/extension/_resolve.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/extension/_resolve.py 2024-01-08 10:08:10.000000000 +0100 @@ -5,7 +5,7 @@ from packaging.version import parse from typing import Callable, List, NamedTuple, Union -from azure.cli.core.extension import ext_compat_with_cli, WHEEL_INFO_RE +from azure.cli.core.extension import ext_compat_with_cli, WHEEL_INFO_RE, is_stable_from_metadata from azure.cli.core.extension._index import get_index_extensions from knack.log import get_logger @@ -77,7 +77,8 @@ return e.args[0] -def resolve_from_index(extension_name, cur_version=None, index_url=None, target_version=None, cli_ctx=None): +def resolve_from_index(extension_name, cur_version=None, index_url=None, target_version=None, cli_ctx=None, + allow_preview=None): """Gets the download Url and digest for the matching extension Args: @@ -86,6 +87,7 @@ index_url (str, optional): Defaults to None. target_version (str, optional): Version of extension to install. Defaults to latest version. cli_ctx (, optional): CLI Context. Defaults to None. + allow_preview(bool, optional): Flag to allow installing preview extensions. Default to None. Raises: NoExtensionCandidatesError when an extension: @@ -113,6 +115,14 @@ ) ] + if not allow_preview: + candidate_filters += [ + _ExtensionFilter( + filter=list_filter(is_stable_from_metadata), + on_empty_results_message=f"No suitable stable version of '{extension_name}' to install. " + f"Add `--allow-preview` to try preview versions" + )] + if target_version: candidate_filters += [ _ExtensionFilter( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure/cli/core/extension/operations.py new/azure-cli-core-2.56.0/azure/cli/core/extension/operations.py --- old/azure-cli-core-2.55.0/azure/cli/core/extension/operations.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/extension/operations.py 2024-01-08 10:08:10.000000000 +0100 @@ -20,8 +20,7 @@ from azure.cli.core import CommandIndex from azure.cli.core.util import CLIError, reload_module, rmtree_with_retry from azure.cli.core.extension import (extension_exists, build_extension_path, get_extensions, get_extension_modname, - get_extension, ext_compat_with_cli, - EXT_METADATA_ISPREVIEW, EXT_METADATA_ISEXPERIMENTAL, + get_extension, ext_compat_with_cli, is_preview_from_extension_meta, WheelExtension, DevExtension, ExtensionNotInstalledException, WHEEL_INFO_RE) from azure.cli.core.telemetry import set_extension_management_detail @@ -306,7 +305,13 @@ def add_extension(cmd=None, source=None, extension_name=None, index_url=None, yes=None, # pylint: disable=unused-argument, too-many-statements pip_extra_index_urls=None, pip_proxy=None, system=None, - version=None, cli_ctx=None, upgrade=None): + version=None, cli_ctx=None, upgrade=None, allow_preview=None): + if allow_preview is None: + logger.warning("Default enabled including preview versions for extension installation now. " + "Disabled in May 2024. " + "Use '--allow-preview true' to enable it specifically if needed. " + "Use '--allow-preview false' to install stable version only. ") + allow_preview = True ext_sha256 = None update_to_latest = version == 'latest' and not source @@ -315,7 +320,7 @@ if extension_name: cmd_cli_ctx.get_progress_controller().add(message='Searching') try: - source, ext_sha256 = resolve_from_index(extension_name, index_url=index_url, target_version=version, cli_ctx=cmd_cli_ctx) + source, ext_sha256 = resolve_from_index(extension_name, index_url=index_url, target_version=version, cli_ctx=cmd_cli_ctx, allow_preview=allow_preview) except NoExtensionCandidatesError as err: logger.debug(err) err = "{}\n\nUse --debug for more information".format(err.args[0]) @@ -399,7 +404,13 @@ 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, download_url=None, ext_sha256=None): +def update_extension(cmd=None, extension_name=None, index_url=None, pip_extra_index_urls=None, pip_proxy=None, allow_preview=None, cli_ctx=None, version=None, download_url=None, ext_sha256=None): + if allow_preview is None: + logger.warning("Default enabled including preview versions for extension installation now. " + "Disabled in May 2024. " + "Use '--allow-preview true' to enable it specifically if needed. " + "Use '--allow-preview false' to install stable version only. ") + allow_preview = True try: cmd_cli_ctx = cli_ctx or cmd.cli_ctx ext = get_extension(extension_name, ext_type=WheelExtension) @@ -409,7 +420,7 @@ cur_version = ext.get_version() try: 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) + 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, allow_preview=allow_preview) _, ext_version = _get_extension_info_from_source(download_url) set_extension_management_detail(extension_name, ext_version) except NoExtensionCandidatesError as err: @@ -465,8 +476,8 @@ 'name': name, 'version': latest['metadata']['version'], 'summary': latest['metadata']['summary'], - 'preview': latest['metadata'].get(EXT_METADATA_ISPREVIEW, False), - 'experimental': latest['metadata'].get(EXT_METADATA_ISEXPERIMENTAL, False), + 'preview': is_preview_from_extension_meta(latest['metadata']), + 'experimental': False, 'installed': installed }) return results @@ -502,8 +513,8 @@ results.append({ 'name': extension_name, 'version': version, - 'preview': ext['metadata'].get(EXT_METADATA_ISPREVIEW, False), - 'experimental': ext['metadata'].get(EXT_METADATA_ISEXPERIMENTAL, False), + 'preview': is_preview_from_extension_meta(ext['metadata']), + 'experimental': False, 'installed': installed, 'compatible': compatible }) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure/cli/core/profiles/_shared.py new/azure-cli-core-2.56.0/azure/cli/core/profiles/_shared.py --- old/azure-cli-core-2.55.0/azure/cli/core/profiles/_shared.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure/cli/core/profiles/_shared.py 2024-01-08 10:08:10.000000000 +0100 @@ -156,7 +156,7 @@ 'latest': { ResourceType.MGMT_STORAGE: '2023-01-01', ResourceType.MGMT_NETWORK: '2022-01-01', - ResourceType.MGMT_COMPUTE: SDKProfile('2022-11-01', { + ResourceType.MGMT_COMPUTE: SDKProfile('2023-09-01', { 'resource_skus': '2019-04-01', 'disks': '2023-04-02', 'disk_encryption_sets': '2022-03-02', @@ -168,7 +168,7 @@ 'gallery_applications': '2021-07-01', 'gallery_application_versions': '2022-01-03', 'shared_galleries': '2022-01-03', - 'virtual_machine_scale_sets': '2023-07-01', + 'virtual_machine_scale_sets': '2023-09-01', }), ResourceType.MGMT_RESOURCE_FEATURES: '2021-07-01', ResourceType.MGMT_RESOURCE_LINKS: '2016-09-01', @@ -254,7 +254,7 @@ 'subscription_diagnostic_settings': '2017-05-01-preview' }), ResourceType.MGMT_MSI: '2023-01-31', - ResourceType.MGMT_APPSERVICE: '2022-03-01', + ResourceType.MGMT_APPSERVICE: '2023-01-01', ResourceType.MGMT_IOTHUB: '2023-06-30-preview', ResourceType.MGMT_IOTDPS: '2021-10-15', ResourceType.MGMT_IOTCENTRAL: '2021-11-01-preview', @@ -430,6 +430,10 @@ # We should avoid using ad hoc API versions, # use the version in a profile as much as possible. AD_HOC_API_VERSIONS = { + ResourceType.MGMT_APPSERVICE: { + # src/azure-cli/azure/cli/command_modules/appservice/_constants.py:68 + 'app_service_certificate_orders': '2022-09-01' + }, ResourceType.MGMT_CONTAINERREGISTRY: { # src/azure-cli/azure/cli/command_modules/acr/_client_factory.py:8 'VERSION_2019_05_01_PREVIEW': "2019-05-01-preview", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.55.0/azure_cli_core.egg-info/PKG-INFO new/azure-cli-core-2.56.0/azure_cli_core.egg-info/PKG-INFO --- old/azure-cli-core-2.55.0/azure_cli_core.egg-info/PKG-INFO 2023-11-29 04:41:37.000000000 +0100 +++ new/azure-cli-core-2.56.0/azure_cli_core.egg-info/PKG-INFO 2024-01-08 10:08:25.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.55.0 +Version: 2.56.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.55.0/setup.py new/azure-cli-core-2.56.0/setup.py --- old/azure-cli-core-2.55.0/setup.py 2023-11-29 04:41:08.000000000 +0100 +++ new/azure-cli-core-2.56.0/setup.py 2024-01-08 10:08:10.000000000 +0100 @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "2.55.0" +VERSION = "2.56.0" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions.