Exemplo n.º 1
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')
Exemplo n.º 2
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')
Exemplo n.º 3
0
    def test_initialize_session_auth_file(self):
        s = Session(authorization_file=self.authorization_file)

        self.assertIs(type(s.get_credentials()._credential),
                      ClientSecretCredential)
        self.assertEqual(s.get_subscription_id(), DEFAULT_SUBSCRIPTION_ID)
        self.assertEqual(s.get_tenant_id(), 'tenant')
Exemplo n.º 4
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')
Exemplo n.º 5
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')
Exemplo n.º 6
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(
            'Azure Authentication Failure\n'
            'Error: Could not authenticate using managed service identity (system identity)'
        )
Exemplo n.º 7
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')
Exemplo n.º 8
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)
Exemplo n.º 9
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'])
Exemplo n.º 10
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)
Exemplo n.º 11
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)
Exemplo n.º 12
0
class AzureEventsTest(BaseTest):
    def setUp(self):
        super(AzureEventsTest, self).setUp()
        self.session = Session()

    def test_get_returns_event_dict(self):
        event_dic = AzureEvents.get('VmWrite')
        self.assertEqual(event_dic['event'], 'write')
        self.assertEqual(event_dic['resource_provider'],
                         'Microsoft.Compute/virtualMachines')

    def test_get_event_operations_one_string(self):
        event_string = 'VmWrite'
        event_operations = AzureEvents.get_event_operations([event_string])
        self.assertEqual(len(event_operations), 1)
        self.assertEqual(event_operations[0],
                         'Microsoft.Compute/virtualMachines/write')

    def test_get_event_operations_one_event_object(self):
        event_dictionary = {
            'resourceProvider': 'Microsoft.Compute/virtualMachines',
            'event': 'write'
        }
        event_operations = AzureEvents.get_event_operations([event_dictionary])
        self.assertEqual(len(event_operations), 1)
        self.assertEqual(event_operations[0],
                         'Microsoft.Compute/virtualMachines/write')

    def test_get_event_operations_both_event_types(self):
        event_string = 'AppServicePlanWrite'
        event_dict = {
            'resourceProvider': 'Microsoft.Compute/virtualMachines',
            'event': 'write'
        }
        event_operations = AzureEvents.get_event_operations(
            [event_string, event_dict])
        self.assertEqual(len(event_operations), 2)
        self.assertTrue(
            'Microsoft.Compute/virtualMachines/write' in event_operations)
        self.assertTrue('Microsoft.Web/serverFarms/write' in event_operations)

    @arm_template('storage.json')
    def test_create_azure_event_subscription(self):
        account = self.setup_account()
        queue_name = 'cctestevensub'
        StorageUtilities.create_queue_from_storage_account(
            account, queue_name, self.session)
        sub_destination = StorageQueueEventSubscriptionDestination(
            resource_id=account.id, queue_name=queue_name)
        sub_name = 'custodiantestsubscription'
        event_subscription = AzureEventSubscription.create(
            sub_destination, sub_name, self.session.get_subscription_id())
        self.assertEqual(event_subscription.name, sub_name)
        self.assertEqual(event_subscription.destination.endpoint_type,
                         'StorageQueue')
Exemplo n.º 13
0
    def test_initialize_session_authentication_error(self, mock_log, mock_cred):
        with self.assertRaises(SystemExit):
            adal_err = AdalError("test")
            adal_err.error_response = {'error': 'test'}
            err = AuthenticationError('test')
            err.inner_exception = adal_err
            mock_cred.side_effect = err

            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()
                s.get_subscription_id()

        mock_log.assert_called_once_with(
            'Failed to authenticate with service principal.\nMessage: {\n  "error": "test"\n}')
Exemplo n.º 14
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))
Exemplo n.º 15
0
class AzureEventsTest(BaseTest):
    def setUp(self):
        super(AzureEventsTest, self).setUp()
        self.session = Session()

    def test_get_returns_event_dict(self):
        event_dic = AzureEvents.get('VmWrite')
        self.assertEqual(event_dic['event'], 'write')
        self.assertEqual(event_dic['resource_provider'],
                         'Microsoft.Compute/virtualMachines')

    def test_get_event_operations_one_string(self):
        event_string = 'VmWrite'
        event_operations = AzureEvents.get_event_operations([event_string])
        self.assertEqual(len(event_operations), 1)
        self.assertEqual(event_operations[0],
                         'Microsoft.Compute/virtualMachines/write')

    def test_get_event_operations_one_event_object(self):
        event_dictionary = {
            'resourceProvider': 'Microsoft.Compute/virtualMachines',
            'event': 'write'
        }
        event_operations = AzureEvents.get_event_operations([event_dictionary])
        self.assertEqual(len(event_operations), 1)
        self.assertEqual(event_operations[0],
                         'Microsoft.Compute/virtualMachines/write')

    def test_get_event_operations_both_event_types(self):
        event_string = 'AppServicePlanWrite'
        event_dict = {
            'resourceProvider': 'Microsoft.Compute/virtualMachines',
            'event': 'write'
        }
        event_operations = AzureEvents.get_event_operations(
            [event_string, event_dict])
        self.assertEqual(len(event_operations), 2)
        self.assertTrue(
            'Microsoft.Compute/virtualMachines/write' in event_operations)
        self.assertTrue('Microsoft.Web/serverFarms/write' in event_operations)

    @patch('azure.mgmt.eventgrid.operations.event_subscriptions_operations.'
           'EventSubscriptionsOperations.create_or_update')
    def test_create_azure_event_subscription(self, create_mock):
        sub_destination = StorageQueueEventSubscriptionDestination(
            resource_id="cctestid", queue_name="cctestevensub")
        sub_name = 'custodiantestsubscription'
        sub_id = self.session.get_subscription_id()
        AzureEventSubscription.create(sub_destination, sub_name, sub_id)

        args = create_mock.mock_calls[0].args
        self.assertTrue(sub_id in args[0])
        self.assertEqual(sub_name, args[1])
        self.assertEqual(sub_destination, args[2].destination)
Exemplo n.º 16
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')
Exemplo n.º 17
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)
Exemplo n.º 18
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)
Exemplo n.º 19
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')
Exemplo n.º 20
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'])
Exemplo n.º 21
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)
Exemplo n.º 22
0
    def test_initialize_session_kv_authentication_error(
            self, mock_log, mock_get_kv_secret):
        reload(sys.modules['c7n_azure.session'])

        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(
            'Azure Authentication Failure\nError: '
            'Cannot retrieve SP credentials from the Key Vault '
            '(KV uses MSI to access) with client id: kv_client')
Exemplo n.º 23
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)
Exemplo n.º 24
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')
Exemplo n.º 25
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)
Exemplo n.º 26
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)
Exemplo n.º 27
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')
Exemplo n.º 28
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')
Exemplo n.º 29
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')
class AzureEventSubscriptionsTest(BaseTest):
    event_sub_name = 'custodiantestsubscription'

    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())

    def test_event_subscription_schema_validate(self):
        with self.sign_out_patch():
            p = self.load_policy(
                {
                    'name': 'test-azure-event-subscription',
                    'resource': 'azure.eventsubscription',
                    'actions': [{
                        'type': 'delete'
                    }]
                },
                validate=True)
            self.assertTrue(p)

    @arm_template('storage.json')
    def test_azure_event_subscription_policy_run(self):
        p = self.load_policy({
            'name':
            'test-azure-event-subscriptions',
            'resource':
            'azure.eventsubscription',
            'filters': [{
                'type': 'value',
                'key': 'name',
                'op': 'eq',
                'value': self.event_sub_name
            }],
        })
        resources = p.run()
        self.assertEqual(len(resources), 1)

    @arm_template('storage.json')
    def test_azure_event_subscription_delete(self):
        p_get = self.load_policy({
            'name':
            'test-azure-event-subscriptions',
            'resource':
            'azure.eventsubscription',
            'filters': [{
                'type': 'value',
                'key': 'name',
                'op': 'eq',
                'value': self.event_sub_name
            }],
        })
        resources_pre_delete = p_get.run()
        self.assertEqual(len(resources_pre_delete), 1)

        p_delete = self.load_policy(
            {
                'name': 'test-azure-event-subscriptions',
                'resource': 'azure.eventsubscription',
                'actions': [{
                    'type': 'delete'
                }]
            },
            validate=True)

        p_delete.run()
        resources_post_delete = p_get.run()
        self.assertEqual(len(resources_post_delete), 0)
Exemplo n.º 31
0
class CostFilterTest(BaseTest):
    def setUp(self):
        super(CostFilterTest, self).setUp()
        self.session = Session()

    def test_schema(self):
        self.assertTrue(
            self.load_policy(
                {
                    'name':
                    'test-cost-filter',
                    'resource':
                    'azure.vm',
                    'filters': [{
                        'type': 'cost',
                        'timeframe': 'MonthToDate',
                        'op': 'eq',
                        'value': 1
                    }]
                },
                validate=True))

        self.assertTrue(
            self.load_policy(
                {
                    'name':
                    'test-cost-filter',
                    'resource':
                    'azure.resourcegroup',
                    'filters': [{
                        'type': 'cost',
                        'timeframe': 7,
                        'op': 'eq',
                        'value': 1
                    }]
                },
                validate=True))

    def test_custom_timeframe(self):
        resources = [
            self._get_resource('vm1', 2000),
            self._get_resource('vm2', 20),
            self._get_resource('vm3', 3000)
        ]
        f = self._get_filter(
            {
                'timeframe': 'TheLastWeek',
                'op': 'gt',
                'value': 1000
            }, resources)

        result = f.process(resources, None)

        usage_by_scope = f.manager.get_client.return_value.query.usage_by_scope
        self._verify_expected_call(usage_by_scope, 'TheLastWeek', False)
        self.assertEqual(len(result), 2)

    def test_rg(self):
        resources = [
            self._get_resource_group('rg1', 2000),
            self._get_resource_group('rg2', 20),
            self._get_resource_group('rg3', 3000)
        ]
        f = self._get_filter({
            'timeframe': 1,
            'op': 'lt',
            'value': 1000
        }, resources)

        result = f.process(resources, None)

        usage_by_scope = f.manager.get_client.return_value.query.usage_by_scope
        self._verify_expected_call(usage_by_scope, 1, True)
        self.assertEqual(len(result), 1)

    def test_child_resources(self):
        resources = [
            self._get_resource('vm1', 0),
            self._get_resource('vm1/child1', 300),
            self._get_resource('vm1/child2', 3000)
        ]
        f = self._get_filter(
            {
                'timeframe': 'TheLastWeek',
                'op': 'eq',
                'value': 3300
            }, resources)

        result = f.process(resources, None)

        usage_by_scope = f.manager.get_client.return_value.query.usage_by_scope
        self._verify_expected_call(usage_by_scope, 'TheLastWeek', False)
        self.assertEqual(len(result), 1)

    def _verify_expected_call(self, mock, timeframe, resource_group):
        subscription_id = self.session.get_subscription_id()

        mock.assert_called_once()
        definition = mock.call_args[0][1]

        if isinstance(timeframe, int):
            today = utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
            self.assertEqual(definition.timeframe, 'Custom')
            self.assertEqual(definition.time_period.to, today)
            self.assertEqual(definition.time_period.from_property,
                             today - datetime.timedelta(days=timeframe))
        else:
            self.assertEqual(definition.timeframe, timeframe)

        self.assertEqual(len(definition.dataset.grouping), 1)
        self.assertEqual(definition.dataset.grouping[0].type, 'Dimension')
        self.assertEqual(
            definition.dataset.grouping[0].name,
            'ResourceGroupName' if resource_group else 'ResourceId')

        self.assertEqual(definition.dataset.aggregation['totalCost'].name,
                         'PreTaxCost')

        if not resource_group:
            self.assertEqual(definition.dataset.filter.dimension.name,
                             'ResourceType')
            self.assertEqual(definition.dataset.filter.dimension.operator,
                             'In')
            self.assertEqual(definition.dataset.filter.dimension.values,
                             ['Microsoft.Compute/virtualMachines'])

        mock.assert_called_once_with('/subscriptions/' + subscription_id,
                                     definition)

    def _get_filter(self, data, resources):
        manager = Mock()
        manager.get_session.return_value.get_subscription_id.return_value = \
            self.session.get_subscription_id()
        manager.get_client.return_value.query.usage_by_scope.return_value = \
            self._get_costs(resources)
        if 'Microsoft.Compute/virtualMachines' in resources[0]['id']:
            manager.resource_type.resource_type = 'Microsoft.Compute/virtualMachines'
        else:
            manager.type = 'resourcegroup'
            manager.resource_type.resource_type = 'Microsoft.Resources/subscriptions/resourceGroups'
        return CostFilter(data=data, manager=manager)

    def _get_resource(self, name, cost):
        return {
            'id':
            '/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/'
            'TEST_VM/providers/Microsoft.Compute/virtualMachines/{0}'.format(
                name),
            '_cost':
            cost
        }

    def _get_resource_group(self, name, cost):
        return {
            'id':
            '/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/'
            '{0}'.format(name),
            '_cost':
            cost
        }

    def _get_costs(self, resources):
        rows = [[r['id'], r['_cost'], 'USD'] for r in resources]
        cost = {
            'columns': [
                Column('ResourceId'),
                Column('PreTaxCost'),
                Column('Currency'),
            ],
            'rows':
            rows
        }
        cost = namedtuple("Cost", cost.keys())(*cost.values())
        return [cost]
Exemplo n.º 32
0
class CostFilterTest(BaseTest):
    def setUp(self):
        super(CostFilterTest, self).setUp()
        self.session = Session()

    def test_cost_filter_schema_validate_named_timeframe(self):
        p = self.load_policy(
            {
                'name':
                'test-cost-filter',
                'resource':
                'azure.armresource',
                'filters': [{
                    'type': 'cost',
                    'timeframe': 'MonthToDate',
                    'op': 'eq',
                    'value': 1
                }]
            },
            validate=True)
        self.assertTrue(p)

    def test_cost_filter_schema_validate_timeframe_in_days(self):
        p = self.load_policy(
            {
                'name':
                'test-cost-filter',
                'resource':
                'azure.armresource',
                'filters': [{
                    'type': 'cost',
                    'timeframe': 7,
                    'op': 'eq',
                    'value': 1
                }]
            },
            validate=True)
        self.assertTrue(p)

    # run ./templates/provision.sh vm sqlserver to deploy required resource.
    def test_exact_cost(self):

        p = self.load_policy({
            'name':
            'test-cost_filter',
            # 'resource': 'azure.vm',
            'resource':
            'azure.vm',
            'filters': [{
                'type': 'cost',
                'timeframe': 'MonthToDate',
                'op': 'ge',
                'value': 0
            }]
        })

        resources = p.run()

        self.assertTrue(len(resources) > 0)

        for resource in resources:
            self.assertEqual(resource['c7n:cost']['Currency'], 'USD')
            self.assertTrue(resource['c7n:cost']['PreTaxCost'] >= 0)

    def test_timeframe_days(self):

        p = self.load_policy({
            'name':
            'test-cost_filter',
            # 'resource': 'azure.vm',
            'resource':
            'azure.vm',
            'filters': [{
                'type': 'cost',
                'timeframe': 7,
                'op': 'ge',
                'value': 0
            }]
        })

        resources = p.run()

        self.assertTrue(len(resources) > 0)

        for resource in resources:
            self.assertEqual(resource['c7n:cost']['Currency'], 'USD')
            self.assertTrue(resource['c7n:cost']['PreTaxCost'] >= 0)

    def test_cost_greater_than(self):
        p = self.load_policy({
            'name':
            'test-cost_filter',
            'resource':
            'azure.armresource',
            'filters': [{
                'type': 'cost',
                'timeframe': 'TheLastWeek',
                'op': 'gt',
                'value': 1000
            }]
        })

        id1 = '/subscriptions/s1/resourceGroups/test_rg1/id1'
        id2 = '/subscriptions/s1/resourceGroups/test_rg1/id2'
        id3 = '/subscriptions/s1/resourceGroups/test_rg2/id3'
        id4 = '/subscriptions/s1/resourceGroups/test_rg2/id4'

        resources = [{'id': id1}, {'id': id2}, {'id': id3}, {'id': id4}]

        cost = self._make_cost([
            [id1, 2000],
            [id2, 20],
            [id3, 3000],
            [id4, 40],
        ])

        with patch.object(DescribeSource,
                          'get_resources',
                          return_value=resources):
            with patch.object(
                    azure.mgmt.costmanagement.operations.QueryOperations,
                    'usage_by_scope',
                    return_value=cost) as mock:

                resources = p.run()

                mock.assert_has_calls(
                    [self._make_expected_call(mock, 'TheLastWeek')])

                self.assertEqual(mock.call_count, 1)

                self.assertEqual(len(resources), 2)
                self.assertEqual(resources[0]['id'], id1)
                self.assertEqual(resources[1]['id'], id3)

    def test_cost_two_filters(self):
        p = self.load_policy({
            'name':
            'test-cost_filter',
            'resource':
            'azure.armresource',
            'filters': [{
                'type': 'cost',
                'timeframe': 'TheLastWeek',
                'op': 'eq',
                'value': 100
            }, {
                'type': 'cost',
                'timeframe': 'TheLastMonth',
                'op': 'eq',
                'value': 1000
            }]
        })

        id1 = '/subscriptions/s1/resourceGroups/test_rg1/id1'
        id2 = '/subscriptions/s1/resourceGroups/test_rg1/id2'
        id3 = '/subscriptions/s1/resourceGroups/test_rg2/id3'
        id4 = '/subscriptions/s1/resourceGroups/test_rg2/id4'

        resources = [{'id': id1}, {'id': id2}, {'id': id3}, {'id': id4}]

        week_cost = self._make_cost([
            [id1, 100],
            [id2, 100],
            [id3, 100],
            [id4, 10],
        ])

        month_cost = self._make_cost([
            [id1, 2000],
            [id2, 1000],
            [id3, 1000],
            [id4, 1000],
        ])

        with patch.object(DescribeSource,
                          'get_resources',
                          return_value=resources):
            with patch.object(
                    azure.mgmt.costmanagement.operations.QueryOperations,
                    'usage_by_scope') as mock:

                mock.side_effect = [week_cost, month_cost]

                resources = p.run()

                mock.assert_has_calls([
                    self._make_expected_call(mock, 'TheLastWeek'),
                    self._make_expected_call(mock, 'TheLastMonth')
                ])

                self.assertEqual(mock.call_count, 2)

                self.assertEqual(len(resources), 2)
                self.assertEqual(resources[0]['id'], id2)
                self.assertEqual(resources[1]['id'], id3)

    def _make_expected_call(self, mock, timeframe):
        grouping = [QueryGrouping(type='Dimension', name='ResourceId')]
        aggregation = {'totalCost': QueryAggregation(name='PreTaxCost')}
        dataset = QueryDataset(grouping=grouping, aggregation=aggregation)
        definition = QueryDefinition(timeframe=timeframe, dataset=dataset)
        subscription_id = self.session.get_subscription_id()
        return call('/subscriptions/' + subscription_id, definition)

    def _make_cost(self, rows):
        cost = {
            'columns': [
                Column('ResourceId'),
                Column('PreTaxCost'),
                Column('Currency'),
            ],
            'rows':
            rows
        }

        cost = namedtuple("Cost", cost.keys())(*cost.values())

        return [cost]