You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by an...@apache.org on 2016/02/10 02:08:38 UTC
[2/5] libcloud git commit: DimensionData: Backups adding more tests,
moving classes to common
DimensionData: Backups adding more tests, moving classes to common
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/67f7e06f
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/67f7e06f
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/67f7e06f
Branch: refs/heads/trunk
Commit: 67f7e06fad55660be8d67c377f18167cce516803
Parents: bb8ab66
Author: Jeffrey Dunham <je...@gmail.com>
Authored: Tue Feb 9 18:05:34 2016 -0500
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Feb 10 12:08:06 2016 +1100
----------------------------------------------------------------------
libcloud/backup/drivers/dimensiondata.py | 118 ++++-------
libcloud/common/dimensiondata.py | 209 +++++++++++++++++++
..._692f_4314_8725_c8a4f4d13a87_backup_INFO.xml | 27 ++-
...4_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml | 7 +
...4_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml | 2 +
...4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml | 11 +
libcloud/test/backup/test_dimensiondata.py | 75 ++++++-
7 files changed, 361 insertions(+), 88 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/backup/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/backup/drivers/dimensiondata.py b/libcloud/backup/drivers/dimensiondata.py
index 45fb1d7..41cc9f7 100644
--- a/libcloud/backup/drivers/dimensiondata.py
+++ b/libcloud/backup/drivers/dimensiondata.py
@@ -22,69 +22,18 @@ from libcloud.backup.base import BackupDriver, BackupTarget
from libcloud.backup.types import BackupTargetType
from libcloud.backup.types import Provider
from libcloud.common.dimensiondata import DimensionDataConnection
-from libcloud.common.dimensiondata import API_ENDPOINTS
-from libcloud.common.dimensiondata import DEFAULT_REGION
+from libcloud.common.dimensiondata import DimensionDataBackupClientType
+from libcloud.common.dimensiondata import DimensionDataBackupDetails
+from libcloud.common.dimensiondata import DimensionDataBackupClient
+from libcloud.common.dimensiondata import DimensionDataBackupClientAlert
+from libcloud.common.dimensiondata import DimensionDataBackupClientRunningJob
+from libcloud.common.dimensiondata import DimensionDataBackupStoragePolicy
+from libcloud.common.dimensiondata import DimensionDataBackupSchedulePolicy
+from libcloud.common.dimensiondata import API_ENDPOINTS, DEFAULT_REGION
from libcloud.common.dimensiondata import TYPES_URN
-from libcloud.common.dimensiondata import GENERAL_NS
+from libcloud.common.dimensiondata import GENERAL_NS, BACKUP_NS
from libcloud.utils.xml import fixxpath, findtext, findall
-BACKUP_NS = 'http://oec.api.opsource.net/schemas/backup'
-
-
-class DimensionDataBackupClientType(object):
- def __init__(self, type, is_file_system, description):
- self.type = type
- self.is_file_system = is_file_system
- self.description = description
-
-
-class DimensionDataBackupDetails(object):
- def __init__(self, asset_id, service_plan, state, clients=[]):
- self.asset_id = asset_id
- self.service_plan = service_plan
- self.state = state
- self.clients = clients
-
-
-class DimensionDataBackupClient(object):
- def __init__(self, type, is_file_system, status, description,
- schedule_pol, storage_pol, trigger=None, email=None,
- last_backup_time=None, next_backup=None, download_url=None,
- total_backup_size=None, running_job=None):
- self.type = type
- self.is_file_system = is_file_system
- self.status = status
- self.description = description
- self.schedule_policy = schedule_pol
- self.storage_policy = storage_pol
- self.trigger = trigger
- self.email = email
- self.last_backup_time = last_backup_time
- self.next_backup = next_backup
- self.total_backup_size = total_backup_size
- self.download_url = download_url
- self.running_job = running_job
-
-
-class DimensionDataBackupRunningJob(object):
- def __init__(self, id, status, percentage=0):
- self.id = id
- self.percentage = percentage
- self.status = status
-
-
-class DimensionDataBackupStoragePolicy(object):
- def __init__(self, name, retention_period, secondary_location):
- self.name = name
- self.retention_period = retention_period
- self.secondary_location = secondary_location
-
-
-class DimensionDataBackupSchedulePolicy(object):
- def __init__(self, name, description):
- self.name = name
- self.description = description
-
class DimensionDataBackupDriver(BackupDriver):
"""
@@ -579,9 +528,12 @@ class DimensionDataBackupDriver(BackupDriver):
return [self._to_client_type(el) for el in elements]
def _to_client_type(self, element):
+ description = element.get('description')
+ if description is None:
+ description = findtext(element, 'description', BACKUP_NS)
return DimensionDataBackupClientType(
type=element.get('type'),
- description=element.get('description'),
+ description=description,
is_file_system=bool(element.get('isFileSystem') == 'true')
)
@@ -599,26 +551,40 @@ class DimensionDataBackupDriver(BackupDriver):
return [self._to_client(el) for el in elements]
def _to_client(self, element):
- job = element.find(fixxpath('runningJob', BACKUP_NS))
- running_job = None
- if job is not None:
- running_job = DimensionDataBackupRunningJob(
- id=job.get('id'),
- status=job.get('status'),
- percentage=int(job.get('percentageComplete'))
- )
-
return DimensionDataBackupClient(
- type=element.get('type'),
- is_file_system=bool(element.get('isFileSystem') == 'true'),
+ id=element.get('id'),
+ type=self._to_client_type(element, ),
status=element.get('status'),
- description=findtext(element, 'description', BACKUP_NS),
- schedule_pol=findtext(element, 'schedulePolicyName', BACKUP_NS),
- storage_pol=findtext(element, 'storagePolicyName', BACKUP_NS),
+ schedule_policy=findtext(element, 'schedulePolicyName', BACKUP_NS),
+ storage_policy=findtext(element, 'storagePolicyName', BACKUP_NS),
download_url=findtext(element, 'downloadUrl', BACKUP_NS),
- running_job=running_job
+ running_job=self._to_running_job(element),
+ alert=self._to_alert(element)
)
+ def _to_alert(self, element):
+ alert = element.find(fixxpath('alerting', BACKUP_NS))
+ if alert is not None:
+ notify_list = [
+ email_addr.text for email_addr
+ in alert.findall(fixxpath('emailAddress', BACKUP_NS))
+ ]
+ return DimensionDataBackupClientAlert(
+ trigger=element.get('trigger'),
+ notify_list=notify_list
+ )
+ return None
+
+ def _to_running_job(self, element):
+ running_job = element.find(fixxpath('runningJob', BACKUP_NS))
+ if running_job is not None:
+ return DimensionDataBackupClientRunningJob(
+ id=running_job.get('id'),
+ status=running_job.get('status'),
+ percentage=int(running_job.get('percentageComplete'))
+ )
+ return None
+
def _to_targets(self, object):
node_elements = object.findall(fixxpath('server', TYPES_URN))
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/common/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/common/dimensiondata.py b/libcloud/common/dimensiondata.py
index 841f790..5ecd89e 100644
--- a/libcloud/common/dimensiondata.py
+++ b/libcloud/common/dimensiondata.py
@@ -35,6 +35,7 @@ SERVER_NS = NAMESPACE_BASE + "/server"
NETWORK_NS = NAMESPACE_BASE + "/network"
DIRECTORY_NS = NAMESPACE_BASE + "/directory"
GENERAL_NS = NAMESPACE_BASE + "/general"
+BACKUP_NS = NAMESPACE_BASE + "/backup"
# API 2.0 Namespaces and URNs
TYPES_URN = "urn:didata.com:api:cloud:types"
@@ -812,3 +813,211 @@ class DimensionDataVirtualListenerCompatibility(object):
return (('<DimensionDataVirtualListenerCompatibility: '
'type=%s, protocol=%s>')
% (self.type, self.protocol))
+
+
+class DimensionDataBackupClientType(object):
+ """
+ A client type object for backups
+ """
+ def __init__(self, type, is_file_system, description):
+ """
+ Initialize an instance of :class:`DimensionDataBackupClientType`
+
+ :param type: The type of client i.e. (FA.Linux, MySQL, ect.)
+ :type type: ``str``
+
+ :param is_file_system: The name of the iRule
+ :type is_file_system: ``bool``
+
+ :param description: Description of the client
+ :type description: ``str``
+ """
+ self.type = type
+ self.is_file_system = is_file_system
+ self.description = description
+
+ def __repr__(self):
+ return (('<DimensionDataBackupClientType: type=%s>')
+ % (self.type))
+
+
+class DimensionDataBackupDetails(object):
+ """
+ Dimension Data Backup Details represents information about
+ a targets backups configuration
+ """
+
+ def __init__(self, asset_id, service_plan, state, clients=None):
+ """
+ Initialize an instance of :class:`DimensionDataBackupDetails`
+
+ :param asset_id: Asset identification for backups
+ :type asset_id: ``str``
+
+ :param service_plan: The service plan for backups. i.e (Essentials)
+ :type service_plan: ``str``
+
+ :param state: The overall state this backup target. i.e. (unregistered)
+ :type state: ``str``
+
+ :param clients: Backup clients attached to this target
+ :type clients: ``list`` of :class:`DimensionDataBackupClient`
+ """
+ self.asset_id = asset_id
+ self.service_plan = service_plan
+ self.state = state
+ self.clients = clients
+
+ def __repr__(self):
+ return (('<DimensionDataBackupDetails: id=%s>')
+ % (self.asset_id))
+
+
+class DimensionDataBackupClient(object):
+ """
+ An object that represents a backup client
+ """
+ def __init__(self, id, type, status,
+ schedule_policy, storage_policy, download_url,
+ alert=None, running_job=None):
+ """
+ Initialize an instance of :class:`DimensionDataBackupClient`
+
+ :param id: Unique ID for the client
+ :type id: ``str``
+
+ :param type: The type of client that this client is
+ :type type: :class:`DimensionDataBackupClientType`
+
+ :param status: The states of this particular backup client.
+ i.e. (Unregistered)
+ :type status: ``str``
+
+ :param schedule_policy: The schedule policy for this client
+ NOTE: Dimension Data only sends back the name
+ of the schedule policy, no further details
+ :type schedule_policy: ``str``
+
+ :param storage_policy: The storage policy for this client
+ NOTE: Dimension Data only sends back the name
+ of the storage policy, no further details
+ :type storage_policy: ``str``
+
+ :param download_url: The download url for this client
+ :type download_url: ``str``
+
+ :param alert: The alert configured for this backup client (optional)
+ :type alert: :class:`DimensionDataBackupClientAlert`
+
+ :param alert: The running job for the client (optional)
+ :type alert: :class:`DimensionDataBackupClientRunningJob`
+ """
+ self.id = id
+ self.type = type
+ self.status = status
+ self.schedule_policy = schedule_policy
+ self.storage_policy = storage_policy
+ self.download_url = download_url
+ self.alert = alert
+ self.running_job = running_job
+
+ def __repr__(self):
+ return (('<DimensionDataBackupClient: id=%s>')
+ % (self.asset_id))
+
+
+class DimensionDataBackupClientAlert(object):
+ """
+ An alert for a backup client
+ """
+ def __init__(self, trigger, notify_list=[]):
+ """
+ Initialize an instance of :class:`DimensionDataBackupClientAlert`
+
+ :param trigger: Trigger type for the client i.e. ON_FAILURE
+ :type trigger: ``str``
+
+ :param notify_list: List of email addresses that are notified
+ when the alert is fired
+ :type notify_list: ``list`` of ``str``
+ """
+ self.trigger = trigger
+ self.notify_list = notify_list
+
+ def __repr__(self):
+ return (('<DimensionDataBackupClient: id=%s>')
+ % (self.asset_id))
+
+
+class DimensionDataBackupClientRunningJob(object):
+ """
+ A running job for a given backup client
+ """
+ def __init__(self, id, status, percentage=0):
+ """
+ Initialize an instance of :class:`DimensionDataBackupClientRunningJob`
+
+ :param id: The unqiue ID of the job
+ :type id: ``str``
+
+ :param status: The status of the job i.e. Waiting
+ :type status: ``str``
+
+ :param percentage: The percentage completion of the job
+ :type percentage: ``int``
+ """
+ self.id = id
+ self.percentage = percentage
+ self.status = status
+
+ def __repr__(self):
+ return (('<DimensionDataBackupClientRunningJob: id=%s>')
+ % (self.id))
+
+
+class DimensionDataBackupStoragePolicy(object):
+ """
+ A representation of a storage policy
+ """
+ def __init__(self, name, retention_period, secondary_location):
+ """
+ Initialize an instance of :class:`DimensionDataBackupStoragePolicy`
+
+ :param name: The name of the storage policy i.e. 14 Day Storage Policy
+ :type name: ``str``
+
+ :param retention_period: How long to keep the backup in days
+ :type retention_period: ``int``
+
+ :param secondary_location: The secondary location i.e. Primary
+ :type secondary_location: ``str``
+ """
+ self.name = name
+ self.retention_period = retention_period
+ self.secondary_location = secondary_location
+
+ def __repr__(self):
+ return (('<DimensionDataBackupClientStoragePolicy: name=%s>')
+ % (self.name))
+
+
+class DimensionDataBackupSchedulePolicy(object):
+ """
+ A representation of a schedule policy
+ """
+ def __init__(self, name, description):
+ """
+ Initialize an instance of :class:`DimensionDataBackupSchedulePolicy`
+
+ :param name: The name of the policy i.e 12AM - 6AM
+ :type name: ``str``
+
+ :param description: Short summary of the details of the policy
+ :type description: ``str``
+ """
+ self.name = name
+ self.description = description
+
+ def __repr__(self):
+ return (('<DimensionDataBackupClientSchedulePolicy: name=%s>')
+ % (self.name))
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
index 8b5cf55..fc61cce 100644
--- a/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
+++ b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml
@@ -1,11 +1,16 @@
-<ns5:BackupDetails assetId="fbf90c74-a6de-459e-942c-b75b5176ed72" servicePlan="Enterprise" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns="http://oec.api.opsource.net/schemas/server" xmlns:ns14="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns15="http://oec.api.opsource.net/schemas/reset" xmlns:ns9="http://oec.api.opsource.net/schemas/storage" xmlns:ns5="http://oec.api.opsource.net/schemas/backup" xmlns:ns12="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns13="http://oec.api.opsource.net/schemas/general" xmlns:ns6="http://oec.api.opsource.net/schemas/support" xmlns:ns7="http://oec.api.opsource.net/schemas/organization" xmlns:ns10="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns8="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns11="http://oec.api.opsource.net/schemas/vip" xmlns:ns2="http://oec.api.opsource.net/schemas/network" xmlns:ns4="http://oec.api.opsource.net/schemas/directory" xmlns:ns3="http://oec.api.ops
ource.net/schemas/admin">
- <ns5:backupClient id="5fe7502e-f8d7-4547-93b5-f54ac6e58281" type="FA.Linux" isFileSystem="true" status="Offline">
- <ns5:description>Linux File Agent</ns5:description>
- <ns5:schedulePolicyName>12AM - 6AM</ns5:schedulePolicyName>
- <ns5:storagePolicyName>30 Day Storage Policy + Secondary Copy</ns5:storagePolicyName>
- <ns5:times nextBackup="2016-02-09T00:00:00" lastOnline="2016-02-08T06:10:25"/>
- <ns5:totalBackupSizeGb>0</ns5:totalBackupSizeGb>
- <ns5:downloadUrl>https://backups-na.cloud-vpn.net/PCS/BackupClientInstallerDownload/27645708a713cf406b47ccf73895cc8d27d4172c</ns5:downloadUrl>
- <ns5:runningJob id="106130" name="Backup" percentageComplete="5" status="Waiting"/>
- </ns5:backupClient>
-</ns5:BackupDetails>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns9:BackupDetails assetId="12769311-938c-4669-9460-7723eb194269" servicePlan="Enterprise" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.o
psource.net/schemas/vip">
+ <ns9:backupClient id="30b1ff76-c76d-4d7c-b39d-3b72be0384c8" type="FA.Linux" isFileSystem="true" status="Unregistered">
+ <ns9:description>Linux File Agent</ns9:description>
+ <ns9:schedulePolicyName>12AM - 6AM</ns9:schedulePolicyName>
+ <ns9:storagePolicyName>14 Day Storage Policy</ns9:storagePolicyName>
+ <ns9:alerting trigger="ON_FAILURE">
+ <ns9:emailAddress>fake_email@example.com</ns9:emailAddress>
+ <ns9:emailAddress>fake_email2@example.com</ns9:emailAddress>
+ </ns9:alerting>
+ <ns9:times nextBackup="2016-02-09T00:00:00" lastOnline="2016-02-08T06:10:25"/>
+ <ns9:totalBackupSizeGb>0</ns9:totalBackupSizeGb>
+ <ns9:downloadUrl>https://backups-na.cloud-vpn.net/PCS/BackupClientInstallerDownload/cbb8a8c607ca4144e8828814edfc1634c8dd8782</ns9:downloadUrl>
+ <ns9:runningJob id="106130" name="Backup" percentageComplete="5" status="Waiting"/>
+ </ns9:backupClient>
+</ns9:BackupDetails>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml
new file mode 100644
index 0000000..c3a9c37
--- /dev/null
+++ b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns6:Status xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.opsource.net/schemas/vip">
+ <ns6:operation>Get Backup Details</ns6:operation>
+ <ns6:result>ERROR</ns6:result>
+ <ns6:resultDetail>Server e75ead52-692f-4314_8725-c8a4f4d13a87 has not been provisioned for backup</ns6:resultDetail>
+ <ns6:resultCode>REASON_543</ns6:resultCode>
+</ns6:Status>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml
new file mode 100644
index 0000000..0f62576
--- /dev/null
+++ b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns9:BackupDetails assetId="71febbbc-337a-40c4-8c29-0afe85ccb3ea" servicePlan="Essentials" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.o
psource.net/schemas/vip"/>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml
new file mode 100644
index 0000000..45c97ce
--- /dev/null
+++ b/libcloud/test/backup/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns9:BackupDetails assetId="12769311-938c-4669-9460-7723eb194269" servicePlan="Enterprise" state="NORMAL" xmlns:ns16="http://oec.api.opsource.net/schemas/storage" xmlns="http://oec.api.opsource.net/schemas/admin" xmlns:ns14="http://oec.api.opsource.net/schemas/directory" xmlns:ns15="http://oec.api.opsource.net/schemas/multigeo" xmlns:ns9="http://oec.api.opsource.net/schemas/backup" xmlns:ns5="http://oec.api.opsource.net/schemas/datacenter" xmlns:ns12="http://oec.api.opsource.net/schemas/support" xmlns:ns13="http://oec.api.opsource.net/schemas/manualimport" xmlns:ns6="http://oec.api.opsource.net/schemas/general" xmlns:ns7="http://oec.api.opsource.net/schemas/reset" xmlns:ns10="http://oec.api.opsource.net/schemas/server" xmlns:ns8="http://oec.api.opsource.net/schemas/network" xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel" xmlns:ns2="http://oec.api.opsource.net/schemas/organization" xmlns:ns4="http://oec.api.opsource.net/schemas/serverbootstrap" xmlns:ns3="http://oec.api.o
psource.net/schemas/vip">
+ <ns9:backupClient id="30b1ff76-c76d-4d7c-b39d-3b72be0384c8" type="FA.Linux" isFileSystem="true" status="Unregistered">
+ <ns9:description>Linux File Agent</ns9:description>
+ <ns9:schedulePolicyName>12AM - 6AM</ns9:schedulePolicyName>
+ <ns9:storagePolicyName>14 Day Storage Policy</ns9:storagePolicyName>
+ <ns9:times nextBackup="2016-02-09T00:00:00" lastOnline="2016-02-08T06:10:25"/>
+ <ns9:totalBackupSizeGb>0</ns9:totalBackupSizeGb>
+ <ns9:downloadUrl>https://backups-na.cloud-vpn.net/PCS/BackupClientInstallerDownload/cbb8a8c607ca4144e8828814edfc1634c8dd8782</ns9:downloadUrl>
+ </ns9:backupClient>
+</ns9:BackupDetails>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/67f7e06f/libcloud/test/backup/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/backup/test_dimensiondata.py b/libcloud/test/backup/test_dimensiondata.py
index fe5a964..5ce91e3 100644
--- a/libcloud/test/backup/test_dimensiondata.py
+++ b/libcloud/test/backup/test_dimensiondata.py
@@ -100,8 +100,39 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
response = self.driver.ex_get_backup_details_for_target(target)
self.assertEqual(response.service_plan, 'Enterprise')
client = response.clients[0]
- self.assertEqual(client.type, 'FA.Linux')
+ self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8')
+ self.assertEqual(client.type.type, 'FA.Linux')
self.assertEqual(client.running_job.percentage, 5)
+ self.assertEqual(len(client.alert.notify_list), 2)
+ self.assertTrue(isinstance(client.alert.notify_list, list))
+
+ """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]
@@ -152,6 +183,18 @@ class DimensionDataMockHttp(MockHttp):
body = self.fixtures.load('oec_0_9_myaccount.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _oec_0_9_myaccount_NOCLIENT(self, method, url, body, headers):
+ body = self.fixtures.load('oec_0_9_myaccount.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _oec_0_9_myaccount_DISABLED(self, method, url, body, headers):
+ body = self.fixtures.load('oec_0_9_myaccount.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _oec_0_9_myaccount_NOJOB(self, method, url, body, headers):
+ body = self.fixtures.load('oec_0_9_myaccount.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers):
body = self.fixtures.load(
'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml')
@@ -183,6 +226,33 @@ class DimensionDataMockHttp(MockHttp):
else:
raise ValueError("Unknown Method {0}".format(method))
+ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOCLIENT(
+ self, method, url, body, headers):
+ # only gets here are implemented
+ # If we get any other method something has gone wrong
+ assert(method == 'GET')
+ body = self.fixtures.load(
+ 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLED(
+ self, method, url, body, headers):
+ # only gets here are implemented
+ # If we get any other method something has gone wrong
+ assert(method == 'GET')
+ body = self.fixtures.load(
+ 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
+ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOJOB(
+ self, method, url, body, headers):
+ # only gets here are implemented
+ # If we get any other method something has gone wrong
+ assert(method == 'GET')
+ body = self.fixtures.load(
+ 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup(
self, method, url, body, headers):
if method == 'POST':
@@ -203,6 +273,9 @@ class DimensionDataMockHttp(MockHttp):
def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS(
self, method, url, body, headers):
+ # only POSTs are implemented
+ # If we get any other method something has gone wrong
+ assert(method == 'POST')
body = self.fixtures.load(
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml')
return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])