def main():
    module = AnsibleModule(argument_spec=dict(
        region=dict(default='na', choices=dd_regions),
        state=dict(default='present', choices=['present', 'absent']),
        node_ids=dict(required=True,
                      type='list',
                      aliases=['server_id', 'server_ids', 'node_id']),
        client_type=dict(
            required=True,
            choices=['FA.Win', 'FA.AD', 'FA.Linux', 'MySQL', 'PostgreSQL']),
        schedule_policy=dict(
            choices=['12AM - 6AM', '6AM - 12PM', '12PM - 6PM', '6PM - 12AM']),
        storage_policy=dict(choices=_storage_policy_choices()),
        notify_email=dict(required=False, default='*****@*****.**'),
        notify_trigger=dict(required=False,
                            default='ON_FAILURE',
                            choices=['ON_FAILURE', 'ON_SUCCESS']),
        verify_ssl_cert=dict(required=False, default=True, type='bool'),
    ))
    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud is required for this module.')

    # set short vars for readability
    credentials = get_credentials()
    if credentials is False:
        module.fail_json("User credentials not found")
    user_id = credentials['user_id']
    key = credentials['key']
    region = 'dd-%s' % module.params['region']
    verify_ssl_cert = module.params['verify_ssl_cert']
    # Instantiate driver
    libcloud.security.VERIFY_SSL_CERT = verify_ssl_cert
    client = DimensionDataBackupDriver(user_id, key, region=region)

    handle_backup_client(module, client)
class FakeFacility:

    plumbery = FakePlumbery()

    settings = fakeParameters
    blueprints = fakeBlueprints

    DimensionDataNodeDriver.connectionCls.conn_classes = (
        None, DimensionDataMockHttp)
    DimensionDataBackupDriver.connectionCls.conn_classes = (
        None, DimensionDataMockHttp)
    DimensionDataMockHttp.type = None
    region = DimensionDataNodeDriver(*DIMENSIONDATA_PARAMS)
    backup = DimensionDataBackupDriver(*DIMENSIONDATA_PARAMS)
    location = FakeLocation()

    _cache_network_domains = []
    _cache_vlans = []

    def get_location_id(self):
        return 'EU6'

    def get_setting(self, label):
        if label in self.settings:
            return self.settings[label]

        return None
def main():
    module = AnsibleModule(argument_spec=dict(
        region=dict(default='na', choices=dd_regions),
        state=dict(default='present', choices=['present', 'absent']),
        node_ids=dict(required=True,
                      type='list',
                      aliases=['server_id', 'server_ids', 'node_id']),
        service_plan=dict(default='Essentials',
                          choices=['Advanced', 'Essentials', 'Enterprise']),
        verify_ssl_cert=dict(required=False, default=True, type='bool'),
        wait=dict(required=False, default=False, type='bool'),
        wait_time=dict(required=False, default=120, type='int'),
        wait_poll_interval=dict(required=False, default=2, type='int')))
    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud is required for this module.')

    # set short vars for readability
    credentials = get_credentials()
    if credentials is False:
        module.fail_json("User credentials not found")
    user_id = credentials['user_id']
    key = credentials['key']
    region = 'dd-%s' % module.params['region']
    verify_ssl_cert = module.params['verify_ssl_cert']

    # Instantiate driver
    libcloud.security.VERIFY_SSL_CERT = verify_ssl_cert
    client = DimensionDataBackupDriver(user_id, key, region=region)

    handle_backups(module, client)
Exemple #4
0
 def test_invalid_region(self):
     with self.assertRaises(ValueError):
         self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah')
Exemple #5
0
 def setUp(self):
     DimensionData.connectionCls.active_api_version = '2.3'
     DimensionData.connectionCls.conn_classes = (None,
                                                 DimensionDataMockHttp)
     DimensionDataMockHttp.type = None
     self.driver = DimensionData(*DIMENSIONDATA_PARAMS)
Exemple #6
0
class DimensionData_v2_3_Tests(unittest.TestCase, TestCaseMixin):
    def setUp(self):
        DimensionData.connectionCls.active_api_version = '2.3'
        DimensionData.connectionCls.conn_classes = (None,
                                                    DimensionDataMockHttp)
        DimensionDataMockHttp.type = None
        self.driver = DimensionData(*DIMENSIONDATA_PARAMS)

    def test_invalid_region(self):
        with self.assertRaises(ValueError):
            self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah')

    def test_invalid_creds(self):
        DimensionDataMockHttp.type = 'UNAUTHORIZED'
        with self.assertRaises(InvalidCredsError):
            self.driver.list_targets()

    def test_list_targets(self):
        targets = self.driver.list_targets()
        self.assertEqual(len(targets), 2)
        self.assertEqual(targets[0].id, '5579f3a7-4c32-4cf5-8a7e-b45c36a35c10')
        self.assertEqual(targets[0].address,
                         'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(targets[0].extra['servicePlan'], 'Enterprise')

    def test_create_target(self):
        target = self.driver.create_target(
            'name',
            'e75ead52-692f-4314-8725-c8a4f4d13a87',
            extra={'servicePlan': 'Enterprise'})
        self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f')
        self.assertEqual(target.address,
                         'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(target.extra['servicePlan'], 'Enterprise')

    def test_create_target_DEFAULT(self):
        DimensionDataMockHttp.type = 'DEFAULT'
        target = self.driver.create_target(
            'name', 'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f')
        self.assertEqual(target.address,
                         'e75ead52-692f-4314-8725-c8a4f4d13a87')

    def test_create_target_EXISTS(self):
        DimensionDataMockHttp.type = 'EXISTS'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.create_target('name',
                                      'e75ead52-692f-4314-8725-c8a4f4d13a87',
                                      extra={'servicePlan': 'Enterprise'})
        self.assertEqual(context.exception.code, 'ERROR')
        self.assertEqual(
            context.exception.msg,
            'Cloud backup for this server is already enabled or being enabled (state: NORMAL).'
        )

    def test_update_target(self):
        target = self.driver.list_targets()[0]
        extra = {'servicePlan': 'Essentials'}
        new_target = self.driver.update_target(target, extra=extra)
        self.assertEqual(new_target.extra['servicePlan'], 'Essentials')

    def test_update_target_DEFAULT(self):
        DimensionDataMockHttp.type = 'DEFAULT'
        target = 'e75ead52-692f-4314-8725-c8a4f4d13a87'
        self.driver.update_target(target)

    def test_update_target_STR(self):
        target = 'e75ead52-692f-4314-8725-c8a4f4d13a87'
        extra = {'servicePlan': 'Essentials'}
        new_target = self.driver.update_target(target, extra=extra)
        self.assertEqual(new_target.extra['servicePlan'], 'Essentials')

    def test_delete_target(self):
        target = self.driver.list_targets()[0]
        self.assertTrue(self.driver.delete_target(target))

    def test_ex_add_client_to_target(self):
        target = self.driver.list_targets()[0]
        client = self.driver.ex_list_available_client_types(target)[0]
        storage_policy = self.driver.ex_list_available_storage_policies(
            target)[0]
        schedule_policy = self.driver.ex_list_available_schedule_policies(
            target)[0]
        self.assertTrue(
            self.driver.ex_add_client_to_target(target, client, storage_policy,
                                                schedule_policy, 'ON_FAILURE',
                                                '*****@*****.**'))

    def test_ex_add_client_to_target_STR(self):
        self.assertTrue(
            self.driver.ex_add_client_to_target(
                'e75ead52-692f-4314-8725-c8a4f4d13a87', 'FA.Linux',
                '14 Day Storage Policy', '12AM - 6AM', 'ON_FAILURE',
                '*****@*****.**'))

    def test_ex_get_backup_details_for_target(self):
        target = self.driver.list_targets()[0]
        response = self.driver.ex_get_backup_details_for_target(target)
        self.assertEqual(response.service_plan, 'Enterprise')
        client = response.clients[0]
        self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
        self.assertEqual(client.type.type, 'FA.Linux')
        self.assertEqual(client.running_job.progress, 5)
        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
        self.assertEqual(len(client.alert.notify_list), 2)
        self.assertTrue(isinstance(client.alert.notify_list, list))

    def test_ex_get_backup_details_for_target_NOBACKUP(self):
        target = self.driver.list_targets()[0].address
        DimensionDataMockHttp.type = 'NOBACKUP'
        response = self.driver.ex_get_backup_details_for_target(target)
        self.assertTrue(response is None)

    def test_ex_cancel_target_job(self):
        target = self.driver.list_targets()[0]
        response = self.driver.ex_get_backup_details_for_target(target)
        client = response.clients[0]
        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
        success = client.running_job.cancel()
        self.assertTrue(success)

    def test_ex_cancel_target_job_with_extras(self):
        success = self.driver.cancel_target_job(
            None,
            ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8',
            ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87')
        self.assertTrue(success)

    def test_ex_cancel_target_job_FAIL(self):
        DimensionDataMockHttp.type = 'FAIL'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.cancel_target_job(
                None,
                ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8',
                ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87')
        self.assertEqual(context.exception.code, 'ERROR')

    """Test a backup info for a target that does not have a client"""

    def test_ex_get_backup_details_for_target_NO_CLIENT(self):
        DimensionDataMockHttp.type = 'NOCLIENT'
        response = self.driver.ex_get_backup_details_for_target(
            'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(response.service_plan, 'Essentials')
        self.assertEqual(len(response.clients), 0)

    """Test a backup details that has a client, but no alerting or running jobs"""

    def test_ex_get_backup_details_for_target_NO_JOB_OR_ALERT(self):
        DimensionDataMockHttp.type = 'NOJOB'
        response = self.driver.ex_get_backup_details_for_target(
            'e75ead52-692f-4314_8725-c8a4f4d13a87')
        self.assertEqual(response.service_plan, 'Enterprise')
        self.assertTrue(isinstance(response.clients, list))
        self.assertEqual(len(response.clients), 1)
        client = response.clients[0]
        self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
        self.assertEqual(client.type.type, 'FA.Linux')
        self.assertIsNone(client.running_job)
        self.assertIsNone(client.alert)

    """Test getting backup info for a server that doesn't exist"""

    def test_ex_get_backup_details_for_target_DISABLED(self):
        DimensionDataMockHttp.type = 'DISABLED'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.ex_get_backup_details_for_target(
                'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(context.exception.code, 'ERROR')
        self.assertEqual(
            context.exception.msg,
            'Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup'
        )

    def test_ex_list_available_client_types(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_client_types(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].type, 'FA.Linux')
        self.assertEqual(answer[0].is_file_system, True)
        self.assertEqual(answer[0].description, 'Linux File system')

    def test_ex_list_available_storage_policies(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_storage_policies(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].name,
                         '30 Day Storage Policy + Secondary Copy')
        self.assertEqual(answer[0].retention_period, 30)
        self.assertEqual(answer[0].secondary_location, 'Primary')

    def test_ex_list_available_schedule_policies(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_schedule_policies(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].name, '12AM - 6AM')
        self.assertEqual(answer[0].description,
                         'Daily backup will start between 12AM - 6AM')

    def test_ex_remove_client_from_target(self):
        target = self.driver.list_targets()[0]
        client = self.driver.ex_get_backup_details_for_target(
            'e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0]
        self.assertTrue(
            self.driver.ex_remove_client_from_target(target, client))

    def test_ex_remove_client_from_target_STR(self):
        self.assertTrue(
            self.driver.ex_remove_client_from_target(
                'e75ead52-692f-4314-8725-c8a4f4d13a87',
                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'))

    def test_ex_remove_client_from_target_FAIL(self):
        DimensionDataMockHttp.type = 'FAIL'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.ex_remove_client_from_target(
                'e75ead52-692f-4314-8725-c8a4f4d13a87',
                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
        self.assertEqual(context.exception.code, 'ERROR')
        self.assertTrue(
            'Backup Client is currently performing another operation' in
            context.exception.msg)

    def test_priv_target_to_target_address(self):
        target = self.driver.list_targets()[0]
        self.assertEqual(self.driver._target_to_target_address(target),
                         'e75ead52-692f-4314-8725-c8a4f4d13a87')

    def test_priv_target_to_target_address_STR(self):
        self.assertEqual(
            self.driver._target_to_target_address(
                'e75ead52-692f-4314-8725-c8a4f4d13a87'),
            'e75ead52-692f-4314-8725-c8a4f4d13a87')

    def test_priv_target_to_target_address_TYPEERROR(self):
        with self.assertRaises(TypeError):
            self.driver._target_to_target_address([1, 2, 3])

    def test_priv_client_to_client_id(self):
        client = self.driver.ex_get_backup_details_for_target(
            'e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0]
        self.assertEqual(self.driver._client_to_client_id(client),
                         '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')

    def test_priv_client_to_client_id_STR(self):
        self.assertEqual(
            self.driver._client_to_client_id(
                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'),
            '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')

    def test_priv_client_to_client_id_TYPEERROR(self):
        with self.assertRaises(TypeError):
            self.driver._client_to_client_id([1, 2, 3])
Exemple #7
0
 def init_client(self, user, password, region=DEFAULT_REGION):
     self.node = DimensionDataNodeDriver(user, password, region)
     self.backup = DimensionDataBackupDriver(user, password, region)
class DimensionData_v2_3_Tests(unittest.TestCase):
    def setUp(self):
        DimensionData.connectionCls.active_api_version = "2.3"
        DimensionData.connectionCls.conn_class = DimensionDataMockHttp
        DimensionDataMockHttp.type = None
        self.driver = DimensionData(*DIMENSIONDATA_PARAMS)

    def test_invalid_region(self):
        with self.assertRaises(ValueError):
            self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region="blah")

    def test_invalid_creds(self):
        DimensionDataMockHttp.type = "UNAUTHORIZED"
        with self.assertRaises(InvalidCredsError):
            self.driver.list_targets()

    def test_list_targets(self):
        targets = self.driver.list_targets()
        self.assertEqual(len(targets), 2)
        self.assertEqual(targets[0].id, "5579f3a7-4c32-4cf5-8a7e-b45c36a35c10")
        self.assertEqual(targets[0].address,
                         "e75ead52-692f-4314-8725-c8a4f4d13a87")
        self.assertEqual(targets[0].extra["servicePlan"], "Enterprise")

    def test_create_target(self):
        target = self.driver.create_target(
            "name",
            "e75ead52-692f-4314-8725-c8a4f4d13a87",
            extra={"servicePlan": "Enterprise"},
        )
        self.assertEqual(target.id, "ee7c4b64-f7af-4a4f-8384-be362273530f")
        self.assertEqual(target.address,
                         "e75ead52-692f-4314-8725-c8a4f4d13a87")
        self.assertEqual(target.extra["servicePlan"], "Enterprise")

    def test_create_target_DEFAULT(self):
        DimensionDataMockHttp.type = "DEFAULT"
        target = self.driver.create_target(
            "name", "e75ead52-692f-4314-8725-c8a4f4d13a87")
        self.assertEqual(target.id, "ee7c4b64-f7af-4a4f-8384-be362273530f")
        self.assertEqual(target.address,
                         "e75ead52-692f-4314-8725-c8a4f4d13a87")

    def test_create_target_EXISTS(self):
        DimensionDataMockHttp.type = "EXISTS"
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.create_target(
                "name",
                "e75ead52-692f-4314-8725-c8a4f4d13a87",
                extra={"servicePlan": "Enterprise"},
            )
        self.assertEqual(context.exception.code, "ERROR")
        self.assertEqual(
            context.exception.msg,
            "Cloud backup for this server is already enabled or being enabled (state: NORMAL).",
        )

    def test_update_target(self):
        target = self.driver.list_targets()[0]
        extra = {"servicePlan": "Essentials"}
        new_target = self.driver.update_target(target, extra=extra)
        self.assertEqual(new_target.extra["servicePlan"], "Essentials")

    def test_update_target_DEFAULT(self):
        DimensionDataMockHttp.type = "DEFAULT"
        target = "e75ead52-692f-4314-8725-c8a4f4d13a87"
        self.driver.update_target(target)

    def test_update_target_STR(self):
        target = "e75ead52-692f-4314-8725-c8a4f4d13a87"
        extra = {"servicePlan": "Essentials"}
        new_target = self.driver.update_target(target, extra=extra)
        self.assertEqual(new_target.extra["servicePlan"], "Essentials")

    def test_delete_target(self):
        target = self.driver.list_targets()[0]
        self.assertTrue(self.driver.delete_target(target))

    def test_ex_add_client_to_target(self):
        target = self.driver.list_targets()[0]
        client = self.driver.ex_list_available_client_types(target)[0]
        storage_policy = self.driver.ex_list_available_storage_policies(
            target)[0]
        schedule_policy = self.driver.ex_list_available_schedule_policies(
            target)[0]
        self.assertTrue(
            self.driver.ex_add_client_to_target(
                target,
                client,
                storage_policy,
                schedule_policy,
                "ON_FAILURE",
                "*****@*****.**",
            ))

    def test_ex_add_client_to_target_STR(self):
        self.assertTrue(
            self.driver.ex_add_client_to_target(
                "e75ead52-692f-4314-8725-c8a4f4d13a87",
                "FA.Linux",
                "14 Day Storage Policy",
                "12AM - 6AM",
                "ON_FAILURE",
                "*****@*****.**",
            ))

    def test_ex_get_backup_details_for_target(self):
        target = self.driver.list_targets()[0]
        response = self.driver.ex_get_backup_details_for_target(target)
        self.assertEqual(response.service_plan, "Enterprise")
        client = response.clients[0]
        self.assertEqual(client.id, "30b1ff76-c76d-4d7c-b39d-3b72be0384c8")
        self.assertEqual(client.type.type, "FA.Linux")
        self.assertEqual(client.running_job.progress, 5)
        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
        self.assertEqual(len(client.alert.notify_list), 2)
        self.assertTrue(isinstance(client.alert.notify_list, list))

    def test_ex_get_backup_details_for_target_NOBACKUP(self):
        target = self.driver.list_targets()[0].address
        DimensionDataMockHttp.type = "NOBACKUP"
        response = self.driver.ex_get_backup_details_for_target(target)
        self.assertTrue(response is None)

    def test_ex_cancel_target_job(self):
        target = self.driver.list_targets()[0]
        response = self.driver.ex_get_backup_details_for_target(target)
        client = response.clients[0]
        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
        success = client.running_job.cancel()
        self.assertTrue(success)

    def test_ex_cancel_target_job_with_extras(self):
        success = self.driver.cancel_target_job(
            None,
            ex_client="30b1ff76_c76d_4d7c_b39d_3b72be0384c8",
            ex_target="e75ead52_692f_4314_8725_c8a4f4d13a87",
        )
        self.assertTrue(success)

    def test_ex_cancel_target_job_FAIL(self):
        DimensionDataMockHttp.type = "FAIL"
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.cancel_target_job(
                None,
                ex_client="30b1ff76_c76d_4d7c_b39d_3b72be0384c8",
                ex_target="e75ead52_692f_4314_8725_c8a4f4d13a87",
            )
        self.assertEqual(context.exception.code, "ERROR")

    """Test a backup info for a target that does not have a client"""

    def test_ex_get_backup_details_for_target_NO_CLIENT(self):
        DimensionDataMockHttp.type = "NOCLIENT"
        response = self.driver.ex_get_backup_details_for_target(
            "e75ead52-692f-4314-8725-c8a4f4d13a87")
        self.assertEqual(response.service_plan, "Essentials")
        self.assertEqual(len(response.clients), 0)

    """Test a backup details that has a client, but no alerting or running jobs"""

    def test_ex_get_backup_details_for_target_NO_JOB_OR_ALERT(self):
        DimensionDataMockHttp.type = "NOJOB"
        response = self.driver.ex_get_backup_details_for_target(
            "e75ead52-692f-4314_8725-c8a4f4d13a87")
        self.assertEqual(response.service_plan, "Enterprise")
        self.assertTrue(isinstance(response.clients, list))
        self.assertEqual(len(response.clients), 1)
        client = response.clients[0]
        self.assertEqual(client.id, "30b1ff76-c76d-4d7c-b39d-3b72be0384c8")
        self.assertEqual(client.type.type, "FA.Linux")
        self.assertIsNone(client.running_job)
        self.assertIsNone(client.alert)

    """Test getting backup info for a server that doesn't exist"""

    def test_ex_get_backup_details_for_target_DISABLED(self):
        DimensionDataMockHttp.type = "DISABLED"
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.ex_get_backup_details_for_target(
                "e75ead52-692f-4314-8725-c8a4f4d13a87")
        self.assertEqual(context.exception.code, "ERROR")
        self.assertEqual(
            context.exception.msg,
            "Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup",
        )

    def test_ex_list_available_client_types(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_client_types(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].type, "FA.Linux")
        self.assertEqual(answer[0].is_file_system, True)
        self.assertEqual(answer[0].description, "Linux File system")

    def test_ex_list_available_storage_policies(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_storage_policies(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].name,
                         "30 Day Storage Policy + Secondary Copy")
        self.assertEqual(answer[0].retention_period, 30)
        self.assertEqual(answer[0].secondary_location, "Primary")

    def test_ex_list_available_schedule_policies(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_schedule_policies(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].name, "12AM - 6AM")
        self.assertEqual(answer[0].description,
                         "Daily backup will start between 12AM - 6AM")

    def test_ex_remove_client_from_target(self):
        target = self.driver.list_targets()[0]
        client = self.driver.ex_get_backup_details_for_target(
            "e75ead52-692f-4314-8725-c8a4f4d13a87").clients[0]
        self.assertTrue(
            self.driver.ex_remove_client_from_target(target, client))

    def test_ex_remove_client_from_target_STR(self):
        self.assertTrue(
            self.driver.ex_remove_client_from_target(
                "e75ead52-692f-4314-8725-c8a4f4d13a87",
                "30b1ff76-c76d-4d7c-b39d-3b72be0384c8",
            ))

    def test_ex_remove_client_from_target_FAIL(self):
        DimensionDataMockHttp.type = "FAIL"
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.ex_remove_client_from_target(
                "e75ead52-692f-4314-8725-c8a4f4d13a87",
                "30b1ff76-c76d-4d7c-b39d-3b72be0384c8",
            )
        self.assertEqual(context.exception.code, "ERROR")
        self.assertTrue(
            "Backup Client is currently performing another operation" in
            context.exception.msg)

    def test_priv_target_to_target_address(self):
        target = self.driver.list_targets()[0]
        self.assertEqual(
            self.driver._target_to_target_address(target),
            "e75ead52-692f-4314-8725-c8a4f4d13a87",
        )

    def test_priv_target_to_target_address_STR(self):
        self.assertEqual(
            self.driver._target_to_target_address(
                "e75ead52-692f-4314-8725-c8a4f4d13a87"),
            "e75ead52-692f-4314-8725-c8a4f4d13a87",
        )

    def test_priv_target_to_target_address_TYPEERROR(self):
        with self.assertRaises(TypeError):
            self.driver._target_to_target_address([1, 2, 3])

    def test_priv_client_to_client_id(self):
        client = self.driver.ex_get_backup_details_for_target(
            "e75ead52-692f-4314-8725-c8a4f4d13a87").clients[0]
        self.assertEqual(
            self.driver._client_to_client_id(client),
            "30b1ff76-c76d-4d7c-b39d-3b72be0384c8",
        )

    def test_priv_client_to_client_id_STR(self):
        self.assertEqual(
            self.driver._client_to_client_id(
                "30b1ff76-c76d-4d7c-b39d-3b72be0384c8"),
            "30b1ff76-c76d-4d7c-b39d-3b72be0384c8",
        )

    def test_priv_client_to_client_id_TYPEERROR(self):
        with self.assertRaises(TypeError):
            self.driver._client_to_client_id([1, 2, 3])
 def test_invalid_region(self):
     with self.assertRaises(ValueError):
         self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah')
 def setUp(self):
     DimensionData.connectionCls.active_api_version = '2.4'
     DimensionData.connectionCls.conn_class = DimensionDataMockHttp
     DimensionDataMockHttp.type = None
     self.driver = DimensionData(*DIMENSIONDATA_PARAMS)
class DimensionData_v2_4_Tests(unittest.TestCase, TestCaseMixin):

    def setUp(self):
        DimensionData.connectionCls.active_api_version = '2.4'
        DimensionData.connectionCls.conn_class = DimensionDataMockHttp
        DimensionDataMockHttp.type = None
        self.driver = DimensionData(*DIMENSIONDATA_PARAMS)

    def test_invalid_region(self):
        with self.assertRaises(ValueError):
            self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah')

    def test_invalid_creds(self):
        DimensionDataMockHttp.type = 'UNAUTHORIZED'
        with self.assertRaises(InvalidCredsError):
            self.driver.list_targets()

    def test_list_targets(self):
        targets = self.driver.list_targets()
        self.assertEqual(len(targets), 2)
        self.assertEqual(targets[0].id, '5579f3a7-4c32-4cf5-8a7e-b45c36a35c10')
        self.assertEqual(targets[0].address, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(targets[0].extra['servicePlan'], 'Enterprise')

    def test_create_target(self):
        target = self.driver.create_target(
            'name',
            'e75ead52-692f-4314-8725-c8a4f4d13a87',
            extra={'servicePlan': 'Enterprise'})
        self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f')
        self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(target.extra['servicePlan'], 'Enterprise')

    def test_create_target_DEFAULT(self):
        DimensionDataMockHttp.type = 'DEFAULT'
        target = self.driver.create_target(
            'name',
            'e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f')
        self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87')

    def test_create_target_EXISTS(self):
        DimensionDataMockHttp.type = 'EXISTS'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.create_target(
                'name',
                'e75ead52-692f-4314-8725-c8a4f4d13a87',
                extra={'servicePlan': 'Enterprise'})
        self.assertEqual(context.exception.code, 'ERROR')
        self.assertEqual(context.exception.msg, 'Cloud backup for this server is already enabled or being enabled (state: NORMAL).')

    def test_update_target(self):
        target = self.driver.list_targets()[0]
        extra = {'servicePlan': 'Essentials'}
        new_target = self.driver.update_target(target, extra=extra)
        self.assertEqual(new_target.extra['servicePlan'], 'Essentials')

    def test_update_target_DEFAULT(self):
        DimensionDataMockHttp.type = 'DEFAULT'
        target = 'e75ead52-692f-4314-8725-c8a4f4d13a87'
        self.driver.update_target(target)

    def test_update_target_STR(self):
        target = 'e75ead52-692f-4314-8725-c8a4f4d13a87'
        extra = {'servicePlan': 'Essentials'}
        new_target = self.driver.update_target(target, extra=extra)
        self.assertEqual(new_target.extra['servicePlan'], 'Essentials')

    def test_delete_target(self):
        target = self.driver.list_targets()[0]
        self.assertTrue(self.driver.delete_target(target))

    def test_ex_add_client_to_target(self):
        target = self.driver.list_targets()[0]
        client = self.driver.ex_list_available_client_types(target)[0]
        storage_policy = self.driver.ex_list_available_storage_policies(target)[0]
        schedule_policy = self.driver.ex_list_available_schedule_policies(target)[0]
        self.assertTrue(
            self.driver.ex_add_client_to_target(target, client, storage_policy,
                                                schedule_policy, 'ON_FAILURE', '*****@*****.**')
        )

    def test_ex_add_client_to_target_STR(self):
        self.assertTrue(
            self.driver.ex_add_client_to_target('e75ead52-692f-4314-8725-c8a4f4d13a87', 'FA.Linux', '14 Day Storage Policy',
                                                '12AM - 6AM', 'ON_FAILURE', '*****@*****.**')
        )

    def test_ex_get_backup_details_for_target(self):
        target = self.driver.list_targets()[0]
        response = self.driver.ex_get_backup_details_for_target(target)
        self.assertEqual(response.service_plan, 'Enterprise')
        client = response.clients[0]
        self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
        self.assertEqual(client.type.type, 'FA.Linux')
        self.assertEqual(client.running_job.progress, 5)
        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
        self.assertEqual(len(client.alert.notify_list), 2)
        self.assertTrue(isinstance(client.alert.notify_list, list))

    def test_ex_get_backup_details_for_target_NOBACKUP(self):
        target = self.driver.list_targets()[0].address
        DimensionDataMockHttp.type = 'NOBACKUP'
        response = self.driver.ex_get_backup_details_for_target(target)
        self.assertTrue(response is None)

    def test_ex_cancel_target_job(self):
        target = self.driver.list_targets()[0]
        response = self.driver.ex_get_backup_details_for_target(target)
        client = response.clients[0]
        self.assertTrue(isinstance(client.running_job, BackupTargetJob))
        success = client.running_job.cancel()
        self.assertTrue(success)

    def test_ex_cancel_target_job_with_extras(self):
        success = self.driver.cancel_target_job(
            None,
            ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8',
            ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87'
        )
        self.assertTrue(success)

    def test_ex_cancel_target_job_FAIL(self):
        DimensionDataMockHttp.type = 'FAIL'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.cancel_target_job(
                None,
                ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8',
                ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87'
            )
        self.assertEqual(context.exception.code, 'ERROR')

    """Test a backup info for a target that does not have a client"""
    def test_ex_get_backup_details_for_target_NO_CLIENT(self):
        DimensionDataMockHttp.type = 'NOCLIENT'
        response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(response.service_plan, 'Essentials')
        self.assertEqual(len(response.clients), 0)

    """Test a backup details that has a client, but no alerting or running jobs"""
    def test_ex_get_backup_details_for_target_NO_JOB_OR_ALERT(self):
        DimensionDataMockHttp.type = 'NOJOB'
        response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314_8725-c8a4f4d13a87')
        self.assertEqual(response.service_plan, 'Enterprise')
        self.assertTrue(isinstance(response.clients, list))
        self.assertEqual(len(response.clients), 1)
        client = response.clients[0]
        self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
        self.assertEqual(client.type.type, 'FA.Linux')
        self.assertIsNone(client.running_job)
        self.assertIsNone(client.alert)

    """Test getting backup info for a server that doesn't exist"""
    def test_ex_get_backup_details_for_target_DISABLED(self):
        DimensionDataMockHttp.type = 'DISABLED'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87')
        self.assertEqual(context.exception.code, 'ERROR')
        self.assertEqual(context.exception.msg, 'Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup')

    def test_ex_list_available_client_types(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_client_types(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].type, 'FA.Linux')
        self.assertEqual(answer[0].is_file_system, True)
        self.assertEqual(answer[0].description, 'Linux File system')

    def test_ex_list_available_storage_policies(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_storage_policies(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].name,
                         '30 Day Storage Policy + Secondary Copy')
        self.assertEqual(answer[0].retention_period, 30)
        self.assertEqual(answer[0].secondary_location, 'Primary')

    def test_ex_list_available_schedule_policies(self):
        target = self.driver.list_targets()[0]
        answer = self.driver.ex_list_available_schedule_policies(target)
        self.assertEqual(len(answer), 1)
        self.assertEqual(answer[0].name, '12AM - 6AM')
        self.assertEqual(answer[0].description, 'Daily backup will start between 12AM - 6AM')

    def test_ex_remove_client_from_target(self):
        target = self.driver.list_targets()[0]
        client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0]
        self.assertTrue(self.driver.ex_remove_client_from_target(target, client))

    def test_ex_remove_client_from_target_STR(self):
        self.assertTrue(
            self.driver.ex_remove_client_from_target(
                'e75ead52-692f-4314-8725-c8a4f4d13a87',
                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
            )
        )

    def test_ex_remove_client_from_target_FAIL(self):
        DimensionDataMockHttp.type = 'FAIL'
        with self.assertRaises(DimensionDataAPIException) as context:
            self.driver.ex_remove_client_from_target(
                'e75ead52-692f-4314-8725-c8a4f4d13a87',
                '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
            )
        self.assertEqual(context.exception.code, 'ERROR')
        self.assertTrue('Backup Client is currently performing another operation' in context.exception.msg)

    def test_priv_target_to_target_address(self):
        target = self.driver.list_targets()[0]
        self.assertEqual(
            self.driver._target_to_target_address(target),
            'e75ead52-692f-4314-8725-c8a4f4d13a87'
        )

    def test_priv_target_to_target_address_STR(self):
        self.assertEqual(
            self.driver._target_to_target_address('e75ead52-692f-4314-8725-c8a4f4d13a87'),
            'e75ead52-692f-4314-8725-c8a4f4d13a87'
        )

    def test_priv_target_to_target_address_TYPEERROR(self):
        with self.assertRaises(TypeError):
            self.driver._target_to_target_address([1, 2, 3])

    def test_priv_client_to_client_id(self):
        client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0]
        self.assertEqual(
            self.driver._client_to_client_id(client),
            '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
        )

    def test_priv_client_to_client_id_STR(self):
        self.assertEqual(
            self.driver._client_to_client_id('30b1ff76-c76d-4d7c-b39d-3b72be0384c8'),
            '30b1ff76-c76d-4d7c-b39d-3b72be0384c8'
        )

    def test_priv_client_to_client_id_TYPEERROR(self):
        with self.assertRaises(TypeError):
            self.driver._client_to_client_id([1, 2, 3])