From 6198a7b21610fd508b8408d2c60bdd521912b94a Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Tue, 16 Mar 2021 21:34:30 -0700 Subject: [PATCH 1/7] Fix Azure Functions run --- .../c7n_azure/provisioning/app_insights.py | 4 ++-- .../c7n_azure/provisioning/resource_group.py | 4 ++-- .../c7n_azure/provisioning/storage_account.py | 4 ++-- tools/c7n_azure/c7n_azure/session.py | 16 ++++++++++---- tools/c7n_azure/c7n_azure/utils.py | 2 +- tools/c7n_azure/poetry.lock | 21 +++++++++++++++++-- tools/c7n_azure/pyproject.toml | 2 ++ tools/c7n_azure/requirements.txt | 2 ++ tools/c7n_azure/setup.py | 2 ++ 9 files changed, 44 insertions(+), 13 deletions(-) diff --git a/tools/c7n_azure/c7n_azure/provisioning/app_insights.py b/tools/c7n_azure/c7n_azure/provisioning/app_insights.py index 5e8cc3f112d..f42cdb7d6f3 100644 --- a/tools/c7n_azure/c7n_azure/provisioning/app_insights.py +++ b/tools/c7n_azure/c7n_azure/provisioning/app_insights.py @@ -1,6 +1,6 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 -from msrestazure.azure_exceptions import CloudError +from azure.core.exceptions import ResourceNotFoundError from c7n_azure.provisioning.deployment_unit import DeploymentUnit from c7n_azure.provisioning.resource_group import ResourceGroupUnit @@ -16,7 +16,7 @@ def __init__(self): def _get(self, params): try: return self.client.components.get(params['resource_group_name'], params['name']) - except CloudError: + except ResourceNotFoundError: return None def _provision(self, params): diff --git a/tools/c7n_azure/c7n_azure/provisioning/resource_group.py b/tools/c7n_azure/c7n_azure/provisioning/resource_group.py index a574716effb..8fc6d6d0b53 100644 --- a/tools/c7n_azure/c7n_azure/provisioning/resource_group.py +++ b/tools/c7n_azure/c7n_azure/provisioning/resource_group.py @@ -1,6 +1,6 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 -from msrestazure.azure_exceptions import CloudError +from azure.core.exceptions import ResourceNotFoundError from c7n_azure.provisioning.deployment_unit import DeploymentUnit @@ -18,7 +18,7 @@ def verify_params(self, params): def _get(self, params): try: return self.client.resource_groups.get(params['name']) - except CloudError: + except ResourceNotFoundError: return None def _provision(self, params): diff --git a/tools/c7n_azure/c7n_azure/provisioning/storage_account.py b/tools/c7n_azure/c7n_azure/provisioning/storage_account.py index cd0e600610c..aaa2f247630 100644 --- a/tools/c7n_azure/c7n_azure/provisioning/storage_account.py +++ b/tools/c7n_azure/c7n_azure/provisioning/storage_account.py @@ -1,6 +1,6 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 -from msrestazure.azure_exceptions import CloudError +from azure.core.exceptions import ResourceNotFoundError from c7n_azure.provisioning.deployment_unit import DeploymentUnit from c7n_azure.provisioning.resource_group import ResourceGroupUnit @@ -17,7 +17,7 @@ def _get(self, params): try: return self.client.storage_accounts.get_properties(params['resource_group_name'], params['name']) - except CloudError: + except ResourceNotFoundError: return None def _provision(self, params): diff --git a/tools/c7n_azure/c7n_azure/session.py b/tools/c7n_azure/c7n_azure/session.py index 0333fd36aa8..a4e27087296 100644 --- a/tools/c7n_azure/c7n_azure/session.py +++ b/tools/c7n_azure/c7n_azure/session.py @@ -75,31 +75,39 @@ def __init__(self, cloud_endpoints, authorization_file=None, subscription_id_ove self._credential = None self._subscription_id = self._auth_params['subscription_id'] if self._auth_params.get('access_token') is not None: + auth_name = 'Access Token' pass - elif (self._auth_params['client_id'] and - self._auth_params['client_secret'] and - self._auth_params['tenant_id'] + elif (self._auth_params.get('client_id') and + self._auth_params.get('client_secret') and + self._auth_params.get('tenant_id') ): + auth_name = 'Principal' self._credential = ClientSecretCredential( client_id=self._auth_params['client_id'], client_secret=self._auth_params['client_secret'], tenant_id=self._auth_params['tenant_id'], authority=self._auth_params['authority']) elif self._auth_params.get('use_msi'): + auth_name = 'MSI' self._credential = ManagedIdentityCredential( client_id=self._auth_params.get('client_id')) elif self._auth_params.get('enable_cli_auth'): + auth_name = 'Azure CLI' self._credential = AzureCliCredential() self._subscription_id, error = _run_command('az account show --output tsv --query id') self._subscription_id = self._subscription_id.strip('\n') if error is not None: raise Exception('Unable to query SubscriptionId') + log.info('Authenticated [%s | %s%s]', + auth_name, self.subscription_id, + ' | Authorization File' if authorization_file else '') + def get_token(self, *scopes, **kwargs): # Access Token is used only in tests realistically because # KeyVault, Storage and mgmt plane requires separate tokens. # TODO: Should we scope this to tests only? - if (self._auth_params['access_token']): + if (self._auth_params.get('access_token')): return AccessToken(self._auth_params['access_token'], expires_on=0) try: return self._credential.get_token(*scopes, **kwargs) diff --git a/tools/c7n_azure/c7n_azure/utils.py b/tools/c7n_azure/c7n_azure/utils.py index 3fa5c911c36..1556ee0cdfc 100644 --- a/tools/c7n_azure/c7n_azure/utils.py +++ b/tools/c7n_azure/c7n_azure/utils.py @@ -633,7 +633,7 @@ def log_response_data(response): send_logger.debug(http_response.status_code) for k, v in http_response.headers.items(): if k.startswith('x-ms-ratelimit'): - send_logger.info(k + ':' + v) + send_logger.debug(k + ':' + v) # This workaround will replace used api-version for costmanagement requests diff --git a/tools/c7n_azure/poetry.lock b/tools/c7n_azure/poetry.lock index b9a6c27c606..279c3a80f87 100644 --- a/tools/c7n_azure/poetry.lock +++ b/tools/c7n_azure/poetry.lock @@ -547,6 +547,19 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.2.0,<2.0.0" msrest = ">=0.5.0" +[[package]] +name = "azure-mgmt-msi" +version = "1.0.0" +description = "Microsoft Azure MSI Management Client Library for Python" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +azure-common = ">=1.1,<2.0" +msrest = ">=0.5.0" +msrestazure = ">=0.4.32,<2.0.0" + [[package]] name = "azure-mgmt-network" version = "17.1.0" @@ -928,7 +941,7 @@ six = "*" name = "jmespath" version = "0.10.0" description = "JSON Matching Expressions" -category = "dev" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" @@ -1297,7 +1310,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "9ac507c9c0fa482c21c2e91c688c027ac9585328dd369157412a3b9dc0cacf29" +content-hash = "1f75519ef4af8cfffd36ad9d6d141fc8f7a3c619c8c097ba00bc6d9b958dfd20" [metadata.files] adal = [ @@ -1468,6 +1481,10 @@ azure-mgmt-monitor = [ {file = "azure-mgmt-monitor-2.0.0.zip", hash = "sha256:e7f7943fe8f0efe98b3b1996cdec47c709765257a6e09e7940f7838a0f829e82"}, {file = "azure_mgmt_monitor-2.0.0-py2.py3-none-any.whl", hash = "sha256:af4917df2fe685e3daf25750f3586f11ccd2e7c2da68df392ca093fc3b7b8089"}, ] +azure-mgmt-msi = [ + {file = "azure-mgmt-msi-1.0.0.zip", hash = "sha256:d46f3aab25db3dad520e4055c1d67afe4fcc6d66335c762134e60f82265f8f58"}, + {file = "azure_mgmt_msi-1.0.0-py2.py3-none-any.whl", hash = "sha256:e75175af21f9a471c1e8d7a538c11905d65083b86d661b9a759578fb65a1dbcc"}, +] azure-mgmt-network = [ {file = "azure-mgmt-network-17.1.0.zip", hash = "sha256:f47852836a5960447ab534784a9285696969f007744ba030828da2eab92621ab"}, {file = "azure_mgmt_network-17.1.0-py2.py3-none-any.whl", hash = "sha256:43a1896c4d674ab28c46e2261f128d3ab7a30bcb19cf806f20ff5bccf95187d9"}, diff --git a/tools/c7n_azure/pyproject.toml b/tools/c7n_azure/pyproject.toml index 52207d4f371..95201960cb0 100644 --- a/tools/c7n_azure/pyproject.toml +++ b/tools/c7n_azure/pyproject.toml @@ -76,6 +76,8 @@ azure-identity = "^1.5.0" azure-keyvault = "^4.1.0" azure-storage-file-share = "^12.4.1" cryptography = "^3.4.6" +azure-mgmt-msi = "^1.0.0" +jmespath = "^0.10.0" [tool.poetry.dev-dependencies] # setup custodian as a dev dependency diff --git a/tools/c7n_azure/requirements.txt b/tools/c7n_azure/requirements.txt index a0a496d1b3d..7a1495c3b92 100644 --- a/tools/c7n_azure/requirements.txt +++ b/tools/c7n_azure/requirements.txt @@ -38,6 +38,7 @@ azure-mgmt-keyvault==8.0.0 azure-mgmt-logic==9.0.0 azure-mgmt-managementgroups==1.0.0b1 azure-mgmt-monitor==2.0.0 +azure-mgmt-msi==1.0.0 azure-mgmt-network==17.1.0 azure-mgmt-policyinsights==1.0.0 azure-mgmt-rdbms==8.0.0 @@ -64,6 +65,7 @@ distlib==0.3.1 idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" importlib-resources==5.1.2; python_version >= "3.6" and python_version < "3.7" isodate==0.6.0 +jmespath==0.10.0; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") jsonpickle==1.3 msal-extensions==0.3.0 msal==1.10.0 diff --git a/tools/c7n_azure/setup.py b/tools/c7n_azure/setup.py index a54e29d8727..d2e01ba26e4 100644 --- a/tools/c7n_azure/setup.py +++ b/tools/c7n_azure/setup.py @@ -52,6 +52,7 @@ 'azure-mgmt-logic>=9.0.0,<10.0.0', 'azure-mgmt-managementgroups==1.0.0b1', 'azure-mgmt-monitor>=2.0.0,<3.0.0', + 'azure-mgmt-msi>=1.0.0,<2.0.0', 'azure-mgmt-network>=17.1.0,<18.0.0', 'azure-mgmt-policyinsights>=1.0.0,<2.0.0', 'azure-mgmt-rdbms>=8.0.0,<9.0.0', @@ -75,6 +76,7 @@ 'distlib>=0.3.0,<0.4.0', 'importlib-metadata (>=3.7.2,<4.0.0)', 'jmespath (>=0.10.0,<0.11.0)', + 'jmespath>=0.10.0,<0.11.0', 'jsonpickle (>=1.3,<2.0)', 'jsonpickle==1.3', 'jsonschema (>=3.2.0,<4.0.0)', From 5a75e52a729a9aa90995800c4ffe45ef3fe63dbc Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Tue, 16 Mar 2021 22:28:41 -0700 Subject: [PATCH 2/7] Update exception --- tools/c7n_azure/c7n_azure/handler.py | 3 ++- .../resources/network_security_group.py | 4 ++-- .../c7n_azure/resources/sqldatabase.py | 21 +++++++++---------- tools/c7n_azure/tests_azure/azure_common.py | 2 +- .../tests_resources/test_keyvault.py | 8 +++---- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/c7n_azure/c7n_azure/handler.py b/tools/c7n_azure/c7n_azure/handler.py index 0303da2d917..cd8b397cdb2 100644 --- a/tools/c7n_azure/c7n_azure/handler.py +++ b/tools/c7n_azure/c7n_azure/handler.py @@ -8,6 +8,7 @@ from azure.common import AzureHttpError from msrestazure.azure_exceptions import CloudError +from azure.core.exceptions import AzureError from c7n.utils import reset_session_cache from c7n.config import Config @@ -53,7 +54,7 @@ def run(event, context, subscription_id=None): for p in policies: try: p.push(event, context) - except (CloudError, AzureHttpError) as error: + except (CloudError, AzureHttpError, AzureError) as error: log.error("Unable to process policy: %s :: %s" % (p.name, error)) reset_session_cache() diff --git a/tools/c7n_azure/c7n_azure/resources/network_security_group.py b/tools/c7n_azure/c7n_azure/resources/network_security_group.py index e5ce49b61c6..2c1e2c2dee1 100644 --- a/tools/c7n_azure/c7n_azure/resources/network_security_group.py +++ b/tools/c7n_azure/c7n_azure/resources/network_security_group.py @@ -6,7 +6,7 @@ from c7n_azure.provider import resources from c7n_azure.resources.arm import ArmResourceManager from c7n_azure.utils import StringUtils, PortsRangeHelper -from msrestazure.azure_exceptions import CloudError +from azure.core.exceptions import AzureError from c7n.actions import BaseAction from c7n.filters import Filter, FilterValidationError @@ -295,7 +295,7 @@ def process(self, network_security_groups): rule_name, new_rule ) - except CloudError as e: + except AzureError as e: self.manager.log.error('Failed to create or update security rule for %s NSG.', nsg_name) self.manager.log.error(e) diff --git a/tools/c7n_azure/c7n_azure/resources/sqldatabase.py b/tools/c7n_azure/c7n_azure/resources/sqldatabase.py index 93371735f5a..8a994dfa521 100644 --- a/tools/c7n_azure/c7n_azure/resources/sqldatabase.py +++ b/tools/c7n_azure/c7n_azure/resources/sqldatabase.py @@ -17,6 +17,7 @@ import enum import logging +from azure.core.exceptions import AzureError, ResourceNotFoundError from azure.mgmt.sql.models import (BackupLongTermRetentionPolicy, BackupShortTermRetentionPolicy, DatabaseUpdate, Sku) @@ -29,7 +30,6 @@ from c7n_azure.query import ChildTypeInfo from c7n_azure.resources.arm import ChildArmResourceManager from c7n_azure.utils import ResourceIdParser, RetentionPeriod, ThreadHelper -from msrestazure.azure_exceptions import CloudError log = logging.getLogger('custodian.azure.sqldatabase') @@ -119,17 +119,16 @@ def get_backup_retention_policy(database, get_operation, cache_key): try: response = get_operation(resource_group_name, server_name, database_name, policy) - except CloudError as e: - if e.status_code == 404: - return None - else: - log.error( - "Unable to get backup retention policy. " - "(resourceGroup: {}, sqlserver: {}, sqldatabase: {})".format( - resource_group_name, server_name, database_name - ) + except ResourceNotFoundError: + return None + except AzureError as e: + log.error( + "Unable to get backup retention policy. " + "(resourceGroup: {}, sqlserver: {}, sqldatabase: {})".format( + resource_group_name, server_name, database_name ) - raise e + ) + raise e retention_policy = response.as_dict() database[policy_key] = retention_policy diff --git a/tools/c7n_azure/tests_azure/azure_common.py b/tools/c7n_azure/tests_azure/azure_common.py index d7448f03c10..969be8f9a67 100644 --- a/tools/c7n_azure/tests_azure/azure_common.py +++ b/tools/c7n_azure/tests_azure/azure_common.py @@ -473,7 +473,7 @@ def lro_init(self, client, initial_response, deserialization_callback, polling_m issubclass(deserialization_callback, Model): deserialization_callback = deserialization_callback.deserialize - # Might raise a CloudError + # Might raise a AzureError self._polling_method.initialize(self._client, self._response, deserialization_callback) self._thread = None diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_keyvault.py b/tools/c7n_azure/tests_azure/tests_resources/test_keyvault.py index dbe3ace697b..ff6ca89ef05 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_keyvault.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_keyvault.py @@ -7,7 +7,7 @@ from c7n_azure.session import Session from c7n_azure.utils import GraphHelper from mock import patch, Mock -from msrestazure.azure_exceptions import CloudError +from azure.core.exceptions import HttpResponseError from netaddr import IPSet from parameterized import parameterized import pytest @@ -138,8 +138,8 @@ def test_whitelist_not_authorized(self, get_principal_dictionary): mock_response = Mock(spec=Response) mock_response.status_code = 403 - mock_response.text = 'forbidden' - get_principal_dictionary.side_effect = CloudError(mock_response) + mock_response.reason = 'forbidden' + get_principal_dictionary.side_effect = HttpResponseError(response=mock_response) p = self.load_policy({ 'name': 'test-key-vault', @@ -158,7 +158,7 @@ def test_whitelist_not_authorized(self, get_principal_dictionary): ] }) - with self.assertRaises(CloudError) as e: + with self.assertRaises(HttpResponseError) as e: p.run() self.assertEqual(403, e.exception.status_code) From 9e03c3c133fcac5fd0060ae30e9b56c0b3050fb3 Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Tue, 16 Mar 2021 23:24:05 -0700 Subject: [PATCH 3/7] Container Host fix --- tools/c7n_azure/c7n_azure/container_host/host.py | 6 +++--- tools/c7n_azure/c7n_azure/storage_utils.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/c7n_azure/c7n_azure/container_host/host.py b/tools/c7n_azure/c7n_azure/container_host/host.py index bc4b0ec9189..192a13dec79 100644 --- a/tools/c7n_azure/c7n_azure/container_host/host.py +++ b/tools/c7n_azure/c7n_azure/container_host/host.py @@ -159,7 +159,7 @@ def update_policies(self): client.get_blob_to_path(container, blob.name, policy_path) self.load_policy(policy_path, policies_copy) - self.blob_cache.update({blob.name: blob.properties.content_settings.content_md5}) + self.blob_cache.update({blob.name: blob.content_settings.content_md5}) # Assign our copy back over the original self.policies = policies_copy @@ -167,7 +167,7 @@ def update_policies(self): def _get_new_blobs(self, blobs): new_blobs = [] for blob in blobs: - md5_hash = blob.properties.content_settings.content_md5 + md5_hash = blob.content_settings.content_md5 if not md5_hash: blob, md5_hash = self._try_create_md5_content_hash(blob) if blob and md5_hash and md5_hash != self.blob_cache.get(blob.name): @@ -191,7 +191,7 @@ def _try_create_md5_content_hash(self, blob): # Re-fetch the blob with the new hash hashed_blob = client.get_blob_properties(container, blob.name) - return hashed_blob, hashed_blob.properties.content_settings.content_md5 + return hashed_blob, hashed_blob.content_settings.content_md5 except AzureHttpError as e: log.warning("Failed to apply a md5 content hash to policy {}. " "This policy will be skipped.".format(blob.name)) diff --git a/tools/c7n_azure/c7n_azure/storage_utils.py b/tools/c7n_azure/c7n_azure/storage_utils.py index 269664e9e34..ef4b3f530fb 100644 --- a/tools/c7n_azure/c7n_azure/storage_utils.py +++ b/tools/c7n_azure/c7n_azure/storage_utils.py @@ -19,6 +19,12 @@ def get_blob_to_bytes(self, container_name, blob_name): client = self.get_blob_client(container_name, blob_name) return client.download_blob().content_as_bytes() + def get_blob_to_path(self, container_name, blob_name, path): + client = self.get_blob_client(container_name, blob_name) + with open(path, "wb") as f: + download_stream = client.download_blob() + f.write(download_stream.readall()) + def create_blob_from_bytes(self, container_name, blob_name, content, validate_content): client = self.get_blob_client(container_name, blob_name) client.upload_blob(content, overwrite=True) @@ -27,6 +33,11 @@ def get_blob_properties(self, container_name, blob_name): client = self.get_blob_client(container_name, blob_name) return client.get_blob_properties() + def list_blobs(self, container_name): + client = self.get_container_client(container_name) + return client.list_blobs() + + class OldQueueService: From d626136f8d830f5928b3cf531d9314028b00cafb Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Tue, 16 Mar 2021 23:58:39 -0700 Subject: [PATCH 4/7] mailer_tests --- tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py | 9 ++++----- tools/c7n_mailer/tests/test_azure.py | 3 ++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py b/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py index 283da7ff2a8..568f02fee1c 100644 --- a/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py +++ b/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py @@ -1,16 +1,15 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +from azure.keyvault.secrets import SecretProperties from c7n_azure.constants import VAULT_AUTH_ENDPOINT -from azure.keyvault import KeyVaultId def azure_decrypt(config, logger, session, encrypted_field): data = config[encrypted_field] # type: str if type(data) is dict: - kv_session = session.get_session_for_resource(resource=VAULT_AUTH_ENDPOINT) - secret_id = KeyVaultId.parse_secret_id(data['secret']) - kv_client = kv_session.client('azure.keyvault.KeyVaultClient') - return kv_client.get_secret(secret_id.vault, secret_id.name, secret_id.version).value + secret_id = SecretProperties(attributes=None, vault_id=data['secret']) + kv_client = session.client('azure.keyvault.secrets.SecretClient', vault_url=secret_id.vault_url) + return kv_client.get_secret(secret_id.name, secret_id.version).value return data diff --git a/tools/c7n_mailer/tests/test_azure.py b/tools/c7n_mailer/tests/test_azure.py index 97c437dd883..6e5e18f26d6 100644 --- a/tools/c7n_mailer/tests/test_azure.py +++ b/tools/c7n_mailer/tests/test_azure.py @@ -106,7 +106,8 @@ def test_sendgrid_handler_multiple_to_addrs(self, mock_send): def test_azure_mailer_requirements(self): reqs = deploy.get_mailer_requirements() self.assertIn('adal', reqs) - self.assertIn('azure-storage-common', reqs) + self.assertIn('azure-storage-blob', reqs) + self.assertIn('azure-storage-queue', reqs) self.assertIn('azure-common', reqs) self.assertIn('azure-mgmt-managementgroups', reqs) self.assertIn('azure-mgmt-web', reqs) From 470b38fc6f9e718685c5192f6bcc1caefb60e8b2 Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Wed, 17 Mar 2021 00:27:24 -0700 Subject: [PATCH 5/7] Containerhost test --- .../tests_azure/tests_resources/test_container_host.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_container_host.py b/tools/c7n_azure/tests_azure/tests_resources/test_container_host.py index d34c007f9ee..d709e0c5c99 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_container_host.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_container_host.py @@ -630,7 +630,7 @@ def download_missing_mode_policy_blob(_, name, path): def get_mock_blob(name, md5): new_blob = Mock() new_blob.name = name - new_blob.properties.content_settings.content_md5 = md5 + new_blob.content_settings.content_md5 = md5 return new_blob @staticmethod From d3d7dd30a7cfa9e569b5c6452f22abe28757d078 Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Wed, 17 Mar 2021 00:36:46 -0700 Subject: [PATCH 6/7] lint --- tools/c7n_azure/c7n_azure/storage_utils.py | 1 - tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/c7n_azure/c7n_azure/storage_utils.py b/tools/c7n_azure/c7n_azure/storage_utils.py index ef4b3f530fb..b08185caab0 100644 --- a/tools/c7n_azure/c7n_azure/storage_utils.py +++ b/tools/c7n_azure/c7n_azure/storage_utils.py @@ -38,7 +38,6 @@ def list_blobs(self, container_name): return client.list_blobs() - class OldQueueService: def __init__(self, account_url, credential): diff --git a/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py b/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py index 568f02fee1c..f5255a9ffe2 100644 --- a/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py +++ b/tools/c7n_mailer/c7n_mailer/azure_mailer/utils.py @@ -2,14 +2,14 @@ # SPDX-License-Identifier: Apache-2.0 from azure.keyvault.secrets import SecretProperties -from c7n_azure.constants import VAULT_AUTH_ENDPOINT def azure_decrypt(config, logger, session, encrypted_field): data = config[encrypted_field] # type: str if type(data) is dict: secret_id = SecretProperties(attributes=None, vault_id=data['secret']) - kv_client = session.client('azure.keyvault.secrets.SecretClient', vault_url=secret_id.vault_url) + kv_client = session.client('azure.keyvault.secrets.SecretClient', + vault_url=secret_id.vault_url) return kv_client.get_secret(secret_id.name, secret_id.version).value return data From 5d338e8babb1e1978cbdfcf1e7d7580254517f8e Mon Sep 17 00:00:00 2001 From: Kirill Logachev Date: Wed, 17 Mar 2021 09:22:23 -0700 Subject: [PATCH 7/7] [Azure SDK integration branch PR] Lint changes (#6540) --- tools/c7n_azure/c7n_azure/actions/delete.py | 5 +- tools/c7n_azure/c7n_azure/azure_events.py | 3 +- tools/c7n_azure/c7n_azure/filters.py | 5 +- .../c7n_azure/provisioning/function_app.py | 5 +- .../c7n_azure/resources/cosmos_db.py | 1 - .../c7n_azure/resources/key_vault.py | 16 +- .../c7n_azure/resources/network_interface.py | 3 +- .../c7n_azure/c7n_azure/resources/storage.py | 6 +- tools/c7n_azure/c7n_azure/session.py | 17 +- tools/c7n_azure/c7n_azure/storage_utils.py | 17 +- tools/c7n_azure/c7n_azure/utils.py | 7 +- tools/c7n_azure/poetry.lock | 334 ++---------------- tools/c7n_azure/pyproject.toml | 2 +- tools/c7n_azure/requirements.txt | 41 +-- tools/c7n_azure/setup.py | 2 +- tools/c7n_azure/tests_azure/azure_common.py | 11 +- ...workSecurityGroupTest.test_open_ports.json | 3 +- .../c7n_azure/tests_azure/test_azure_utils.py | 1 + tools/c7n_azure/tests_azure/test_session.py | 19 +- .../tests_azure/test_storageutils.py | 7 +- .../tests_resources/test_cosmos_db.py | 25 +- .../test_event_subscriptions.py | 3 +- .../test_networksecuritygroup.py | 5 +- .../tests_resources/test_storage.py | 15 +- tox.ini | 1 + 25 files changed, 120 insertions(+), 434 deletions(-) diff --git a/tools/c7n_azure/c7n_azure/actions/delete.py b/tools/c7n_azure/c7n_azure/actions/delete.py index ac89482cb49..e1977c64938 100644 --- a/tools/c7n_azure/c7n_azure/actions/delete.py +++ b/tools/c7n_azure/c7n_azure/actions/delete.py @@ -64,6 +64,7 @@ def _process_resource(self, resource): if is_resource_group(resource): self.client.resource_groups.delete(resource['name']) else: - self.client.resources.begin_delete_by_id(resource['id'], - self.session.resource_api_version(resource['id'])) + self.client.resources.begin_delete_by_id( + resource['id'], + self.session.resource_api_version(resource['id'])) return "deleted" diff --git a/tools/c7n_azure/c7n_azure/azure_events.py b/tools/c7n_azure/c7n_azure/azure_events.py index e4af7e9aa0e..b40d4ad530b 100644 --- a/tools/c7n_azure/c7n_azure/azure_events.py +++ b/tools/c7n_azure/c7n_azure/azure_events.py @@ -139,5 +139,6 @@ def create(destination, name, subscription_id, session=None, event_filter=None): scope = '/subscriptions/%s' % subscription_id client = s.client('azure.mgmt.eventgrid.EventGridManagementClient') - event_subscription = client.event_subscriptions.begin_create_or_update(scope, name, event_info) + event_subscription = \ + client.event_subscriptions.begin_create_or_update(scope, name, event_info) return event_subscription.result() diff --git a/tools/c7n_azure/c7n_azure/filters.py b/tools/c7n_azure/c7n_azure/filters.py index e542bfa2db5..ea9484b2f74 100644 --- a/tools/c7n_azure/c7n_azure/filters.py +++ b/tools/c7n_azure/c7n_azure/filters.py @@ -947,7 +947,10 @@ def _query_costs(self): timeframe = 'Custom' time_period = QueryTimePeriod(from_property=start_time, to=end_time) - definition = QueryDefinition(type='ActualCost', timeframe=timeframe, time_period=time_period, dataset=dataset) + definition = QueryDefinition(type='ActualCost', + timeframe=timeframe, + time_period=time_period, + dataset=dataset) subscription_id = manager.get_session().get_subscription_id() diff --git a/tools/c7n_azure/c7n_azure/provisioning/function_app.py b/tools/c7n_azure/c7n_azure/provisioning/function_app.py index 48ceb499f83..54cdfd9e15d 100644 --- a/tools/c7n_azure/c7n_azure/provisioning/function_app.py +++ b/tools/c7n_azure/c7n_azure/provisioning/function_app.py @@ -4,8 +4,7 @@ from azure.mgmt.web.models import ( Site, SiteConfig, - ManagedServiceIdentity, - Components1Jq1T4ISchemasManagedserviceidentityPropertiesUserassignedidentitiesAdditionalproperties as UserAssignedIdentity) + ManagedServiceIdentity) from c7n_azure.constants import (AUTH_TYPE_EMBED, FUNCTION_DOCKER_VERSION, FUNCTION_EXT_VERSION) from c7n_azure.provisioning.deployment_unit import DeploymentUnit @@ -31,7 +30,7 @@ def _get_identity(self, params): identity = ManagedServiceIdentity(type=params['identity']['type']) if 'id' in params['identity']: identity.user_assigned_identities = { - params['identity']['id']: UserAssignedIdentity()} + params['identity']['id']: {}} return identity def _provision(self, params): diff --git a/tools/c7n_azure/c7n_azure/resources/cosmos_db.py b/tools/c7n_azure/c7n_azure/resources/cosmos_db.py index 6908915df4e..c156b29b8e0 100644 --- a/tools/c7n_azure/c7n_azure/resources/cosmos_db.py +++ b/tools/c7n_azure/c7n_azure/resources/cosmos_db.py @@ -101,7 +101,6 @@ def _query_rules(self, resource): return resource_rules - @CosmosDB.filter_registry.register('firewall-bypass') class CosmosFirewallBypassFilter(FirewallBypassFilter): """ diff --git a/tools/c7n_azure/c7n_azure/resources/key_vault.py b/tools/c7n_azure/c7n_azure/resources/key_vault.py index 245aaddf178..c81271f00e1 100644 --- a/tools/c7n_azure/c7n_azure/resources/key_vault.py +++ b/tools/c7n_azure/c7n_azure/resources/key_vault.py @@ -1,21 +1,17 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 -from azure.graphrbac import GraphRbacManagementClient +import logging + +from c7n.filters import Filter +from c7n.utils import type_schema from c7n_azure.actions.base import AzureBaseAction from c7n_azure.constants import GRAPH_AUTH_ENDPOINT -from c7n_azure.filters import FirewallRulesFilter, FirewallBypassFilter +from c7n_azure.filters import FirewallBypassFilter, FirewallRulesFilter from c7n_azure.provider import resources +from c7n_azure.resources.arm import ArmResourceManager from c7n_azure.session import Session - -from c7n.filters import Filter -from c7n.utils import type_schema from c7n_azure.utils import GraphHelper - -from c7n_azure.resources.arm import ArmResourceManager - -import logging - from netaddr import IPSet log = logging.getLogger('custodian.azure.keyvault') diff --git a/tools/c7n_azure/c7n_azure/resources/network_interface.py b/tools/c7n_azure/c7n_azure/resources/network_interface.py index f7c6b4f9aba..3b43b1a3d65 100644 --- a/tools/c7n_azure/c7n_azure/resources/network_interface.py +++ b/tools/c7n_azure/c7n_azure/resources/network_interface.py @@ -90,9 +90,10 @@ def _process_resource_set(self, resources, event): for resource in resources: try: if 'routes' not in resource: + rg = resource['resourceGroup'] route_table = ( client.network_interfaces - .begin_get_effective_route_table(resource['resourceGroup'], resource['name']) + .begin_get_effective_route_table(rg, resource['name']) .result() ) diff --git a/tools/c7n_azure/c7n_azure/resources/storage.py b/tools/c7n_azure/c7n_azure/resources/storage.py index 2569bac1ceb..02bcf6f9a33 100644 --- a/tools/c7n_azure/c7n_azure/resources/storage.py +++ b/tools/c7n_azure/c7n_azure/resources/storage.py @@ -434,8 +434,8 @@ def _process_resource(self, resource, event=None): 'read': self.READ in self.logs_to_enable, 'write': self.WRITE in self.logs_to_enable, 'retention_policy': { - 'enabled':self.retention != 0, - 'days': self.retention if self.retention != 0 else None # Throws if 0 + 'enabled': self.retention != 0, + 'days': self.retention if self.retention != 0 else None # Throws if 0 }, 'version': '1.0'} else: @@ -492,7 +492,7 @@ def _get_queue_client_from_storage_account(storage_account, session): @staticmethod def _get_client(storage_type, storage_account, session=None): client = getattr(StorageSettingsUtilities, '_get_{}_client_from_storage_account' - .format(storage_type))(storage_account, session) + .format(storage_type))(storage_account, session) return client @staticmethod diff --git a/tools/c7n_azure/c7n_azure/session.py b/tools/c7n_azure/c7n_azure/session.py index 67647c1a863..0333fd36aa8 100644 --- a/tools/c7n_azure/c7n_azure/session.py +++ b/tools/c7n_azure/c7n_azure/session.py @@ -9,11 +9,9 @@ import sys import types -import jwt from azure.common.credentials import BasicTokenAuthentication from azure.core.credentials import AccessToken -from azure.identity import (AzureCliCredential, ChainedTokenCredential, - ClientSecretCredential, CredentialUnavailableError, +from azure.identity import (AzureCliCredential, ClientSecretCredential, ManagedIdentityCredential) from azure.identity._credentials.azure_cli import _run_command from msrestazure.azure_cloud import AZURE_PUBLIC_CLOUD @@ -27,13 +25,6 @@ get_keyvault_auth_endpoint, get_keyvault_secret, log_response_data) -try: - from azure.cli.core._profile import Profile - from knack.util import CLIError -except Exception: - Profile = None - CLIError = ImportError # Assign an exception that never happens because of Auth problems - from functools import lru_cache log = logging.getLogger('custodian.azure.session') @@ -81,14 +72,14 @@ def __init__(self, cloud_endpoints, authorization_file=None, subscription_id_ove 'from Key Vault with client id: {0}'.format(keyvault_client_id) raise - self._credential = None # type: TokenCredential + self._credential = None self._subscription_id = self._auth_params['subscription_id'] if self._auth_params.get('access_token') is not None: pass elif (self._auth_params['client_id'] and self._auth_params['client_secret'] and self._auth_params['tenant_id'] - ): + ): self._credential = ClientSecretCredential( client_id=self._auth_params['client_id'], client_secret=self._auth_params['client_secret'], @@ -105,8 +96,6 @@ def __init__(self, cloud_endpoints, authorization_file=None, subscription_id_ove raise Exception('Unable to query SubscriptionId') def get_token(self, *scopes, **kwargs): - # type: (*str, **Any) -> AccessToken - # Access Token is used only in tests realistically because # KeyVault, Storage and mgmt plane requires separate tokens. # TODO: Should we scope this to tests only? diff --git a/tools/c7n_azure/c7n_azure/storage_utils.py b/tools/c7n_azure/c7n_azure/storage_utils.py index bca286b0641..269664e9e34 100644 --- a/tools/c7n_azure/c7n_azure/storage_utils.py +++ b/tools/c7n_azure/c7n_azure/storage_utils.py @@ -1,17 +1,12 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 from collections import namedtuple -from functools import lru_cache, wraps +from functools import lru_cache from urllib.parse import urlparse -from azure.common import AzureHttpError from azure.core.exceptions import ResourceExistsError from azure.storage.blob import BlobServiceClient -from azure.storage.common import TokenCredential from azure.storage.queue import QueueClient -from types import MethodType - -from c7n_azure.constants import STORAGE_AUTH_ENDPOINT class OldBlobServiceClient(BlobServiceClient): @@ -47,7 +42,7 @@ def create_queue(self, queue_name): except ResourceExistsError: # Queue already exists pass - except: + except Exception: return False return True @@ -55,7 +50,7 @@ def delete_queue(self, queue_name): queue_service = self._get_service(queue_name) try: queue_service.delete_queue() - except: + except Exception: return False return True @@ -132,12 +127,14 @@ def get_queue_client_by_storage_account(storage_account, session): @staticmethod def create_queue_from_storage_account(storage_account, name, session): - queue_service = StorageUtilities.get_queue_client_by_storage_account(storage_account, session) + queue_service = \ + StorageUtilities.get_queue_client_by_storage_account(storage_account, session) return queue_service.create_queue(name) @staticmethod def delete_queue_from_storage_account(storage_account, name, session): - queue_service = StorageUtilities.get_queue_client_by_storage_account(storage_account, session) + queue_service = \ + StorageUtilities.get_queue_client_by_storage_account(storage_account, session) return queue_service.delete_queue(name) @staticmethod diff --git a/tools/c7n_azure/c7n_azure/utils.py b/tools/c7n_azure/c7n_azure/utils.py index 9e72b70f0ba..3fa5c911c36 100644 --- a/tools/c7n_azure/c7n_azure/utils.py +++ b/tools/c7n_azure/c7n_azure/utils.py @@ -12,14 +12,11 @@ import uuid from concurrent.futures import as_completed from functools import lru_cache -from json import JSONEncoder -from azure.core.pipeline.policies import (CustomHookPolicy, RetryMode, - RetryPolicy) +from azure.core.pipeline.policies import RetryMode, RetryPolicy from azure.graphrbac.models import DirectoryObject, GetObjectsParameters from azure.identity import ManagedIdentityCredential from azure.keyvault.secrets import SecretClient, SecretProperties -from azure.mgmt.managementgroups import ManagementGroupsAPI from azure.mgmt.web.models import NameValuePair from c7n.utils import chunks, local_session from msrestazure.azure_exceptions import CloudError @@ -609,6 +606,7 @@ def serialize(item): d[k.strip('_')] = v return d + class C7nRetryPolicy(RetryPolicy): def __init__(self, **kwargs): @@ -637,6 +635,7 @@ def log_response_data(response): if k.startswith('x-ms-ratelimit'): send_logger.info(k + ':' + v) + # This workaround will replace used api-version for costmanagement requests # 2020-06-01 is not supported, but 2019-11-01 is working as expected. def cost_query_override_api_version(request): diff --git a/tools/c7n_azure/poetry.lock b/tools/c7n_azure/poetry.lock index d796c5c212a..b9a6c27c606 100644 --- a/tools/c7n_azure/poetry.lock +++ b/tools/c7n_azure/poetry.lock @@ -50,7 +50,7 @@ zookeeper = ["kazoo"] name = "argcomplete" version = "1.12.2" description = "Bash tab completion for argparse" -category = "main" +category = "dev" optional = false python-versions = "*" @@ -74,51 +74,6 @@ docs = ["furo", "sphinx", "zope.interface"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] -[[package]] -name = "azure-cli-core" -version = "2.20.0" -description = "Microsoft Azure Command-Line Tools Core Module" -category = "main" -optional = false -python-versions = ">=3.6.0" - -[package.dependencies] -adal = ">=1.2.6,<1.3.0" -argcomplete = ">=1.8,<2.0" -azure-cli-telemetry = ">=1.0.0,<1.1.0" -azure-common = ">=1.1,<2.0" -azure-mgmt-core = ">=1.2.0,<2.0.0" -colorama = ">=0.4.1,<0.5.0" -cryptography = ">=3.2,<3.4" -humanfriendly = ">=4.7,<10.0" -jmespath = "*" -knack = "0.8.0rc2" -msal = ">=1.9,<2.0" -msrest = ">=0.5.0" -msrestazure = ">=0.6.3" -paramiko = ">=2.0.8,<3.0.0" -pkginfo = ">=1.5.0.1" -psutil = ">=5.7,<6.0" -PyJWT = "1.7.1" -pyopenssl = ">=17.1.0" -requests = ">=2.22,<3.0" -six = ">=1.12,<2.0" - -[package.extras] -test = ["mock"] - -[[package]] -name = "azure-cli-telemetry" -version = "1.0.6" -description = "Microsoft Azure CLI Telemetry Package" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -applicationinsights = ">=0.11.1,<0.12" -portalocker = ">=1.2,<2.0" - [[package]] name = "azure-common" version = "1.1.26" @@ -808,22 +763,6 @@ azure-core = ">=1.10.0,<2.0.0" cryptography = ">=2.1.4" msrest = ">=0.6.10" -[[package]] -name = "bcrypt" -version = "3.2.0" -description = "Modern password hashing for your software and your servers" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cffi = ">=1.1" -six = ">=1.4.1" - -[package.extras] -tests = ["pytest (>=3.2.1,!=3.3.0)"] -typecheck = ["mypy"] - [[package]] name = "boto3" version = "1.17.24" @@ -908,32 +847,24 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[[package]] -name = "colorama" -version = "0.4.4" -description = "Cross-platform colored terminal text." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - [[package]] name = "cryptography" -version = "3.3.2" +version = "3.4.6" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.6" [package.dependencies] cffi = ">=1.12" -six = ">=1.4.1" [package.extras] docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=3.6.0,!=3.9.0,!=3.9.1,!=3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] name = "distlib" @@ -943,17 +874,6 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "humanfriendly" -version = "9.1" -description = "Human friendly output for text interfaces using Python" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[package.dependencies] -pyreadline = {version = "*", markers = "sys_platform == \"win32\""} - [[package]] name = "idna" version = "2.10" @@ -966,7 +886,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" name = "importlib-metadata" version = "3.7.2" description = "Read metadata from Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.6" @@ -1008,7 +928,7 @@ six = "*" name = "jmespath" version = "0.10.0" description = "JSON Matching Expressions" -category = "main" +category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" @@ -1038,23 +958,6 @@ six = ">=1.11.0" format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] -[[package]] -name = "knack" -version = "0.8.0rc2" -description = "A Command-Line Interface framework" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -argcomplete = "*" -colorama = "*" -jmespath = "*" -pygments = "*" -pyyaml = "*" -six = "*" -tabulate = "*" - [[package]] name = "msal" version = "1.10.0" @@ -1156,36 +1059,6 @@ python-versions = "*" [package.extras] dev = ["jinja2"] -[[package]] -name = "paramiko" -version = "2.7.2" -description = "SSH2 protocol library" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -bcrypt = ">=3.1.3" -cryptography = ">=2.5" -pynacl = ">=1.0.1" - -[package.extras] -all = ["pyasn1 (>=0.1.7)", "pynacl (>=1.0.1)", "bcrypt (>=3.1.3)", "invoke (>=1.3)", "gssapi (>=1.4.1)", "pywin32 (>=2.1.8)"] -ed25519 = ["pynacl (>=1.0.1)", "bcrypt (>=3.1.3)"] -gssapi = ["pyasn1 (>=0.1.7)", "gssapi (>=1.4.1)", "pywin32 (>=2.1.8)"] -invoke = ["invoke (>=1.3)"] - -[[package]] -name = "pkginfo" -version = "1.7.0" -description = "Query metadatdata from sdists / bdists / installed packages." -category = "main" -optional = false -python-versions = "*" - -[package.extras] -testing = ["nose", "coverage"] - [[package]] name = "portalocker" version = "1.7.1" @@ -1201,17 +1074,6 @@ pywin32 = {version = "!=226", markers = "platform_system == \"Windows\""} docs = ["sphinx (>=1.7.1)"] tests = ["pytest (>=4.6.9)", "pytest-cov (>=2.8.1)", "sphinx (>=1.8.5)", "pytest-flake8 (>=1.0.5)"] -[[package]] -name = "psutil" -version = "5.8.0" -description = "Cross-platform lib for process and system monitoring in Python." -category = "main" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.extras] -test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] - [[package]] name = "pycparser" version = "2.20" @@ -1220,14 +1082,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[[package]] -name = "pygments" -version = "2.8.1" -description = "Pygments is a syntax highlighting package written in Python." -category = "main" -optional = false -python-versions = ">=3.5" - [[package]] name = "pyjwt" version = "1.7.1" @@ -1244,46 +1098,6 @@ crypto = ["cryptography (>=1.4)"] flake8 = ["flake8", "flake8-import-order", "pep8-naming"] test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"] -[[package]] -name = "pynacl" -version = "1.4.0" -description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -cffi = ">=1.4.1" -six = "*" - -[package.extras] -docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] -tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] - -[[package]] -name = "pyopenssl" -version = "20.0.1" -description = "Python wrapper module around the OpenSSL library" -category = "main" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" - -[package.dependencies] -cryptography = ">=3.2" -six = ">=1.5.2" - -[package.extras] -docs = ["sphinx", "sphinx-rtd-theme"] -test = ["flaky", "pretend", "pytest (>=3.0.1)"] - -[[package]] -name = "pyreadline" -version = "2.1" -description = "A python implmementation of GNU readline." -category = "main" -optional = false -python-versions = "*" - [[package]] name = "pyrsistent" version = "0.17.3" @@ -1323,7 +1137,7 @@ python-versions = "*" name = "pyyaml" version = "5.4.1" description = "YAML parser and emitter for Python" -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" @@ -1383,7 +1197,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" name = "tabulate" version = "0.8.9" description = "Pretty-print tabular data" -category = "main" +category = "dev" optional = false python-versions = "*" @@ -1394,7 +1208,7 @@ widechars = ["wcwidth"] name = "typing-extensions" version = "3.7.4.3" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "main" +category = "dev" optional = false python-versions = "*" @@ -1483,7 +1297,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "d2766fed3bf661fca2771fa2cebcc933d4015ac6478f62c853dacb02ba473202" +content-hash = "9ac507c9c0fa482c21c2e91c688c027ac9585328dd369157412a3b9dc0cacf29" [metadata.files] adal = [ @@ -1506,14 +1320,6 @@ attrs = [ {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] -azure-cli-core = [ - {file = "azure-cli-core-2.20.0.tar.gz", hash = "sha256:a23bc53d222a3c76e3de5299c1d3c27d8d005926b9d44b0c98722cbdc30505ab"}, - {file = "azure_cli_core-2.20.0-py3-none-any.whl", hash = "sha256:e11f9edba62905623d54a75388afd8d21eeeb31a8aec22197abd24337ff5fa75"}, -] -azure-cli-telemetry = [ - {file = "azure-cli-telemetry-1.0.6.tar.gz", hash = "sha256:fc6cadf59f14f3bbd6c01d1b4d6ad54cfc1456303510d8bdb6206db08c40e661"}, - {file = "azure_cli_telemetry-1.0.6-py3-none-any.whl", hash = "sha256:05c11939b8ed9a98b8bad1d0201909ff7c33671aaa4a98932069594e815aefbe"}, -] azure-common = [ {file = "azure-common-1.1.26.zip", hash = "sha256:b2866238aea5d7492cfb0282fc8b8d5f6d06fb433872345864d45753c10b6e4f"}, {file = "azure_common-1.1.26-py2.py3-none-any.whl", hash = "sha256:acd26b2adb3ea192d766b4f083805287da080adc7f316ce7e52ef0ea917fbe31"}, @@ -1731,15 +1537,6 @@ azure-storage-queue = [ {file = "azure-storage-queue-12.1.5.zip", hash = "sha256:f0f2f4064120c05a0b594cb504321b523cefd47329a047dd885bb30978100180"}, {file = "azure_storage_queue-12.1.5-py2.py3-none-any.whl", hash = "sha256:038b3a0e4494e34a0a60a7bf9f98a77df65ed768b1db3c60e6ac2727ceb33469"}, ] -bcrypt = [ - {file = "bcrypt-3.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6"}, - {file = "bcrypt-3.2.0-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7"}, - {file = "bcrypt-3.2.0-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1"}, - {file = "bcrypt-3.2.0-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d"}, - {file = "bcrypt-3.2.0-cp36-abi3-win32.whl", hash = "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55"}, - {file = "bcrypt-3.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34"}, - {file = "bcrypt-3.2.0.tar.gz", hash = "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"}, -] boto3 = [ {file = "boto3-1.17.24-py2.py3-none-any.whl", hash = "sha256:7d1f30022f7e28e0907ea521dc84b04506f83cc6afc7c63225153bf3a35cf1b6"}, {file = "boto3-1.17.24.tar.gz", hash = "sha256:bf4a321da7dbe0c5a20380ff9f6a8a4e2e135e72a40348890122a197368b4421"}, @@ -1800,34 +1597,24 @@ click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, ] -colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, -] cryptography = [ - {file = "cryptography-3.3.2-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:541dd758ad49b45920dda3b5b48c968f8b2533d8981bcdb43002798d8f7a89ed"}, - {file = "cryptography-3.3.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:49570438e60f19243e7e0d504527dd5fe9b4b967b5a1ff21cc12b57602dd85d3"}, - {file = "cryptography-3.3.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a4ac9648d39ce71c2f63fe7dc6db144b9fa567ddfc48b9fde1b54483d26042"}, - {file = "cryptography-3.3.2-cp27-cp27m-win32.whl", hash = "sha256:aa4969f24d536ae2268c902b2c3d62ab464b5a66bcb247630d208a79a8098e9b"}, - {file = "cryptography-3.3.2-cp27-cp27m-win_amd64.whl", hash = "sha256:1bd0ccb0a1ed775cd7e2144fe46df9dc03eefd722bbcf587b3e0616ea4a81eff"}, - {file = "cryptography-3.3.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e18e6ab84dfb0ab997faf8cca25a86ff15dfea4027b986322026cc99e0a892da"}, - {file = "cryptography-3.3.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:c7390f9b2119b2b43160abb34f63277a638504ef8df99f11cb52c1fda66a2e6f"}, - {file = "cryptography-3.3.2-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:0d7b69674b738068fa6ffade5c962ecd14969690585aaca0a1b1fc9058938a72"}, - {file = "cryptography-3.3.2-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:922f9602d67c15ade470c11d616f2b2364950602e370c76f0c94c94ae672742e"}, - {file = "cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:a0f0b96c572fc9f25c3f4ddbf4688b9b38c69836713fb255f4a2715d93cbaf44"}, - {file = "cryptography-3.3.2-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:a777c096a49d80f9d2979695b835b0f9c9edab73b59e4ceb51f19724dda887ed"}, - {file = "cryptography-3.3.2-cp36-abi3-win32.whl", hash = "sha256:3c284fc1e504e88e51c428db9c9274f2da9f73fdf5d7e13a36b8ecb039af6e6c"}, - {file = "cryptography-3.3.2-cp36-abi3-win_amd64.whl", hash = "sha256:7951a966613c4211b6612b0352f5bf29989955ee592c4a885d8c7d0f830d0433"}, - {file = "cryptography-3.3.2.tar.gz", hash = "sha256:5a60d3780149e13b7a6ff7ad6526b38846354d11a15e21068e57073e29e19bed"}, + {file = "cryptography-3.4.6-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799"}, + {file = "cryptography-3.4.6-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7"}, + {file = "cryptography-3.4.6-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3"}, + {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b"}, + {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964"}, + {file = "cryptography-3.4.6-cp36-abi3-win32.whl", hash = "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2"}, + {file = "cryptography-3.4.6-cp36-abi3-win_amd64.whl", hash = "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0"}, + {file = "cryptography-3.4.6-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b"}, + {file = "cryptography-3.4.6-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df"}, + {file = "cryptography-3.4.6-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336"}, + {file = "cryptography-3.4.6-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724"}, + {file = "cryptography-3.4.6.tar.gz", hash = "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87"}, ] distlib = [ {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, ] -humanfriendly = [ - {file = "humanfriendly-9.1-py2.py3-none-any.whl", hash = "sha256:d5c731705114b9ad673754f3317d9fa4c23212f36b29bdc4272a892eafc9bc72"}, - {file = "humanfriendly-9.1.tar.gz", hash = "sha256:066562956639ab21ff2676d1fda0b5987e985c534fc76700a19bd54bcb81121d"}, -] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, @@ -1856,10 +1643,6 @@ jsonschema = [ {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, ] -knack = [ - {file = "knack-0.8.0rc2-py3-none-any.whl", hash = "sha256:d43aa9c3744623d266003be8f54b2b88d950ba4c7a457cbbfc4fdc55b5043181"}, - {file = "knack-0.8.0rc2.tar.gz", hash = "sha256:e29ce0570395713e54b236f21a4137d316ac84c012533a107b63861d29cae5da"}, -] msal = [ {file = "msal-1.10.0-py2.py3-none-any.whl", hash = "sha256:daffb9d21fb45b36419182735fa12a4f9d4071b427188aa114162bd623edd812"}, {file = "msal-1.10.0.tar.gz", hash = "sha256:582e92e3b9fa68084dca6ecfd8db866ddc75cd9043de267c79d6b6277dd27f55"}, @@ -1927,89 +1710,18 @@ parameterized = [ {file = "parameterized-0.7.5-py2.py3-none-any.whl", hash = "sha256:b36f709fcfd9e8c144c1374b16a40fc0b5984efe93e41d53e6d228ae2a1540c5"}, {file = "parameterized-0.7.5.tar.gz", hash = "sha256:b5e6af67b9e49485e30125b1c8f031ffa81a265ca08bfa73f31551bf03cf68c4"}, ] -paramiko = [ - {file = "paramiko-2.7.2-py2.py3-none-any.whl", hash = "sha256:4f3e316fef2ac628b05097a637af35685183111d4bc1b5979bd397c2ab7b5898"}, - {file = "paramiko-2.7.2.tar.gz", hash = "sha256:7f36f4ba2c0d81d219f4595e35f70d56cc94f9ac40a6acdf51d6ca210ce65035"}, -] -pkginfo = [ - {file = "pkginfo-1.7.0-py2.py3-none-any.whl", hash = "sha256:9fdbea6495622e022cc72c2e5e1b735218e4ffb2a2a69cde2694a6c1f16afb75"}, - {file = "pkginfo-1.7.0.tar.gz", hash = "sha256:029a70cb45c6171c329dfc890cde0879f8c52d6f3922794796e06f577bb03db4"}, -] portalocker = [ {file = "portalocker-1.7.1-py2.py3-none-any.whl", hash = "sha256:34cb36c618d88bcd9079beb36dcdc1848a3e3d92ac4eac59055bdeafc39f9d4a"}, {file = "portalocker-1.7.1.tar.gz", hash = "sha256:6d6f5de5a3e68c4dd65a98ec1babb26d28ccc5e770e07b672d65d5a35e4b2d8a"}, ] -psutil = [ - {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"}, - {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"}, - {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df"}, - {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131"}, - {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60"}, - {file = "psutil-5.8.0-cp27-none-win32.whl", hash = "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876"}, - {file = "psutil-5.8.0-cp27-none-win_amd64.whl", hash = "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65"}, - {file = "psutil-5.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8"}, - {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6"}, - {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac"}, - {file = "psutil-5.8.0-cp36-cp36m-win32.whl", hash = "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2"}, - {file = "psutil-5.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d"}, - {file = "psutil-5.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935"}, - {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d"}, - {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023"}, - {file = "psutil-5.8.0-cp37-cp37m-win32.whl", hash = "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394"}, - {file = "psutil-5.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"}, - {file = "psutil-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef"}, - {file = "psutil-5.8.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28"}, - {file = "psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b"}, - {file = "psutil-5.8.0-cp38-cp38-win32.whl", hash = "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d"}, - {file = "psutil-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d"}, - {file = "psutil-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7"}, - {file = "psutil-5.8.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4"}, - {file = "psutil-5.8.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b"}, - {file = "psutil-5.8.0-cp39-cp39-win32.whl", hash = "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0"}, - {file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"}, - {file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"}, -] pycparser = [ {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] -pygments = [ - {file = "Pygments-2.8.1-py3-none-any.whl", hash = "sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8"}, - {file = "Pygments-2.8.1.tar.gz", hash = "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94"}, -] pyjwt = [ {file = "PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e"}, {file = "PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"}, ] -pynacl = [ - {file = "PyNaCl-1.4.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff"}, - {file = "PyNaCl-1.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514"}, - {file = "PyNaCl-1.4.0-cp27-cp27m-win32.whl", hash = "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574"}, - {file = "PyNaCl-1.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80"}, - {file = "PyNaCl-1.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7"}, - {file = "PyNaCl-1.4.0-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122"}, - {file = "PyNaCl-1.4.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d"}, - {file = "PyNaCl-1.4.0-cp35-abi3-win32.whl", hash = "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634"}, - {file = "PyNaCl-1.4.0-cp35-abi3-win_amd64.whl", hash = "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6"}, - {file = "PyNaCl-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4"}, - {file = "PyNaCl-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25"}, - {file = "PyNaCl-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4"}, - {file = "PyNaCl-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6"}, - {file = "PyNaCl-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f"}, - {file = "PyNaCl-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f"}, - {file = "PyNaCl-1.4.0-cp38-cp38-win32.whl", hash = "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96"}, - {file = "PyNaCl-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420"}, - {file = "PyNaCl-1.4.0.tar.gz", hash = "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505"}, -] -pyopenssl = [ - {file = "pyOpenSSL-20.0.1-py2.py3-none-any.whl", hash = "sha256:818ae18e06922c066f777a33f1fca45786d85edfe71cd043de6379337a7f274b"}, - {file = "pyOpenSSL-20.0.1.tar.gz", hash = "sha256:4c231c759543ba02560fcd2480c48dcec4dae34c9da7d3747c508227e0624b51"}, -] -pyreadline = [ - {file = "pyreadline-2.1.win-amd64.exe", hash = "sha256:9ce5fa65b8992dfa373bddc5b6e0864ead8f291c94fbfec05fbd5c836162e67b"}, - {file = "pyreadline-2.1.win32.exe", hash = "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e"}, - {file = "pyreadline-2.1.zip", hash = "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1"}, -] pyrsistent = [ {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"}, ] diff --git a/tools/c7n_azure/pyproject.toml b/tools/c7n_azure/pyproject.toml index 051bc598809..52207d4f371 100644 --- a/tools/c7n_azure/pyproject.toml +++ b/tools/c7n_azure/pyproject.toml @@ -57,7 +57,6 @@ distlib = "^0.3.0" jsonpickle = "1.3" requests = "^2.22.0" PyJWT = "^1.7.1" -azure-cli-core = "^2.20.0" adal = "^1.2.6" @@ -76,6 +75,7 @@ azure-keyvault-certificates = "^4.2.1" azure-identity = "^1.5.0" azure-keyvault = "^4.1.0" azure-storage-file-share = "^12.4.1" +cryptography = "^3.4.6" [tool.poetry.dev-dependencies] # setup custodian as a dev dependency diff --git a/tools/c7n_azure/requirements.txt b/tools/c7n_azure/requirements.txt index a5f896943fa..a0a496d1b3d 100644 --- a/tools/c7n_azure/requirements.txt +++ b/tools/c7n_azure/requirements.txt @@ -1,10 +1,7 @@ adal==1.2.6 applicationinsights==0.11.9 apscheduler==3.7.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") -argcomplete==1.12.2; python_full_version >= "3.6.0" -azure-cli-core==2.20.0; python_full_version >= "3.6.0" -azure-cli-telemetry==1.0.6; python_full_version >= "3.6.0" -azure-common==1.1.26; python_full_version >= "3.6.0" +azure-common==1.1.26 azure-core==1.12.0 azure-cosmos==3.2.0 azure-cosmosdb-nspkg==2.0.2 @@ -26,7 +23,7 @@ azure-mgmt-compute==19.0.0 azure-mgmt-containerinstance==7.0.0 azure-mgmt-containerregistry==8.0.0b1 azure-mgmt-containerservice==15.0.0 -azure-mgmt-core==1.2.2; python_full_version >= "3.6.0" +azure-mgmt-core==1.2.2 azure-mgmt-cosmosdb==6.1.0 azure-mgmt-costmanagement==1.0.0 azure-mgmt-databricks==1.0.0b1 @@ -58,47 +55,31 @@ azure-storage-common==2.1.0 azure-storage-file-share==12.4.1 azure-storage-file==2.1.0 azure-storage-queue==12.1.5 -bcrypt==3.2.0; python_version >= "3.6" and python_full_version >= "3.6.0" certifi==2020.12.5; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" -cffi==1.14.5; python_version >= "3.6" and python_full_version >= "3.6.0" +cffi==1.14.5; python_version >= "3.6" chardet==4.0.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" click==7.1.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") -colorama==0.4.4; python_full_version >= "3.6.0" -cryptography==3.3.2; python_full_version >= "3.6.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") +cryptography==3.4.6; python_version >= "3.6" distlib==0.3.1 -humanfriendly==9.1; python_full_version >= "3.6.0" idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" -importlib-metadata==3.7.2; python_version == "3.6" and python_full_version >= "3.6.0" or python_version == "3.7" and python_full_version >= "3.6.0" importlib-resources==5.1.2; python_version >= "3.6" and python_version < "3.7" isodate==0.6.0 -jmespath==0.10.0; python_full_version >= "3.6.0" jsonpickle==1.3 -knack==0.8.0rc2; python_full_version >= "3.6.0" msal-extensions==0.3.0 -msal==1.10.0; python_full_version >= "3.6.0" -msrest==0.6.21; python_full_version >= "3.6.0" -msrestazure==0.6.4; python_full_version >= "3.6.0" +msal==1.10.0 +msrest==0.6.21 +msrestazure==0.6.4 netaddr==0.7.20 oauthlib==3.1.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" -paramiko==2.7.2; python_full_version >= "3.6.0" -pkginfo==1.7.0; python_full_version >= "3.6.0" portalocker==1.7.1 -psutil==5.8.0; python_full_version >= "3.6.0" -pycparser==2.20; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" -pygments==2.8.1; python_version >= "3.5" and python_full_version >= "3.6.0" +pycparser==2.20; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" pyjwt==1.7.1 -pynacl==1.4.0; python_full_version >= "3.6.0" -pyopenssl==20.0.1; python_full_version >= "3.6.0" -pyreadline==2.1; sys_platform == "win32" and python_full_version >= "3.6.0" -python-dateutil==2.8.1; python_full_version >= "3.6.0" +python-dateutil==2.8.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" pytz==2021.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" pywin32==300; platform_system == "Windows" and python_full_version >= "3.6.0" -pyyaml==5.4.1; python_full_version >= "3.6.0" requests-oauthlib==1.3.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" requests==2.25.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") -six==1.15.0; python_full_version >= "3.6.0" and python_version < "4" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and python_version >= "3.6" -tabulate==0.8.9; python_full_version >= "3.6.0" -typing-extensions==3.7.4.3; python_version == "3.6" and python_full_version >= "3.6.0" or python_version == "3.7" and python_full_version >= "3.6.0" +six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" tzlocal==2.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" urllib3==1.26.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" -zipp==3.4.1; python_version >= "3.6" and python_version < "3.7" and (python_version == "3.6" and python_full_version >= "3.6.0" or python_version == "3.7" and python_full_version >= "3.6.0") +zipp==3.4.1; python_version >= "3.6" and python_version < "3.7" diff --git a/tools/c7n_azure/setup.py b/tools/c7n_azure/setup.py index eebad1cb49b..a54e29d8727 100644 --- a/tools/c7n_azure/setup.py +++ b/tools/c7n_azure/setup.py @@ -20,7 +20,6 @@ 'apscheduler>=3.6.3,<4.0.0', 'argcomplete (>=1.12.2,<2.0.0)', 'attrs (>=20.3.0,<21.0.0)', - 'azure-cli-core>=2.20.0,<3.0.0', 'azure-cosmos>=3.1.2,<4.0.0', 'azure-cosmosdb-table>=1.0.6,<2.0.0', 'azure-graphrbac>=0.61.1,<0.62.0', @@ -72,6 +71,7 @@ 'botocore (>=1.20.24,<2.0.0)', 'c7n (>=0.9.11,<0.10.0)', 'click>=7.0,<8.0', + 'cryptography>=3.4.6,<4.0.0', 'distlib>=0.3.0,<0.4.0', 'importlib-metadata (>=3.7.2,<4.0.0)', 'jmespath (>=0.10.0,<0.11.0)', diff --git a/tools/c7n_azure/tests_azure/azure_common.py b/tools/c7n_azure/tests_azure/azure_common.py index 710c6c70745..d7448f03c10 100644 --- a/tools/c7n_azure/tests_azure/azure_common.py +++ b/tools/c7n_azure/tests_azure/azure_common.py @@ -190,8 +190,8 @@ def _get_vcr(self, **kwargs): def _azure_matcher(self, r1, r2): """Replace all subscription ID's and ignore api-version""" - if [(k[0].lower(), k[1].lower()) for k in set(r1.query) if k[0] != 'api-version'] != [ - (k[0].lower(), k[1].lower()) for k in set(r2.query) if k[0] != 'api-version']: + if [(k[0].lower(), k[1].lower()) for k in set(r1.query) if k[0] != 'api-version'] != \ + [(k[0].lower(), k[1].lower()) for k in set(r2.query) if k[0] != 'api-version']: return False r1_path = AzureVCRBaseTest._replace_subscription_id(r1.path) @@ -372,17 +372,10 @@ def __init__(self, *args, **kwargs): @classmethod def setUpClass(cls, *args, **kwargs): super(BaseTest, cls).setUpClass(*args, **kwargs) - if os.environ.get(constants.ENV_ACCESS_TOKEN) == "fake_token": - cls._token_patch = patch( - 'c7n_azure.session.jwt.decode', - return_value={'tid': DEFAULT_TENANT_ID}) - cls._token_patch.start() @classmethod def tearDownClass(cls, *args, **kwargs): super(BaseTest, cls).tearDownClass(*args, **kwargs) - if os.environ.get(constants.ENV_ACCESS_TOKEN) == "fake_token": - cls._token_patch.stop() def setUp(self): super(BaseTest, self).setUp() diff --git a/tools/c7n_azure/tests_azure/cassettes/NetworkSecurityGroupTest.test_open_ports.json b/tools/c7n_azure/tests_azure/cassettes/NetworkSecurityGroupTest.test_open_ports.json index 0765b1d4da0..cdd2ce227d0 100644 --- a/tools/c7n_azure/tests_azure/cassettes/NetworkSecurityGroupTest.test_open_ports.json +++ b/tools/c7n_azure/tests_azure/cassettes/NetworkSecurityGroupTest.test_open_ports.json @@ -45,6 +45,7 @@ "provisioningState": "Succeeded", "resourceGuid": "73755b2a-d58b-47db-8deb-76ba8ddbde0f", "securityRules": [ + { "name": "test4", "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_networksecuritygroup/providers/Microsoft.Network/networkSecurityGroups/c7n-nsg/securityRules/test4", "etag": "W/\"95ab7ee9-b501-403a-9d79-b69e24b26900\"", @@ -252,7 +253,7 @@ { "request": { "method": "PUT", - "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_networksecuritygroup/providers/Microsoft.Network/networkSecurityGroups/c7n-nsg/securityRules/c7n-policy-baea42b8-85e7-11eb-b168-00155d1e47af?api-version=2020-08-01", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_networksecuritygroup/providers/Microsoft.Network/networkSecurityGroups/c7n-nsg/securityRules/c7n-policy-00000000-0000-0000-0000-000000000000?api-version=2020-08-01", "body": "mock_body", "headers": {} }, diff --git a/tools/c7n_azure/tests_azure/test_azure_utils.py b/tools/c7n_azure/tests_azure/test_azure_utils.py index 7de4a06d07c..f948f01a81f 100644 --- a/tools/c7n_azure/tests_azure/test_azure_utils.py +++ b/tools/c7n_azure/tests_azure/test_azure_utils.py @@ -35,6 +35,7 @@ GUID = '00000000-0000-0000-0000-000000000000' + def _get_descendant_info(**kwargs): info = DescendantInfo() for k, v in kwargs.items(): diff --git a/tools/c7n_azure/tests_azure/test_session.py b/tools/c7n_azure/tests_azure/test_session.py index 1c24a94b195..4eb7c3c6fde 100644 --- a/tools/c7n_azure/tests_azure/test_session.py +++ b/tools/c7n_azure/tests_azure/test_session.py @@ -8,17 +8,12 @@ import pytest from adal import AdalError -from azure.common.credentials import (BasicTokenAuthentication, - ServicePrincipalCredentials) from azure.core.credentials import AccessToken -from azure.identity import (AzureCliCredential, ChainedTokenCredential, - ClientSecretCredential, ManagedIdentityCredential) +from azure.identity import (ClientSecretCredential, ManagedIdentityCredential) from c7n_azure import constants -from c7n_azure.session import AzureCredential, Session -from knack.util import CLIError +from c7n_azure.session import Session from mock import patch from msrest.exceptions import AuthenticationError -from msrestazure.azure_active_directory import MSIAuthentication from msrestazure.azure_cloud import AZURE_CHINA_CLOUD from requests import HTTPError @@ -134,10 +129,11 @@ def test_initialize_msi_auth_user(self): s = Session() self.assertIsInstance(s.get_credentials()._credential, ManagedIdentityCredential) - self.assertEqual(s.get_credentials()._credential._credential._identity_config["client_id"], 'client') + self.assertEqual( + s.get_credentials()._credential._credential._identity_config["client_id"], + 'client') self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID) - @patch('msrestazure.azure_active_directory.MSIAuthentication.__init__') @patch('c7n_azure.session.log.error') def test_initialize_session_msi_authentication_error(self, mock_log, mock_cred): @@ -296,7 +292,8 @@ def test_compare_auth_params(self, _1): }, clear=True): env_params = Session().get_credentials().auth_params - file_params = Session(authorization_file=self.authorization_file_full).get_credentials().auth_params + session = Session(authorization_file=self.authorization_file_full) + file_params = session.get_credentials().auth_params self.assertTrue(env_params.pop('enable_cli_auth')) self.assertFalse(file_params.pop('enable_cli_auth', None)) @@ -361,7 +358,7 @@ def test_get_auth_endpoint_storage(self): @patch('c7n_azure.utils.C7nRetryPolicy.__init__', return_value=None) def test_retry_policy_override(self, c7n_retry): s = Session() - client = s.client('azure.mgmt.compute.ComputeManagementClient') + s.client('azure.mgmt.compute.ComputeManagementClient') c7n_retry.assert_called_once() @patch('c7n_azure.session.log_response_data', return_value=None) diff --git a/tools/c7n_azure/tests_azure/test_storageutils.py b/tools/c7n_azure/tests_azure/test_storageutils.py index ac37f2e7a79..20f9e2ab137 100644 --- a/tools/c7n_azure/tests_azure/test_storageutils.py +++ b/tools/c7n_azure/tests_azure/test_storageutils.py @@ -1,12 +1,9 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 import pytest -from azure.common import AzureHttpError from azure.mgmt.storage.models import StorageAccountListKeysResult, StorageAccountKey -from azure.storage.common import TokenCredential from c7n_azure.session import Session from c7n_azure.storage_utils import StorageUtilities -from c7n_azure.utils import ResourceIdParser from mock import patch from msrestazure.azure_cloud import AZURE_CHINA_CLOUD from c7n.utils import local_session @@ -128,5 +125,7 @@ def test_get_queue_client_by_uri_china_cloud(self, mock_create): Session(cloud_endpoints=AZURE_CHINA_CLOUD)) self.assertIsNotNone(queue_service) self.assertEqual(queue_name, "queuename") - self.assertTrue(CHINA_STORAGE_ENDPOINT in queue_service._get_service(queue_name).primary_endpoint) + self.assertIn( + CHINA_STORAGE_ENDPOINT, + queue_service._get_service(queue_name).primary_endpoint) self.assertTrue(mock_create.called_once()) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_cosmos_db.py b/tools/c7n_azure/tests_azure/tests_resources/test_cosmos_db.py index 6a56fd7b090..08f2f783c56 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_cosmos_db.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_cosmos_db.py @@ -28,6 +28,7 @@ def get_azuredc_ip(): # this means "azure datacenters only" return '0.0.0.0' + def get_ip_rules(ip_str): if ip_str == '': return [] @@ -279,12 +280,14 @@ def test_store_throughput_state_collection_action(self): class CosmosDBFirewallFilterTest(BaseTest): def test_query_firewall_disabled(self): - resource = {'properties': {'ipRules': get_ip_rules(''), 'isVirtualNetworkFilterEnabled': False}} + resource = {'properties': {'ipRules': get_ip_rules(''), + 'isVirtualNetworkFilterEnabled': False}} expected = IPSet(['0.0.0.0/0']) self.assertEqual(expected, self._get_filter()._query_rules(resource)) def test_query_block_everything(self): - resource = {'properties': {'ipRules': get_ip_rules(''), 'isVirtualNetworkFilterEnabled': True}} + resource = {'properties': {'ipRules': get_ip_rules(''), + 'isVirtualNetworkFilterEnabled': True}} expected = IPSet() self.assertEqual(expected, self._get_filter()._query_rules(resource)) @@ -338,7 +341,8 @@ class CosmosDBFirewallBypassFilterTest(BaseTest): [get_ip_rules(','.join(AZURE_CLOUD_IPS + PORTAL_IPS)), False, ['AzureCloud', 'Portal']], [get_ip_rules(','.join(AZURE_CLOUD_IPS + ['10.0.0.8'])), False, ['AzureCloud']], [get_ip_rules(','.join(PORTAL_IPS + ['10.0.0.8'])), False, ['Portal']], - [get_ip_rules(','.join(AZURE_CLOUD_IPS + PORTAL_IPS + ['10.0.0.8'])), False, ['AzureCloud', 'Portal']], + [get_ip_rules(','.join(AZURE_CLOUD_IPS + PORTAL_IPS + ['10.0.0.8'])), False, + ['AzureCloud', 'Portal']], ] @parameterized.expand(scenarios) @@ -380,7 +384,8 @@ def test_set_ip_range_filter_append(self, update_mock): expected = set(['11.12.13.14', '21.22.23.24', get_ext_ip()]) expected.update(get_portal_ips()) - actual = set([ip['ipAddressOrRange'] for ip in kwargs['create_update_parameters']['properties']['ipRules']]) + actual = set([ip['ipAddressOrRange'] + for ip in kwargs['create_update_parameters']['properties']['ipRules']]) self.assertEqual(resources[0]['resourceGroup'], args[0]) self.assertEqual(resources[0]['name'], args[1]) @@ -416,7 +421,8 @@ def test_set_ip_range_filter_replace(self, update_mock): expected = set(['11.12.13.14', '21.22.23.24', ext_ip]) expected.update(get_portal_ips()) - actual = set([ip['ipAddressOrRange'] for ip in kwargs['create_update_parameters']['properties']['ipRules']]) + actual = set([ip['ipAddressOrRange'] + for ip in kwargs['create_update_parameters']['properties']['ipRules']]) self.assertEqual(resources[0]['resourceGroup'], args[0]) self.assertEqual(resources[0]['name'], args[1]) @@ -453,7 +459,8 @@ def test_set_ip_range_filter_replace_bypass(self, update_mock): expected = set(['11.12.13.14', '21.22.23.24', ext_ip, get_azuredc_ip()]) expected.update(get_portal_ips()) - actual = set([ip['ipAddressOrRange'] for ip in kwargs['create_update_parameters']['properties']['ipRules']]) + actual = set([ip['ipAddressOrRange'] + for ip in kwargs['create_update_parameters']['properties']['ipRules']]) self.assertEqual(resources[0]['resourceGroup'], args[0]) self.assertEqual(resources[0]['name'], args[1]) @@ -492,7 +499,8 @@ def test_set_ip_range_filter_remove_bypass(self, update_mock): self.assertEqual(resources[0]['name'], args[1]) expected = set(['21.22.23.24', ext_ip]) - actual = set([ip['ipAddressOrRange'] for ip in kwargs['create_update_parameters']['properties']['ipRules']]) + actual = set([ip['ipAddressOrRange'] + for ip in kwargs['create_update_parameters']['properties']['ipRules']]) self.assertEqual(expected, actual) @@ -525,7 +533,8 @@ def test_set_vnet_append(self, update_mock): expected = set(['11.12.13.14', '21.22.23.24', get_ext_ip()]) expected.update(get_portal_ips()) - actual = set([ip['ipAddressOrRange'] for ip in kwargs['create_update_parameters']['properties']['ipRules']]) + actual = set([ip['ipAddressOrRange'] + for ip in kwargs['create_update_parameters']['properties']['ipRules']]) self.assertEqual(resources[0]['resourceGroup'], args[0]) self.assertEqual(resources[0]['name'], args[1]) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_event_subscriptions.py b/tools/c7n_azure/tests_azure/tests_resources/test_event_subscriptions.py index bbd514a3a53..bc76f0116bf 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_event_subscriptions.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_event_subscriptions.py @@ -3,10 +3,9 @@ from azure.mgmt.eventgrid.models import \ StorageQueueEventSubscriptionDestination from c7n_azure.azure_events import AzureEventSubscription -from c7n_azure.session import Session from c7n_azure.storage_utils import StorageUtilities -from ..azure_common import BaseTest, arm_template, requires_arm_polling +from ..azure_common import BaseTest, arm_template class AzureEventSubscriptionsTest(BaseTest): diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_networksecuritygroup.py b/tools/c7n_azure/tests_azure/tests_resources/test_networksecuritygroup.py index 5c7b29f04f0..38aed93c88e 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_networksecuritygroup.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_networksecuritygroup.py @@ -1,5 +1,7 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +from mock import patch + from ..azure_common import BaseTest, arm_template @@ -168,7 +170,8 @@ def test_egress_policy_protocols(self): self.assertEqual(len(resources), 0) @arm_template('networksecuritygroup.json') - def test_open_ports(self): + @patch('uuid.uuid1', return_value='00000000-0000-0000-0000-000000000000') + def test_open_ports(self, _1): p = self.load_policy({ 'name': 'test-azure-nsg', 'resource': 'azure.networksecuritygroup', diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_storage.py b/tools/c7n_azure/tests_azure/tests_resources/test_storage.py index 57f187c4796..f03d705d90a 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_storage.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_storage.py @@ -362,9 +362,11 @@ def test_enable_log_settings(self): # assert all logging settings are enabled self.assertTrue(blob_settings['analytics_logging'].delete and - blob_settings['analytics_logging'].read and blob_settings['analytics_logging'].write) + blob_settings['analytics_logging'].read and + blob_settings['analytics_logging'].write) self.assertTrue(queue_settings['analytics_logging'].delete and - queue_settings['analytics_logging'].read and queue_settings['analytics_logging'].write) + queue_settings['analytics_logging'].read and + queue_settings['analytics_logging'].write) self.assertTrue(table_settings.logging.delete and table_settings.logging.read and table_settings.logging.write) @@ -412,9 +414,12 @@ def test_disable_log_settings(self): TABLE_TYPE, resources[0], session=session) # assert read and write logging settings are disabled - self.assertFalse(blob_settings['analytics_logging'].read and blob_settings['analytics_logging'].write) - self.assertFalse(queue_settings['analytics_logging'].read and queue_settings['analytics_logging'].write) - self.assertFalse(table_settings.logging.read and table_settings.logging.write) + self.assertFalse(blob_settings['analytics_logging'].read and + blob_settings['analytics_logging'].write) + self.assertFalse(queue_settings['analytics_logging'].read and + queue_settings['analytics_logging'].write) + self.assertFalse(table_settings.logging.read and + table_settings.logging.write) # assert delete logging settings are enabled self.assertTrue(blob_settings['analytics_logging'].delete) diff --git a/tox.ini b/tox.ini index 2769f189485..91c212817f1 100644 --- a/tox.ini +++ b/tox.ini @@ -26,6 +26,7 @@ setenv = C7N_TEST_RUN=true AZURE_ACCESS_TOKEN=fake_token AZURE_SUBSCRIPTION_ID=ea42f556-5106-4743-99b0-c129bfa71a47 + AZURE_TENANT_ID=ea42f556-5106-4743-99b0-000000000000 GOOGLE_CLOUD_PROJECT=custodian-1291 GOOGLE_APPLICATION_CREDENTIALS=tools/c7n_gcp/tests/data/credentials.json