Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DimensionData: Adding in new methods/tests for backups #695

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 150 additions & 26 deletions libcloud/backup/drivers/dimensiondata.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,18 @@
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 DimensionDataBackupClient
from libcloud.common.dimensiondata import DimensionDataBackupClientAlert
from libcloud.common.dimensiondata import DimensionDataBackupClientRunningJob
from libcloud.common.dimensiondata import DimensionDataBackupClientType
from libcloud.common.dimensiondata import DimensionDataBackupDetails
from libcloud.common.dimensiondata import DimensionDataBackupSchedulePolicy
from libcloud.common.dimensiondata import DimensionDataBackupStoragePolicy
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 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):
"""
Expand Down Expand Up @@ -232,6 +216,8 @@ def delete_target(self, target):

:param target: Backup target to delete
:type target: Instance of :class:`BackupTarget`

:rtype: ``bool``
"""
response = self.connection.request_with_orgId_api_1(
'server/%s/backup?disable' % (target.address),
Expand Down Expand Up @@ -384,6 +370,93 @@ def cancel_target_job(self, target, job):
raise NotImplementedError(
'cancel_target_job not implemented for this driver')

def ex_add_client_to_target(self, target, client_type, storage_policy,
schedule_policy, trigger, email):
"""
Add a client to a target

:param target: Backup target with the backup data
:type target: Instance of :class:`BackupTarget` or ``str``

:param client: Client to add to the target
:type client: Instance of :class:`DimensionDataBackupClientType`
or ``str``

:param storage_policy: The storage policy for the client
:type storage_policy: Instance of
:class:`DimensionDataBackupStoragePolicy`
or ``str``

:param schedule_policy: The schedule policy for the client
:type schedule_policy: Instance of
:class:`DimensionDataBackupSchedulePolicy`
or ``str``

:param trigger: The notify trigger for the client
:type trigger: ``str``

:param email: The notify email for the client
:type email: ``str``

:rtype: ``bool``
"""

if isinstance(target, BackupTarget):
server_id = target.address
else:
server_id = target

backup_elm = ET.Element('NewBackupClient',
{'xmlns': BACKUP_NS})
if isinstance(client_type, DimensionDataBackupClientType):
ET.SubElement(backup_elm, "type").text = client_type.type
else:
ET.SubElement(backup_elm, "type").text = client_type

if isinstance(storage_policy, DimensionDataBackupStoragePolicy):
ET.SubElement(backup_elm,
"storagePolicyName").text = storage_policy.name
else:
ET.SubElement(backup_elm,
"storagePolicyName").text = storage_policy

if isinstance(schedule_policy, DimensionDataBackupSchedulePolicy):
ET.SubElement(backup_elm,
"schedulePolicyName").text = schedule_policy.name
else:
ET.SubElement(backup_elm,
"schedulePolicyName").text = schedule_policy

alerting_elm = ET.SubElement(backup_elm, "alerting")
alerting_elm.set('trigger', trigger)
ET.SubElement(alerting_elm, "emailAddress").text = email

response = self.connection.request_with_orgId_api_1(
'server/%s/backup/client' % (server_id),
method='POST',
data=ET.tostring(backup_elm)).object
response_code = findtext(response, 'result', GENERAL_NS)
return response_code in ['IN_PROGRESS', 'SUCCESS']

def ex_get_backup_details_for_target(self, target):
"""
Returns a list of available backup client types

:param target: The backup target to list available types for
:type target: :class:`BackupTarget` or ``str``

:rtype: ``list`` of :class:`DimensionDataBackupDetails`
"""

if isinstance(target, BackupTarget):
server_id = target.address
else:
server_id = target
response = self.connection.request_with_orgId_api_1(
'server/%s/backup' % (server_id),
method='GET').object
return self._to_backup_details(response)

def ex_list_available_client_types(self, target):
"""
Returns a list of available backup client types
Expand Down Expand Up @@ -455,12 +528,63 @@ def _to_client_types(self, object):
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')
)

def _to_backup_details(self, object):
return DimensionDataBackupDetails(
asset_id=object.get('asset_id'),
service_plan=object.get('servicePlan'),
state=object.get('state'),
clients=self._to_clients(object)
)

def _to_clients(self, object):
elements = object.findall(fixxpath('backupClient', BACKUP_NS))

return [self._to_client(el) for el in elements]

def _to_client(self, element):
return DimensionDataBackupClient(
id=element.get('id'),
type=self._to_client_type(element, ),
status=element.get('status'),
schedule_policy=findtext(element, 'schedulePolicyName', BACKUP_NS),
storage_policy=findtext(element, 'storagePolicyName', BACKUP_NS),
download_url=findtext(element, 'downloadUrl', BACKUP_NS),
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))

Expand Down
Loading