Example #1
0
    def test_add_or_update_single_tag(self):
        """Verifies we can add a new tag to a VM and not modify
        an existing tag on that resource
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tag': 'tag1',
                 'value': 'value1'}
            ],
        })
        p.run()

        # verify that the a new tag is added without modifying existing tags
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(vm.tags, {'tag1': 'value1', 'testtag': 'testvalue'})
    def augment(self, resources):
        s = Session(resource='https://graph.windows.net')
        graph_client = GraphRbacManagementClient(s.get_credentials(), s.get_tenant_id())

        object_ids = list(set(
            resource['properties']['principalId'] for resource in resources
            if resource['properties']['principalId']))

        object_params = GetObjectsParameters(
            include_directory_object_references=True,
            object_ids=object_ids)

        aad_objects = graph_client.objects.get_objects_by_object_ids(object_params)

        try:
            principal_dics = {aad_object.object_id: aad_object for aad_object in aad_objects}

            for resource in resources:
                graph_resource = principal_dics[resource['properties']['principalId']]
                resource['principalName'] = self.get_principal_name(graph_resource)
                resource['displayName'] = graph_resource.display_name
                resource['aadType'] = graph_resource.object_type

        except CloudError:
            log.warning('Credentials not authorized for access to read from Microsoft Graph. \n '
                        'Can not query on principalName, displayName, or aadType. \n'
                        )

        return resources
    def test_get_functions_auth_string_overrides(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: 'ea42f556-5106-4743-99b0-c129bfa71a47',
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret',
                                constants.ENV_FUNCTION_TENANT_ID: 'functiontenant',
                                constants.ENV_FUNCTION_SUB_ID: '000000-5106-4743-99b0-c129bfa71a47',
                                constants.ENV_FUNCTION_CLIENT_ID: 'functionclient',
                                constants.ENV_FUNCTION_CLIENT_SECRET: 'functionsecret'
                            }, clear=True):
                s = Session()

                auth = s.get_functions_auth_string('000000-5106-4743-99b0-c129bfa71a47')

                expected = """{
                               "credentials": {
                                 "client_id": "functionclient",
                                 "secret": "functionsecret",
                                 "tenant": "functiontenant"
                               },
                               "subscription": "000000-5106-4743-99b0-c129bfa71a47"
                             }"""

                self.assertEqual(json.loads(auth), json.loads(expected))
Example #4
0
    def test_auto_tag_add_creator_tag(self, utcnow_mock):
        """Adds CreatorEmail to a resource group
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'auto-tag-user',
                 'tag': 'CreatorEmail'},
            ],
        })
        p.run()

        # verify CreatorEmail tag set
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]
        self.assertTrue(re.match(self.EMAIL_REGEX, rg.tags['CreatorEmail']))
 def test_api_version(self):
     """Verify we retrieve the correct API version for a resource type"""
     s = Session()
     client = s.client('azure.mgmt.resource.ResourceManagementClient')
     resource = next(client.resources.list())
     self.assertTrue(re.match('\\d{4}-\\d{2}-\\d{2}',
                              s.resource_api_version(resource.id)) is not None)
Example #6
0
    def test_tag_trim_does_nothing_if_space_available(self):
        """Verifies tag trim returns without trimming tags
        if the resource has space equal to or greater than
        the space value.
        """

        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        start_tags = vm.tags

        # verify there is at least 1 space for a tag
        self.assertLess(len(start_tags), 15)

        # trim for space for 1 tag
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag-trim',
                 'space': 1}
            ],
        })
        p.run()

        # verify that tags are unchanged
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(vm.tags, start_tags)
Example #7
0
 def setup_account():
     # Find actual name of storage account provisioned in our test environment
     s = Session()
     client = s.client('azure.mgmt.storage.StorageManagementClient')
     accounts = list(client.storage_accounts.list())
     matching_account = [a for a in accounts if a.name.startswith("cctstorage")]
     return matching_account[0]
Example #8
0
    def test_initialize_session_auth_file(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            s = Session(authorization_file=self.authorization_file)

            self.assertIs(type(s.get_credentials()), ServicePrincipalCredentials)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
            self.assertEqual(s.get_tenant_id(), 'tenant')
Example #9
0
    def test_initialize_session_cli(self, mock_run):
        mock_run.return_value = \
            f'{{"id":"{DEFAULT_SUBSCRIPTION_ID}", "tenantId":"{DEFAULT_TENANT_ID}"}}'

        with patch.dict(os.environ, {}, clear=True):
            s = Session()
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
            self.assertEqual(s.get_tenant_id(), DEFAULT_TENANT_ID)
Example #10
0
 def test_get_client_us_gov(self):
     """Verify we are setting the correct credential scope for us government"""
     s = Session(cloud_endpoints=AZURE_US_GOV_CLOUD)
     client = s.client('azure.mgmt.resource.ResourceManagementClient')
     self.assertEqual(AZURE_US_GOV_CLOUD.endpoints.resource_manager,
                      client._client._base_url)
     self.assertEqual(AZURE_US_GOV_CLOUD.endpoints.management + ".default",
                      client._client._config.credential_scopes[0])
Example #11
0
 def test_api_version(self):
     """Verify we retrieve the correct API version for a resource type"""
     s = Session()
     client = s.client('azure.mgmt.resource.ResourceManagementClient')
     resource = next(client.resources.list())
     self.assertTrue(
         re.match('\\d{4}-\\d{2}-\\d{2}', s.resource_api_version(
             resource.id)) is not None)
    def test_initialize_session_auth_file(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            s = Session(authorization_file=self.authorization_file)

            self.assertIs(type(s.get_credentials()), ServicePrincipalCredentials)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
            self.assertEqual(s.get_tenant_id(), 'tenant')
 def test_get_client_overrides(self, mock):
     # Reload the module to re-import patched function
     reload(sys.modules['c7n_azure.session'])
     s = Session()
     client = s.client('azure.mgmt.resource.ResourceManagementClient')
     self.assertFalse(client._client.config.retry_policy.policy.respect_retry_after_header)
     self.assertIsNotNone(client._client.orig_send)
     client._client.send()
     self.assertTrue(mock.called)
 def setup_account():
     # Find actual name of storage account provisioned in our test environment
     s = Session()
     client = s.client('azure.mgmt.storage.StorageManagementClient')
     accounts = list(client.storage_accounts.list())
     matching_account = [
         a for a in accounts if a.name.startswith("cctstorage")
     ]
     return matching_account[0]
Example #15
0
 def test_get_client_overrides(self, mock):
     # Reload the module to re-import patched function
     reload(sys.modules['c7n_azure.session'])
     s = Session()
     client = s.client('azure.mgmt.resource.ResourceManagementClient')
     self.assertFalse(client._client.config.retry_policy.policy.respect_retry_after_header)
     self.assertIsNotNone(client._client.orig_send)
     client._client.send()
     self.assertTrue(mock.called)
Example #16
0
    def test_remove_tags(self):
        """Verifies we can delete multiple tags from a resource
        group without modifying existing tags.
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'pre-existing-1': 'to-keep', 'pre-existing-2': 'to-keep',
                          'added-1': 'to-delete', 'added-2': 'to-delete'}},
            ],
        })
        p.run()

        # verify initial tag set
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]
        start_tags = rg.tags
        self.assertTrue('pre-existing-1' in start_tags)
        self.assertTrue('pre-existing-2' in start_tags)
        self.assertTrue('added-1' in start_tags)
        self.assertTrue('added-2' in start_tags)

        p = self.load_policy({
            'name': 'test-azure-remove-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'untag',
                 'tags': ['added-1', 'added-2']}
            ],
        })
        p.run()

        # verify tags removed and pre-existing tags not removed
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]  # NOQA
        end_tags = rg.tags
        self.assertTrue('pre-existing-1' in end_tags)
        self.assertTrue('pre-existing-2' in end_tags)
        self.assertTrue('added-1' not in end_tags)
        self.assertTrue('added-2' not in end_tags)
Example #17
0
    def test_remove_tags(self):
        """Verifies we can delete multiple tags from a resource
        group without modifying existing tags.
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'pre-existing-1': 'to-keep', 'pre-existing-2': 'to-keep',
                          'added-1': 'to-delete', 'added-2': 'to-delete'}},
            ],
        })
        p.run()

        # verify initial tag set
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]
        start_tags = rg.tags
        self.assertTrue('pre-existing-1' in start_tags)
        self.assertTrue('pre-existing-2' in start_tags)
        self.assertTrue('added-1' in start_tags)
        self.assertTrue('added-2' in start_tags)

        p = self.load_policy({
            'name': 'test-azure-remove-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'untag',
                 'tags': ['added-1', 'added-2']}
            ],
        })
        p.run()

        # verify tags removed and pre-existing tags not removed
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0] # NOQA
        end_tags = rg.tags
        self.assertTrue('pre-existing-1' in end_tags)
        self.assertTrue('pre-existing-2' in end_tags)
        self.assertTrue('added-1' not in end_tags)
        self.assertTrue('added-2' not in end_tags)
Example #18
0
    def test_initialize_msi_auth_system(self):
        with patch.dict(os.environ,
                        {
                            constants.ENV_USE_MSI: 'true',
                            constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
                        }, clear=True):
            s = Session()

            self.assertIsInstance(s.get_credentials()._credential, ManagedIdentityCredential)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
Example #19
0
    def test_initialize_session_token(self, _1):
        with patch.dict(os.environ, {
                constants.ENV_ACCESS_TOKEN: 'token',
                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
        },
                        clear=True):
            s = Session()

            self.assertIs(type(s.get_credentials()), BasicTokenAuthentication)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
Example #20
0
    def test_initialize_session_auth_file_no_sub(self):
        s = Session(subscription_id=CUSTOM_SUBSCRIPTION_ID,
                    authorization_file=self.authorization_file_no_sub)

        self.assertIs(type(s.get_credentials()._credential), ClientSecretCredential)
        self.assertEqual(s.get_subscription_id(), CUSTOM_SUBSCRIPTION_ID)

        # will vary between recorded/live auth options but useful to ensure
        # we ended up with one of the valid values
        self.assertTrue(s.get_tenant_id() in [DEFAULT_TENANT_ID, 'tenant'])
Example #21
0
    def test_remove_single_tag(self):
        """Verifies we can delete a tag to a VM and not modify
        an existing tag on that resource
        """
        p = self.load_policy({
            'name':
            'test-azure-remove-single-tag',
            'resource':
            'azure.vm',
            'filters': [{
                'type': 'value',
                'key': 'name',
                'op': 'eq',
                'value_type': 'normalize',
                'value': 'cctestvm'
            }],
            'actions': [{
                'type': 'tag',
                'tag': 'tag1',
                'value': 'to-delete'
            }],
        })
        p.run()

        # verify the initial tag set
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(vm.tags, {
            'tag1': 'to-delete',
            'testtag': 'testvalue'
        })

        p = self.load_policy({
            'name':
            'test-azure-tag',
            'resource':
            'azure.vm',
            'filters': [{
                'type': 'value',
                'key': 'name',
                'op': 'eq',
                'value_type': 'normalize',
                'value': 'cctestvm'
            }],
            'actions': [{
                'type': 'untag',
                'tags': ['tag1']
            }],
        })
        p.run()

        # verify that the a tag is deleted without modifying existing tags
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(vm.tags, {'testtag': 'testvalue'})
Example #22
0
    def test_tag_trim_space_0_removes_all_tags_but_preserve(self):
        """Verifies tag trim removes all other tags but tags
        listed in preserve
        """

        # Add tags to trim
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'tag-to-trim1': 'value1', 'tag-to-trim2': 'value2',
                          'tag-to-trim3': 'value3'}}
            ],
        })
        p.run()

        # verify initial tags contain more than testtag
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertTrue('tag-to-trim1' in vm.tags)
        self.assertTrue('tag-to-trim2' in vm.tags)
        self.assertTrue('tag-to-trim3' in vm.tags)
        self.assertTrue('testtag' in vm.tags)

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag-trim',
                 'space': 0,
                 'preserve': ['testtag']
                 }
            ],
        })
        p.run()

        # verify all tags trimmed but testtag
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(vm.tags, {'testtag': 'testvalue'})
Example #23
0
    def test_auto_tag_update_false_noop_for_existing_tag(self, utcnow_mock):
        """Adds CreatorEmail to a resource group
        """

        # setup by adding an existing CreatorEmail tag
        p = self.load_policy({
            'name':
            'test-azure-tag',
            'resource':
            'azure.resourcegroup',
            'filters': [{
                'type': 'value',
                'key': 'name',
                'op': 'eq',
                'value_type': 'normalize',
                'value': 'test_vm'
            }],
            'actions': [
                {
                    'type': 'tag',
                    'tag': 'CreatorEmail',
                    'value': 'do-not-modify'
                },
            ],
        })
        p.run()

        p = self.load_policy({
            'name':
            'test-azure-tag',
            'resource':
            'azure.resourcegroup',
            'filters': [{
                'type': 'value',
                'key': 'name',
                'op': 'eq',
                'value_type': 'normalize',
                'value': 'test_vm'
            }],
            'actions': [{
                'type': 'auto-tag-user',
                'tag': 'CreatorEmail',
                'update': False,
                'days': 10
            }],
        })
        p.run()

        # verify CreatorEmail tag was not modified
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [
            rg for rg in client.resource_groups.list() if rg.name == 'test_vm'
        ][0]
        self.assertEqual(rg.tags['CreatorEmail'], 'do-not-modify')
Example #24
0
    def test_tag_trim_space_0_removes_all_tags_but_preserve(self):
        """Verifies tag trim removes all other tags but tags
        listed in preserve
        """

        # Add tags to trim
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'tag-to-trim1': 'value1', 'tag-to-trim2': 'value2',
                          'tag-to-trim3': 'value3'}}
            ],
        })
        p.run()

        # verify initial tags contain more than testtag
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertTrue('tag-to-trim1' in vm.tags)
        self.assertTrue('tag-to-trim2' in vm.tags)
        self.assertTrue('tag-to-trim3' in vm.tags)
        self.assertTrue('testtag' in vm.tags)

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag-trim',
                 'space': 0,
                 'preserve': ['testtag']
                 }
            ],
        })
        p.run()

        # verify all tags trimmed but testtag
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(vm.tags, {'testtag': 'testvalue'})
Example #25
0
 def setUp(self):
     super(AzureEventSubscriptionsTest, self).setUp()
     self.session = Session()
     account = self.setup_account()
     queue_name = 'cctesteventsub'
     StorageUtilities.create_queue_from_storage_account(account, queue_name, self.session)
     event_sub_destination = StorageQueueEventSubscriptionDestination(
         resource_id=account.id, queue_name=queue_name)
     AzureEventSubscription.create(event_sub_destination,
                                   self.event_sub_name,
                                   self.session.get_subscription_id())
Example #26
0
    def test_initialize_session_token(self):
        with patch.dict(os.environ,
                        {
                            constants.ENV_ACCESS_TOKEN: 'token',
                            constants.ENV_SUB_ID: 'ea42f556-5106-4743-99b0-c129bfa71a47'
                        }, clear=True):

            s = Session()

            self.assertIs(type(s.get_credentials()), BasicTokenAuthentication)
            self.assertEqual(s.get_subscription_id(), 'ea42f556-5106-4743-99b0-c129bfa71a47')
Example #27
0
    def test_initialize_session_token(self):
        with patch.dict(os.environ,
                        {
                            constants.ENV_ACCESS_TOKEN: 'token',
                            constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
                        }, clear=True):
            s = Session()

            self.assertIsNone(s.get_credentials()._credential)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
            self.assertEqual(s.get_credentials().get_token(), AccessToken('token', 0))
    def test_initialize_session_token(self):
        with patch.dict(os.environ,
                        {
                            constants.ENV_ACCESS_TOKEN: 'token',
                            constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
                        }, clear=True):

            s = Session()

            self.assertIs(type(s.get_credentials()), BasicTokenAuthentication)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
    def test_initialize_msi_auth_system(self):
        with patch('msrestazure.azure_active_directory.MSIAuthentication.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_USE_MSI: 'true',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
                            }, clear=True):
                s = Session()

                self.assertIs(type(s.get_credentials()), MSIAuthentication)
                self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
Example #30
0
    def test_tag_trim_removes_tags_for_space(self):
        """Verifies tag trim removes tags when the space value
        and number of tags on the resource are greater than the max
        tag value (15)
        """

        # Add tags to trim
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'tag-to-trim1': 'value1', 'tag-to-trim2': 'value2'}}
            ],
        })
        p.run()

        # verify more than 1 tag on resource
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertTrue(len(vm.tags) > 1)

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag-trim',
                 'space': 14,
                 'preserve': ['testtag']
                 }
            ],
        })
        p.run()

        # verify that tags were trimmed to
        # have 14 spaces and 1 preserved
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(len(vm.tags), 1)
Example #31
0
    def test_initialize_msi_auth_system(self):
        with patch('msrestazure.azure_active_directory.MSIAuthentication.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_USE_MSI: 'true',
                                constants.ENV_SUB_ID: 'ea42f556-5106-4743-99b0-c129bfa71a47'
                            }, clear=True):
                s = Session()

                self.assertIs(type(s.get_credentials()), MSIAuthentication)
                self.assertEqual(s.get_subscription_id(), 'ea42f556-5106-4743-99b0-c129bfa71a47')
Example #32
0
    def test_initialize_msi_auth_system(self):
        with patch('msrestazure.azure_active_directory.MSIAuthentication.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_USE_MSI: 'true',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
                            }, clear=True):
                s = Session()

                self.assertIs(type(s.get_credentials()), MSIAuthentication)
                self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
Example #33
0
    def test_initialize_session_auth_file_no_sub(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            s = Session(subscription_id=CUSTOM_SUBSCRIPTION_ID,
                        authorization_file=self.authorization_file_no_sub)

            self.assertIs(type(s.get_credentials()), ServicePrincipalCredentials)
            self.assertEqual(s.get_subscription_id(), CUSTOM_SUBSCRIPTION_ID)

            # will vary between recorded/live auth options but useful to ensure
            # we ended up with one of the valid values
            self.assertTrue(s.get_tenant_id() in [DEFAULT_TENANT_ID, 'tenant'])
Example #34
0
    def test_tag_trim_removes_tags_for_space(self):
        """Verifies tag trim removes tags when the space value
        and number of tags on the resource are greater than the max
        tag value (15)
        """

        # Add tags to trim
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'tag-to-trim1': 'value1', 'tag-to-trim2': 'value2'}}
            ],
        })
        p.run()

        # verify more than 1 tag on resource
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertTrue(len(vm.tags) > 1)

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'tag-trim',
                 'space': 14,
                 'preserve': ['testtag']
                 }
            ],
        })
        p.run()

        # verify that tags were trimmed to
        # have 14 spaces and 1 preserved
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertEqual(len(vm.tags), 1)
Example #35
0
    def test_initialize_session_principal(self):
        with patch.dict(os.environ,
                        {
                            constants.ENV_TENANT_ID: DEFAULT_TENANT_ID,
                            constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                            constants.ENV_CLIENT_ID: 'client',
                            constants.ENV_CLIENT_SECRET: 'secret'
                        }, clear=True):
            s = Session()

            self.assertIs(type(s.get_credentials()._credential), ClientSecretCredential)
            self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
            self.assertEqual(s.get_tenant_id(), DEFAULT_TENANT_ID)
Example #36
0
    def test_initialize_session_msi_authentication_error(self, mock_log, mock_cred):
        with self.assertRaises(SystemExit):
            mock_cred.side_effect = HTTPError()

            with patch.dict(os.environ,
                            {
                                constants.ENV_USE_MSI: 'true',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
                            }, clear=True):
                s = Session()
                s.get_subscription_id()

        mock_log.assert_called_once_with('Failed to authenticate with MSI')
    def test_deploy_webapp(self):
        s = Session()
        web_client = s.client('azure.mgmt.web.WebSiteManagementClient')

        service_plan = web_client.app_service_plans.get(
            CONST_GROUP_NAME, 'cloud-custodian-test')
        self.assertIsNotNone(service_plan)
        webapp_name = 'test-deploy-webapp'
        self.functionapp_util.deploy_webapp(webapp_name, CONST_GROUP_NAME,
                                            service_plan, 'cloudcustodiantest')

        wep_app = web_client.web_apps.get(CONST_GROUP_NAME, webapp_name)
        self.assertIsNotNone(wep_app)
Example #38
0
    def test_initialize_session_token(self):
        with patch.dict(
                os.environ,
            {
                constants.ENV_ACCESS_TOKEN: 'token',
                constants.ENV_SUB_ID: 'ea42f556-5106-4743-99b0-c129bfa71a47'
            },
                clear=True):

            s = Session()

            self.assertIs(type(s.get_credentials()), BasicTokenAuthentication)
            self.assertEqual(s.get_subscription_id(),
                             'ea42f556-5106-4743-99b0-c129bfa71a47')
Example #39
0
    def test_initialize_msi_auth_user(self):
        with patch.dict(os.environ,
                        {
                            constants.ENV_USE_MSI: 'true',
                            constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                            constants.ENV_CLIENT_ID: 'client'
                        }, clear=True):
            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_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
Example #40
0
    def test_add_or_update_tags(self):
        """Adds tags to an empty resource group, then updates one
        tag and adds a new tag
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'pre-existing-1': 'unmodified', 'pre-existing-2': 'unmodified'}},
            ],
        })
        p.run()

        # verify initial tag set
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]
        self.assertEqual(rg.tags,
                         {'pre-existing-1': 'unmodified', 'pre-existing-2': 'unmodified'})

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'tag1': 'value1', 'pre-existing-1': 'modified'}}
            ],
        })
        p.run()

        # verify modified tags
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0] # NOQA
        self.assertEqual(
            rg.tags,
            {'tag1': 'value1', 'pre-existing-1': 'modified', 'pre-existing-2': 'unmodified'})
Example #41
0
    def test_initialize_session_cli_error(self, mock_log, mock_cli_creds):
        with self.assertRaises(SystemExit):
            mock_cli_creds.side_effect = CLIError("Bad CLI credentials")

            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                            }, clear=True):
                s = Session()
                s.get_subscription_id()

        mock_log.assert_called_once_with('Failed to authenticate with CLI credentials. '
                                         'Bad CLI credentials')
Example #42
0
    def test_add_or_update_tags(self):
        """Adds tags to an empty resource group, then updates one
        tag and adds a new tag
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'pre-existing-1': 'unmodified', 'pre-existing-2': 'unmodified'}},
            ],
        })
        p.run()

        # verify initial tag set
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]
        self.assertEqual(rg.tags,
                         {'pre-existing-1': 'unmodified', 'pre-existing-2': 'unmodified'})

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tags': {'tag1': 'value1', 'pre-existing-1': 'modified'}}
            ],
        })
        p.run()

        # verify modified tags
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]  # NOQA
        self.assertEqual(
            rg.tags,
            {'tag1': 'value1', 'pre-existing-1': 'modified', 'pre-existing-2': 'unmodified'})
Example #43
0
    def test_initialize_session_principal(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: DEFAULT_TENANT_ID,
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret'
                            }, clear=True):
                s = Session()

                self.assertIs(type(s.get_credentials()), ServicePrincipalCredentials)
                self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
                self.assertEqual(s.get_tenant_id(), DEFAULT_TENANT_ID)
    def test_deploy_webapp(self):
        s = Session()
        web_client = s.client('azure.mgmt.web.WebSiteManagementClient')

        service_plan = web_client.app_service_plans.get(
            CONST_GROUP_NAME, 'cloud-custodian-test')
        self.assertIsNotNone(service_plan)
        webapp_name = 'test-deploy-webapp'
        self.functionapp_util.deploy_webapp(webapp_name,
                                            CONST_GROUP_NAME,
                                            service_plan,
                                            'cloudcustodiantest')

        wep_app = web_client.web_apps.get(CONST_GROUP_NAME, webapp_name)
        self.assertIsNotNone(wep_app)
Example #45
0
    def test_initialize_session_principal(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: 'ea42f556-5106-4743-99b0-c129bfa71a47',
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret'
                            }, clear=True):

                s = Session()

                self.assertIs(type(s.get_credentials()), ServicePrincipalCredentials)
                self.assertEqual(s.get_subscription_id(), 'ea42f556-5106-4743-99b0-c129bfa71a47')
Example #46
0
    def __init__(self, storage_id, queue_name, policy_uri,
                 log_group=None, metrics=None, output_dir=None):
        logging.basicConfig(level=logging.INFO, format='%(message)s')
        log.info("Running Azure Cloud Custodian Self-Host")

        resources.load_available()

        self.session = local_session(Session)
        self.storage_session = self.session
        storage_subscription_id = ResourceIdParser.get_subscription_id(storage_id)
        if storage_subscription_id != self.session.subscription_id:
            self.storage_session = Session(subscription_id=storage_subscription_id)

        # Load configuration
        self.options = Host.build_options(output_dir, log_group, metrics)
        self.policy_storage_uri = policy_uri
        self.event_queue_id = storage_id
        self.event_queue_name = queue_name

        # Default event queue name is the subscription ID
        if not self.event_queue_name:
            self.event_queue_name = self.session.subscription_id

        # Prepare storage bits
        self.policy_blob_client = None
        self.blob_cache = {}
        self.queue_storage_account = self.prepare_queue_storage(
            self.event_queue_id,
            self.event_queue_name)

        self.queue_service = None

        # Register event subscription
        self.update_event_subscription()

        # Policy cache and dictionary
        self.policy_cache = tempfile.mkdtemp()
        self.policies = {}

        # Configure scheduler
        self.scheduler = BlockingScheduler(Host.get_scheduler_config())
        logging.getLogger('apscheduler.executors.default').setLevel(logging.ERROR)
        logging.getLogger('apscheduler').setLevel(logging.ERROR)

        # Schedule recurring policy updates
        self.scheduler.add_job(self.update_policies,
                               'interval',
                               seconds=policy_update_seconds,
                               id="update_policies",
                               next_run_time=datetime.now(),
                               executor='threadpool')

        # Schedule recurring queue polling
        self.scheduler.add_job(self.poll_queue,
                               'interval',
                               seconds=queue_poll_seconds,
                               id="poll_queue",
                               executor='threadpool')

        self.scheduler.start()
Example #47
0
    def test_auto_tag_update_false_noop_for_existing_tag(self, utcnow_mock):
        """Adds CreatorEmail to a resource group
        """

        # setup by adding an existing CreatorEmail tag
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'tag',
                 'tag': 'CreatorEmail',
                 'value': 'do-not-modify'},
            ],
        })
        p.run()

        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.resourcegroup',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'test_vm'}
            ],
            'actions': [
                {'type': 'auto-tag-user',
                 'tag': 'CreatorEmail',
                 'update': False,
                 'days': 10}
            ],
        })
        p.run()

        # verify CreatorEmail tag was not modified
        s = Session()
        client = s.client('azure.mgmt.resource.ResourceManagementClient')
        rg = [rg for rg in client.resource_groups.list() if rg.name == 'test_vm'][0]
        self.assertEqual(rg.tags['CreatorEmail'], 'do-not-modify')
    def test_initialize_session_msi_authentication_error(
            self, mock_log, mock_cred):
        with self.assertRaises(SystemExit):
            mock_cred.side_effect = HTTPError()

            with patch.dict(os.environ, {
                    constants.ENV_USE_MSI: 'true',
                    constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID
            },
                            clear=True):
                s = Session()
                s.get_subscription_id()

        mock_log.assert_called_once_with(
            'Azure Authentication Failure\n'
            'Error: Could not authenticate using managed service identity (system identity)'
        )
Example #49
0
    def test_initialize_msi_auth_user(self):
        with patch(
                'msrestazure.azure_active_directory.MSIAuthentication.__init__',
                autospec=True,
                return_value=None):
            with patch.dict(os.environ, {
                    constants.ENV_USE_MSI: 'true',
                    constants.ENV_SUB_ID:
                    'ea42f556-5106-4743-99b0-c129bfa71a47',
                    constants.ENV_CLIENT_ID: 'client'
            },
                            clear=True):
                s = Session()

                self.assertIs(type(s.get_credentials()), MSIAuthentication)
                self.assertEqual(s.get_subscription_id(),
                                 'ea42f556-5106-4743-99b0-c129bfa71a47')
Example #50
0
    def test_initialize_session_kv_authentication_error(self, mock_log, mock_get_kv_secret):
        with self.assertRaises(SystemExit):
            mock_get_kv_secret.side_effect = HTTPError()

            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                                constants.ENV_KEYVAULT_CLIENT_ID: 'kv_client',
                                constants.ENV_KEYVAULT_SECRET_ID: 'kv_secret'
                            }, clear=True):
                s = Session()
                s.get_subscription_id()

        mock_log.assert_called_once_with(
            'Failed to retrieve SP credential from '
            'Key Vault with client id: kv_client')
Example #51
0
    def enhance_policies(self, access_policies):
        if self.graph_client is None:
            s = Session(resource='https://graph.windows.net')
            self.graph_client = GraphRbacManagementClient(s.get_credentials(), s.get_tenant_id())

        # Retrieve graph objects for all object_id
        object_ids = [p['objectId'] for p in access_policies]
        # GraphHelper.get_principal_dictionary returns empty AADObject if not found with graph
        # or if graph is not available.
        principal_dics = GraphHelper.get_principal_dictionary(self.graph_client, object_ids)

        for policy in access_policies:
            aad_object = principal_dics[policy['objectId']]
            policy['displayName'] = aad_object.display_name
            policy['aadType'] = aad_object.object_type
            policy['principalName'] = GraphHelper.get_principal_name(aad_object)

        return access_policies
    def augment(self, resources):
        s = Session(resource='https://graph.windows.net')
        graph_client = GraphRbacManagementClient(s.get_credentials(), s.get_tenant_id())

        object_ids = list(set(
            resource['properties']['principalId'] for resource in resources
            if resource['properties']['principalId']))

        principal_dics = GraphHelper.get_principal_dictionary(graph_client, object_ids)

        for resource in resources:
            if resource['properties']['principalId'] in principal_dics.keys():
                graph_resource = principal_dics[resource['properties']['principalId']]
                if graph_resource.object_id:
                    resource['principalName'] = GraphHelper.get_principal_name(graph_resource)
                    resource['displayName'] = graph_resource.display_name
                    resource['aadType'] = graph_resource.object_type

        return resources
    def test_get_functions_auth_string(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret'
                            }, clear=True):
                s = Session()

                auth = s.get_functions_auth_string(CUSTOM_SUBSCRIPTION_ID)

                expected = {"credentials":
                            {"client_id": "client",
                             "secret": "secret",
                             "tenant": "tenant"},
                            "subscription": CUSTOM_SUBSCRIPTION_ID}

                self.assertEqual(json.loads(auth), expected)
    def test_get_function_target_subscription(self):
        with patch('azure.common.credentials.ServicePrincipalCredentials.__init__',
                   autospec=True, return_value=None):
            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret'
                            }, clear=True):
                s = Session()
                self.assertEqual(s.get_function_target_subscription_name(),
                                 DEFAULT_SUBSCRIPTION_ID)
                self.assertEqual(s.get_function_target_subscription_ids(),
                                 [DEFAULT_SUBSCRIPTION_ID])

            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret',
                                constants.ENV_FUNCTION_SUB_ID: CUSTOM_SUBSCRIPTION_ID
                            }, clear=True):
                s = Session()
                self.assertEqual(s.get_function_target_subscription_name(),
                                 CUSTOM_SUBSCRIPTION_ID)
                self.assertEqual(s.get_function_target_subscription_ids(),
                                 [CUSTOM_SUBSCRIPTION_ID])

            with patch.dict(os.environ,
                            {
                                constants.ENV_TENANT_ID: 'tenant',
                                constants.ENV_SUB_ID: DEFAULT_SUBSCRIPTION_ID,
                                constants.ENV_CLIENT_ID: 'client',
                                constants.ENV_CLIENT_SECRET: 'secret',
                                constants.ENV_FUNCTION_MANAGED_GROUP_NAME: 'test'
                            }, clear=True):
                with patch('c7n_azure.utils.ManagedGroupHelper.get_subscriptions_list',
                           return_value=[]):
                    s = Session()
                    self.assertEqual(s.get_function_target_subscription_name(), 'test')
                    self.assertEqual(s.get_function_target_subscription_ids(), [])
Example #55
0
    def test_removal_does_not_raise_on_nonexistent_tag(self):
        """Verifies attempting to delete a tag that is
        not on the resource does not throw an error
        """
        p = self.load_policy({
            'name': 'test-azure-tag',
            'resource': 'azure.vm',
            'filters': [
                {'type': 'value',
                 'key': 'name',
                 'op': 'eq',
                 'value_type': 'normalize',
                 'value': 'cctestvm'}
            ],
            'actions': [
                {'type': 'untag',
                 'tags': ['tag-does-not-exist']},
            ],
        })

        # verify initial tag set
        s = Session()
        client = s.client('azure.mgmt.compute.ComputeManagementClient')
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        start_tags = vm.tags
        self.assertTrue('tag-does-not-exist' not in start_tags)

        raised = False
        try:
            p.run()
        except KeyError:
            raised = True

        # verify no exception raised and no changes to tags on resource
        vm = client.virtual_machines.get('test_vm', 'cctestvm')
        self.assertFalse(raised)
        self.assertEqual(vm.tags, start_tags)
 def test_get_session_for_resource(self):
     s = Session()
     resource_session = s.get_session_for_resource(constants.RESOURCE_STORAGE)
     self.assertEqual(resource_session.resource_namespace, constants.RESOURCE_STORAGE)
 def test_api_version(self):
     """Verify we retrieve the correct API version for a resource type"""
     s = Session()
     client = s.client('azure.mgmt.resource.ResourceManagementClient')
     resource = next(client.resources.list())
     self.assertEqual('2018-04-01', s.resource_api_version(resource.id))