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-01-14 23:13:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/azure-cli-core (Old)
 and      /work/SRC/openSUSE:Factory/.azure-cli-core.new.1892 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "azure-cli-core"

Fri Jan 14 23:13:27 2022 rev:33 rq:946412 version:2.32.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/azure-cli-core/azure-cli-core.changes    
2021-12-08 22:09:45.222885043 +0100
+++ /work/SRC/openSUSE:Factory/.azure-cli-core.new.1892/azure-cli-core.changes  
2022-01-14 23:14:57.566698273 +0100
@@ -1,0 +2,9 @@
+Mon Jan 10 10:41:50 UTC 2022 - John Paul Adrian Glaubitz 
<adrian.glaub...@suse.com>
+
+- New upstream release
+  + Version 2.32.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.31.0.tar.gz

New:
----
  azure-cli-core-2.32.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ azure-cli-core.spec ++++++
--- /var/tmp/diff_new_pack.ZvLs5V/_old  2022-01-14 23:14:57.974698536 +0100
+++ /var/tmp/diff_new_pack.ZvLs5V/_new  2022-01-14 23:14:57.978698539 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package azure-cli-core
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           azure-cli-core
-Version:        2.31.0
+Version:        2.32.0
 Release:        0
 Summary:        Microsoft Azure CLI Core Module
 License:        MIT
@@ -49,7 +49,11 @@
 Requires:       python3-msal < 2.0.0
 Requires:       python3-msal >= 1.15.0
 Requires:       python3-msal-extensions < 1.0.0
-Requires:       python3-msal-extensions >= 0.3.0
+Requires:       python3-msal-extensions >= 0.3.1
+Requires:       python3-msrestazure < 0.7.0
+Requires:       python3-msrestazure >= 0.6.4
+Requires:       python3-packaging < 22.0
+Requires:       python3-packaging >= 20.9
 Requires:       python3-paramiko < 3.0.0
 Requires:       python3-paramiko >= 2.0.8
 Requires:       python3-pip

++++++ azure-cli-core-2.31.0.tar.gz -> azure-cli-core-2.32.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/HISTORY.rst 
new/azure-cli-core-2.32.0/HISTORY.rst
--- old/azure-cli-core-2.31.0/HISTORY.rst       2021-12-03 06:02:53.000000000 
+0100
+++ new/azure-cli-core-2.32.0/HISTORY.rst       2021-12-31 09:05:11.000000000 
+0100
@@ -3,6 +3,10 @@
 Release History
 ===============
 
+2.32.0
+++++++
+* Use optimistic locking for service principal entry reads (#20408)
+
 2.31.0
 ++++++
 * Use MSAL HTTP cache (#20234)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/PKG-INFO 
new/azure-cli-core-2.32.0/PKG-INFO
--- old/azure-cli-core-2.31.0/PKG-INFO  2021-12-03 06:03:07.647528200 +0100
+++ new/azure-cli-core-2.32.0/PKG-INFO  2021-12-31 09:05:24.478523300 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: azure-cli-core
-Version: 2.31.0
+Version: 2.32.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.31.0/azure/cli/core/__init__.py 
new/azure-cli-core-2.32.0/azure/cli/core/__init__.py
--- old/azure-cli-core-2.31.0/azure/cli/core/__init__.py        2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/__init__.py        2021-12-31 
09:05:11.000000000 +0100
@@ -4,7 +4,7 @@
 # 
--------------------------------------------------------------------------------------------
 # pylint: disable=line-too-long
 
-__version__ = "2.31.0"
+__version__ = "2.32.0"
 
 import os
 import sys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/azure/cli/core/_profile.py 
new/azure-cli-core-2.32.0/azure/cli/core/_profile.py
--- old/azure-cli-core-2.31.0/azure/cli/core/_profile.py        2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/_profile.py        2021-12-31 
09:05:11.000000000 +0100
@@ -195,7 +195,7 @@
 
     def login_with_managed_identity(self, identity_id=None, 
allow_no_subscriptions=None):
         import jwt
-        from msrestazure.tools import is_valid_resource_id
+        from azure.mgmt.core.tools import is_valid_resource_id
         from azure.cli.core.auth.adal_authentication import 
MSIAuthenticationWrapper
         resource = self.cli_ctx.cloud.endpoints.active_directory_resource_id
 
@@ -862,7 +862,12 @@
 
     # Only enable encryption for Windows (for now).
     fallback = sys.platform.startswith('win32')
+
+    # EXPERIMENTAL: Use core.encrypt_token_cache=False to turn off token cache 
encryption.
     # encrypt_token_cache affects both MSAL token cache and service principal 
entries.
     encrypt = cli_ctx.config.getboolean('core', 'encrypt_token_cache', 
fallback=fallback)
 
-    return Identity(*args, encrypt=encrypt, **kwargs)
+    # EXPERIMENTAL: Use core.use_msal_http_cache=False to turn off MSAL HTTP 
cache.
+    use_msal_http_cache = cli_ctx.config.getboolean('core', 
'use_msal_http_cache', fallback=True)
+
+    return Identity(*args, encrypt=encrypt, 
use_msal_http_cache=use_msal_http_cache, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/auth/adal_authentication.py 
new/azure-cli-core-2.32.0/azure/cli/core/auth/adal_authentication.py
--- old/azure-cli-core-2.31.0/azure/cli/core/auth/adal_authentication.py        
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/auth/adal_authentication.py        
2021-12-31 09:05:11.000000000 +0100
@@ -92,6 +92,13 @@
         expires_on_epoch_int = int(expires_on)
     except ValueError:
         import datetime
+
+        # Python 3.6 doesn't recognize timezone as +00:00.
+        # These lines can be dropped after Python 3.6 is dropped.
+        # 
https://stackoverflow.com/questions/30999230/how-to-parse-timezone-with-colon
+        if expires_on[-3] == ":":
+            expires_on = expires_on[:-3] + expires_on[-2:]
+
         # Treat as datetime string "11/05/2021 15:18:31 +00:00"
         expires_on_epoch_int = int(datetime.datetime.strptime(expires_on, 
'%m/%d/%Y %H:%M:%S %z').timestamp())
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/auth/identity.py 
new/azure-cli-core-2.32.0/azure/cli/core/auth/identity.py
--- old/azure-cli-core-2.31.0/azure/cli/core/auth/identity.py   2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/auth/identity.py   2021-12-31 
09:05:11.000000000 +0100
@@ -5,9 +5,11 @@
 
 import json
 import os
+import pickle
 import re
 
 from azure.cli.core._environment import get_config_dir
+from azure.cli.core.decorators import retry
 from msal import PublicClientApplication
 
 from knack.log import get_logger
@@ -45,7 +47,7 @@
     # It follows singleton pattern so that _secret_file is read only once.
     _service_principal_store_instance = None
 
-    def __init__(self, authority, tenant_id=None, client_id=None, 
encrypt=False):
+    def __init__(self, authority, tenant_id=None, client_id=None, 
encrypt=False, use_msal_http_cache=True):
         """
         :param authority: Authentication authority endpoint. For example,
             - AAD: https://login.microsoftonline.com
@@ -58,7 +60,8 @@
         self.authority = authority
         self.tenant_id = tenant_id
         self.client_id = client_id or AZURE_CLI_CLIENT_ID
-        self.encrypt = encrypt
+        self._encrypt = encrypt
+        self._use_msal_http_cache = use_msal_http_cache
 
         # Build the authority in MSAL style
         self._msal_authority, self._is_adfs = _get_authority_url(authority, 
tenant_id)
@@ -80,7 +83,7 @@
         if not Identity._msal_token_cache:
             Identity._msal_token_cache = self._load_msal_token_cache()
 
-        if not Identity._msal_http_cache:
+        if self._use_msal_http_cache and not Identity._msal_http_cache:
             Identity._msal_http_cache = self._load_msal_http_cache()
 
         return {
@@ -100,25 +103,46 @@
 
     def _load_msal_token_cache(self):
         # Store for user token persistence
-        cache = load_persisted_token_cache(self._token_cache_file, 
self.encrypt)
+        cache = load_persisted_token_cache(self._token_cache_file, 
self._encrypt)
         return cache
 
+    @retry()
+    def __load_msal_http_cache(self):
+        """Load MSAL HTTP cache with retry. If it still fails at last, raise 
the original exception as-is."""
+        logger.debug("__load_msal_http_cache: %s", self._http_cache_file)
+        try:
+            with open(self._http_cache_file, 'rb') as f:
+                return pickle.load(f)
+        except FileNotFoundError:
+            # The cache file has not been created. This is expected.
+            logger.debug("%s not found. Using a fresh one.", 
self._http_cache_file)
+            return {}
+
+    def _dump_msal_http_cache(self):
+        logger.debug("_dump_msal_http_cache: %s", self._http_cache_file)
+        with open(self._http_cache_file, 'wb') as f:
+            # At this point, an empty cache file will be created. Loading this 
cache file will
+            # trigger EOFError. This can be simulated by adding time.sleep(30) 
here.
+            # So, during loading, EOFError is ignored.
+            pickle.dump(self._msal_http_cache, f)
+
     def _load_msal_http_cache(self):
         import atexit
-        import pickle
 
         logger.debug("_load_msal_http_cache: %s", self._http_cache_file)
         try:
-            with open(self._http_cache_file, 'rb') as f:
-                persisted_http_cache = pickle.load(f)
-        except (pickle.UnpicklingError, FileNotFoundError) as ex:
-            logger.debug("Failed to load MSAL HTTP cache: %s", ex)
+            persisted_http_cache = self.__load_msal_http_cache()
+        except (pickle.UnpicklingError, EOFError) as ex:
+            # We still get exception after retry:
+            # - pickle.UnpicklingError is caused by corrupted cache file, 
perhaps due to concurrent writes.
+            # - EOFError is caused by empty cache file created by other az 
instance, but hasn't been filled yet.
+            logger.debug("Failed to load MSAL HTTP cache: %s. Using a fresh 
one.", ex)
             persisted_http_cache = {}  # Ignore a non-exist or corrupted 
http_cache
-        atexit.register(lambda: pickle.dump(
-            # When exit, flush it back to the file.
-            # If 2 processes write at the same time, the cache will be 
corrupted,
-            # but that is fine. Subsequent runs would reach eventual 
consistency.
-            persisted_http_cache, open(self._http_cache_file, 'wb')))
+
+        # When exiting, flush it back to the file.
+        # If 2 processes write at the same time, the cache will be corrupted,
+        # but that is fine. Subsequent runs would reach eventual consistency.
+        atexit.register(self._dump_msal_http_cache)
 
         return persisted_http_cache
 
@@ -128,7 +152,7 @@
         The instance is lazily created.
         """
         if not Identity._service_principal_store_instance:
-            store = load_secret_store(self._secret_file, self.encrypt)
+            store = load_secret_store(self._secret_file, self._encrypt)
             Identity._service_principal_store_instance = 
ServicePrincipalStore(store)
         return Identity._service_principal_store_instance
 
@@ -263,8 +287,9 @@
         """
         entry = {}
         if secret_or_certificate:
-            if os.path.isfile(secret_or_certificate):
-                entry[_CERTIFICATE] = secret_or_certificate
+            user_expanded = os.path.expanduser(secret_or_certificate)
+            if os.path.isfile(user_expanded):
+                entry[_CERTIFICATE] = user_expanded
                 if use_cert_sn_issuer:
                     entry[_USE_CERT_SN_ISSUER] = use_cert_sn_issuer
             else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/auth/persistence.py 
new/azure-cli-core-2.32.0/azure/cli/core/auth/persistence.py
--- old/azure-cli-core-2.31.0/azure/cli/core/auth/persistence.py        
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/auth/persistence.py        
2021-12-31 09:05:11.000000000 +0100
@@ -13,8 +13,9 @@
                              FilePersistence, PersistedTokenCache, 
CrossPlatLock)
 from msal_extensions.persistence import PersistenceNotFound
 
-from knack.util import CLIError
 from knack.log import get_logger
+from azure.cli.core.decorators import retry
+
 
 logger = get_logger(__name__)
 
@@ -60,13 +61,9 @@
         with CrossPlatLock(self._lock_file):
             self._persistence.save(json.dumps(content, indent=4))
 
+    @retry()
     def load(self):
-        with CrossPlatLock(self._lock_file):
-            try:
-                return json.loads(self._persistence.load())
-            except PersistenceNotFound:
-                return []
-            except Exception as ex:
-                raise CLIError("Failed to load token files. If you can 
reproduce, please log an issue at "
-                               "https://github.com/Azure/azure-cli/issues. At 
the same time, you can clean "
-                               "up by running 'az account clear' and then 'az 
login'. (Inner Error: {})".format(ex))
+        try:
+            return json.loads(self._persistence.load())
+        except PersistenceNotFound:
+            return []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/command_recommender.py 
new/azure-cli-core-2.32.0/azure/cli/core/command_recommender.py
--- old/azure-cli-core-2.31.0/azure/cli/core/command_recommender.py     
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/command_recommender.py     
2021-12-31 09:05:11.000000000 +0100
@@ -134,6 +134,7 @@
         api_url = 'https://app.aladdin.microsoft.com/api/v1.0/suggestions'
         correlation_id = telemetry._session.correlation_id  # pylint: 
disable=protected-access
         subscription_id = telemetry._get_azure_subscription_id()  # pylint: 
disable=protected-access
+        event_id = telemetry._session.event_id  # pylint: 
disable=protected-access
         # Used for DDOS protection and rate limiting
         user_id = telemetry._get_user_azure_id()  # pylint: 
disable=protected-access
         hashed_user_id = hashlib.sha256(user_id.encode('utf-8')).hexdigest()
@@ -152,6 +153,8 @@
                 context['correlationId'] = correlation_id
             if subscription_id:
                 context['subscriptionId'] = subscription_id
+            if event_id:
+                context['eventId'] = event_id
 
         parameters = self._normalize_parameters(self.parameters)
         parameters = [item for item in set(parameters) if item not in 
['--debug', '--verbose', '--only-show-errors']]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/azure/cli/core/commands/arm.py 
new/azure-cli-core-2.32.0/azure/cli/core/commands/arm.py
--- old/azure-cli-core-2.31.0/azure/cli/core/commands/arm.py    2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/commands/arm.py    2021-12-31 
09:05:11.000000000 +0100
@@ -169,7 +169,7 @@
 class ResourceId(str):
 
     def __new__(cls, val):
-        from msrestazure.tools import is_valid_resource_id
+        from azure.mgmt.core.tools import is_valid_resource_id
         if not is_valid_resource_id(val):
             raise ValueError()
         return str.__new__(cls, val)
@@ -782,7 +782,7 @@
 
 
 def get_arm_resource_by_id(cli_ctx, arm_id, api_version=None):
-    from msrestazure.tools import parse_resource_id, is_valid_resource_id
+    from azure.mgmt.core.tools import parse_resource_id, is_valid_resource_id
 
     if not is_valid_resource_id(arm_id):
         raise CLIError("'{}' is not a valid ID.".format(arm_id))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/commands/progress.py 
new/azure-cli-core-2.32.0/azure/cli/core/commands/progress.py
--- old/azure-cli-core-2.31.0/azure/cli/core/commands/progress.py       
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/commands/progress.py       
2021-12-31 09:05:11.000000000 +0100
@@ -5,7 +5,7 @@
 from __future__ import division
 import sys
 
-import humanfriendly
+from humanfriendly.terminal.spinners import Spinner
 
 BAR_LEN = 70
 EMPTY_LINE = ' ' * BAR_LEN
@@ -115,7 +115,7 @@
         :param args: dictionary containing key 'message'
         """
         if self.spinner is None:
-            self.spinner = humanfriendly.Spinner(  # pylint: disable=no-member
+            self.spinner = Spinner(  # pylint: disable=no-member
                 label='In Progress', stream=self.out, hide_cursor=False)
         msg = args.get('message', 'In Progress')
         try:
@@ -179,7 +179,7 @@
         self.message = message
         self.hook = self.cli_ctx.get_progress_controller(
             det=False,
-            spinner=humanfriendly.Spinner(  # pylint: disable=no-member
+            spinner=Spinner(  # pylint: disable=no-member
                 label='Running',
                 stream=sys.stderr,
                 hide_cursor=False))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/commands/template_create.py 
new/azure-cli-core-2.32.0/azure/cli/core/commands/template_create.py
--- old/azure-cli-core-2.31.0/azure/cli/core/commands/template_create.py        
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/commands/template_create.py        
2021-12-31 09:05:11.000000000 +0100
@@ -53,7 +53,7 @@
 def _validate_name_or_id(
         cli_ctx, resource_group_name, property_value, property_type, 
parent_value, parent_type):
     from azure.cli.core.commands.client_factory import get_subscription_id
-    from msrestazure.tools import parse_resource_id, is_valid_resource_id
+    from azure.mgmt.core.tools import parse_resource_id, is_valid_resource_id
     has_parent = parent_type is not None
     if is_valid_resource_id(property_value):
         resource_id_parts = parse_resource_id(property_value)
@@ -95,7 +95,7 @@
 
     # construct the validator
     def validator(cmd, namespace):
-        from msrestazure.tools import resource_id
+        from azure.mgmt.core.tools import resource_id
         type_field_name = '{}_type'.format(property_name)
         property_val = getattr(namespace, property_name, None)
         parent_val = getattr(namespace, parent_name, None) if parent_name else 
None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/commands/transform.py 
new/azure-cli-core-2.32.0/azure/cli/core/commands/transform.py
--- old/azure-cli-core-2.31.0/azure/cli/core/commands/transform.py      
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/commands/transform.py      
2021-12-31 09:05:11.000000000 +0100
@@ -15,6 +15,11 @@
     cli_ctx.register_event(events.EVENT_INVOKER_TRANSFORM_RESULT, 
_x509_from_base64_to_hex_transform)
 
 
+def unregister_global_transforms(cli_ctx):
+    cli_ctx.unregister_event(events.EVENT_INVOKER_TRANSFORM_RESULT, 
_resource_group_transform)
+    cli_ctx.unregister_event(events.EVENT_INVOKER_TRANSFORM_RESULT, 
_x509_from_base64_to_hex_transform)
+
+
 def _parse_id(strid):
     parsed = {}
     parts = re.split('/', strid)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/commands/validators.py 
new/azure-cli-core-2.32.0/azure/cli/core/commands/validators.py
--- old/azure-cli-core-2.31.0/azure/cli/core/commands/validators.py     
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/commands/validators.py     
2021-12-31 09:05:11.000000000 +0100
@@ -71,15 +71,13 @@
 def get_default_location_from_resource_group(cmd, namespace):
     if not namespace.location:
         from azure.cli.core.commands.client_factory import 
get_mgmt_service_client
-        from msrestazure.azure_exceptions import CloudError
-        from knack.util import CLIError
 
+        # We don't use try catch here to let 
azure.cli.core.parser.AzCliCommandParser.validation_error
+        # handle exceptions, such as 
azure.core.exceptions.ResourceNotFoundError
         resource_client = get_mgmt_service_client(cmd.cli_ctx, 
ResourceType.MGMT_RESOURCE_RESOURCES)
-        try:
-            rg = 
resource_client.resource_groups.get(namespace.resource_group_name)
-        except CloudError as ex:
-            raise CLIError('error retrieving default location: 
{}'.format(ex.message))
+        rg = resource_client.resource_groups.get(namespace.resource_group_name)
         namespace.location = rg.location  # pylint: disable=no-member
+
         logger.debug("using location '%s' from resource group '%s'", 
namespace.location, rg.name)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/azure/cli/core/decorators.py 
new/azure-cli-core-2.32.0/azure/cli/core/decorators.py
--- old/azure-cli-core-2.31.0/azure/cli/core/decorators.py      2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/decorators.py      2021-12-31 
09:05:11.000000000 +0100
@@ -16,6 +16,9 @@
 from knack.log import get_logger
 
 
+logger = get_logger(__name__)
+
+
 # pylint: disable=too-few-public-methods
 class Completer:
 
@@ -81,3 +84,30 @@
                     return fallback_return
         return _wrapped_func
     return _decorator
+
+
+def retry(retry_times=3, interval=0.5, exceptions=Exception):
+    """Use optimistic locking to call a function, so that multiple processes 
can
+    access the same resource (such as a file) at the same time.
+
+    :param retry_times: Times to retry.
+    :param interval: Interval between retries.
+    :param exceptions: Exceptions that can be ignored. Use a tuple if multiple 
exceptions should be ignored.
+    """
+    def _decorator(func):
+        @wraps(func)
+        def _wrapped_func(*args, **kwargs):
+            for attempt in range(1, retry_times + 1):
+                try:
+                    return func(*args, **kwargs)
+                except exceptions:  # pylint: disable=broad-except
+                    if attempt < retry_times:
+                        logger.debug("%s failed in No. %d attempt", func, 
attempt)
+                        import traceback
+                        import time
+                        logger.debug(traceback.format_exc())
+                        time.sleep(interval)
+                    else:
+                        raise  # End of retry. Re-raise the exception as-is.
+        return _wrapped_func
+    return _decorator
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure/cli/core/profiles/_shared.py 
new/azure-cli-core-2.32.0/azure/cli/core/profiles/_shared.py
--- old/azure-cli-core-2.31.0/azure/cli/core/profiles/_shared.py        
2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/profiles/_shared.py        
2021-12-31 09:05:11.000000000 +0100
@@ -64,6 +64,7 @@
     MGMT_APPSERVICE = ('azure.mgmt.web', 'WebSiteManagementClient')
     MGMT_IOTCENTRAL = ('azure.mgmt.iotcentral', 'IotCentralClient')
     MGMT_IOTHUB = ('azure.mgmt.iothub', 'IotHubClient')
+    MGMT_IOTDPS = ('azure.mgmt.iothubprovisioningservices', 'IotDpsClient')
     MGMT_ARO = ('azure.mgmt.redhatopenshift', 'AzureRedHatOpenShift4Client')
     MGMT_DATABOXEDGE = ('azure.mgmt.databoxedge', 
'DataBoxEdgeManagementClient')
     MGMT_CUSTOMLOCATION = ('azure.mgmt.extendedlocation', 'CustomLocations')
@@ -227,6 +228,7 @@
         }),
         ResourceType.MGMT_APPSERVICE: '2020-09-01',
         ResourceType.MGMT_IOTHUB: '2021-07-01',
+        ResourceType.MGMT_IOTDPS: '2020-03-01',
         ResourceType.MGMT_IOTCENTRAL: '2018-09-01',
         ResourceType.MGMT_ARO: '2020-04-30',
         ResourceType.MGMT_DATABOXEDGE: '2021-02-01-preview',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/azure/cli/core/telemetry.py 
new/azure-cli-core-2.32.0/azure/cli/core/telemetry.py
--- old/azure-cli-core-2.31.0/azure/cli/core/telemetry.py       2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/telemetry.py       2021-12-31 
09:05:11.000000000 +0100
@@ -45,6 +45,7 @@
         self.module_correlation = None
         self.extension_name = None
         self.extension_version = None
+        self.event_id = str(uuid.uuid4())
         self.feedback = None
         self.extension_management_detail = None
         self.raw_command = None
@@ -105,7 +106,7 @@
                 props.update(base)
                 props.update(cli)
                 props.update({CORRELATION_ID_PROP_NAME: str(uuid.uuid4()),
-                              'Reserved.EventId': str(uuid.uuid4())})
+                              'Reserved.EventId': self.event_id})
                 self.events[DEFAULT_INSTRUMENTATION_KEY].append({
                     'name': name,
                     'properties': props
@@ -117,7 +118,7 @@
     def _get_base_properties(self):
         return {
             'Reserved.ChannelUsed': 'AI',
-            'Reserved.EventId': str(uuid.uuid4()),
+            'Reserved.EventId': self.event_id,
             'Reserved.SequenceNumber': 1,
             'Reserved.SessionId': _get_session_id(),
             'Reserved.TimeSinceSessionStart': 0,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/azure/cli/core/util.py 
new/azure-cli-core-2.32.0/azure/cli/core/util.py
--- old/azure-cli-core-2.31.0/azure/cli/core/util.py    2021-12-03 
06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure/cli/core/util.py    2021-12-31 
09:05:11.000000000 +0100
@@ -380,6 +380,13 @@
             else:
                 _print(ext.name.ljust(20) + (ext.version or 
'Unknown').rjust(20))
         _print()
+
+    _print('Dependencies:')
+    dependencies_versions = get_dependency_versions()
+    for k, v in dependencies_versions.items():
+        _print(k.ljust(20) + v.rjust(20))
+    _print()
+
     _print("Python location '{}'".format(os.path.abspath(sys.executable)))
     _print("Extensions directory '{}'".format(EXTENSIONS_DIR))
     if os.path.isdir(EXTENSIONS_SYS_DIR) and os.listdir(EXTENSIONS_SYS_DIR):
@@ -415,6 +422,31 @@
     return versions
 
 
+def get_dependency_versions():
+    versions = {}
+    # Add msal version
+    try:
+        from msal import __version__ as msal_version
+    except ImportError:
+        msal_version = "N/A"
+    versions['msal'] = msal_version
+
+    # Add azure-mgmt-resource version
+    try:
+        # Track 2 >=15.0.0
+        # pylint: disable=protected-access
+        from azure.mgmt.resource._version import VERSION as 
azure_mgmt_resource_version
+    except ImportError:
+        try:
+            # Track 1 <=13.0.0
+            from azure.mgmt.resource.version import VERSION as 
azure_mgmt_resource_version
+        except ImportError:
+            azure_mgmt_resource_version = "N/A"
+    versions['azure-mgmt-resource'] = azure_mgmt_resource_version
+
+    return versions
+
+
 def show_updates_available(new_line_before=False, new_line_after=False):
     from azure.cli.core._session import VERSIONS
     import datetime
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-core-2.31.0/azure_cli_core.egg-info/PKG-INFO 
new/azure-cli-core-2.32.0/azure_cli_core.egg-info/PKG-INFO
--- old/azure-cli-core-2.31.0/azure_cli_core.egg-info/PKG-INFO  2021-12-03 
06:03:07.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure_cli_core.egg-info/PKG-INFO  2021-12-31 
09:05:24.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: azure-cli-core
-Version: 2.31.0
+Version: 2.32.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.31.0/azure_cli_core.egg-info/requires.txt 
new/azure-cli-core-2.32.0/azure_cli_core.egg-info/requires.txt
--- old/azure-cli-core-2.31.0/azure_cli_core.egg-info/requires.txt      
2021-12-03 06:03:07.000000000 +0100
+++ new/azure-cli-core-2.32.0/azure_cli_core.egg-info/requires.txt      
2021-12-31 09:05:24.000000000 +0100
@@ -5,8 +5,10 @@
 humanfriendly~=10.0
 jmespath
 knack~=0.9.0
-msal-extensions<0.4,>=0.3.0
+msal-extensions<0.4,>=0.3.1
 msal<2.0.0,>=1.16.0
+msrestazure~=0.6.4
+packaging<22.0,>=20.9
 paramiko<3.0.0,>=2.0.8
 pkginfo>=1.5.0.1
 PyJWT>=2.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-core-2.31.0/setup.py 
new/azure-cli-core-2.32.0/setup.py
--- old/azure-cli-core-2.31.0/setup.py  2021-12-03 06:02:53.000000000 +0100
+++ new/azure-cli-core-2.32.0/setup.py  2021-12-31 09:05:11.000000000 +0100
@@ -8,7 +8,7 @@
 from codecs import open
 from setuptools import setup, find_packages
 
-VERSION = "2.31.0"
+VERSION = "2.32.0"
 
 # If we have source, validate that our version numbers match
 # This should prevent uploading releases with mismatched versions.
@@ -51,8 +51,10 @@
     'humanfriendly~=10.0',
     'jmespath',
     'knack~=0.9.0',
-    'msal-extensions>=0.3.0,<0.4',
+    'msal-extensions>=0.3.1,<0.4',
     'msal>=1.16.0,<2.0.0',
+    'msrestazure~=0.6.4',
+    'packaging>=20.9,<22.0',
     'paramiko>=2.0.8,<3.0.0',
     'pkginfo>=1.5.0.1',
     'PyJWT>=2.1.0',

Reply via email to