freezer-web-ui/freezer_ui/api/api.py

294 lines
8.5 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Some helper functions to use the freezer_ui client functionality
from horizon.
"""
from django.conf import settings
import warnings
import freezer.apiclient.client
from horizon.utils import functions as utils
from horizon.utils.memoized import memoized # noqa
class Dict2Object(object):
"""Makes dictionary fields accessible as if they are attributes.
The dictionary keys become class attributes. It is possible to use one
nested dictionary by overwriting nested_dict with the key of that nested
dict.
This class is needed because we mostly deal with objects in horizon (e.g.
for providing data to the tables) but the api only gives us json data.
"""
nested_dict = None
def __init__(self, data_dict):
self.data_dict = data_dict
def __getattr__(self, attr):
"""Make data_dict fields available via class interface """
if attr in self.data_dict:
return self.data_dict[attr]
elif attr in self.data_dict[self.nested_dict]:
return self.data_dict[self.nested_dict][attr]
else:
return object.__getattribute__(self, attr)
def get_dict(self):
return self.data_dict
class Action(Dict2Object):
nested_dict = 'job'
@property
def id(self):
return self.action_id
class Configuration(Dict2Object):
nested_dict = 'config_file'
@property
def id(self):
return self.config_id
class Backup(Dict2Object):
nested_dict = 'backup_metadata'
@property
def id(self):
return self.backup_id
class Client(Dict2Object):
nested_dict = 'client'
@property
def id(self):
return self.client_id
@property
def name(self):
return self.client_id
class ConfigClient(object):
def __init__(self, name, last_backup):
self.id = name
self.name = name
self.last_backup = last_backup
@memoized
def _freezerclient(request):
warnings.warn('Endpoint discovery not implemented yet. Using hard-coded: {'
'}'.format(settings.FREEZER_API_URL))
return freezer.apiclient.client.Client(
token=request.user.token.id,
auth_url=getattr(settings, 'OPENSTACK_KEYSTONE_URL'),
endpoint=settings.FREEZER_API_URL)
def configuration_create(request, name=None, container_name=None,
src_file=None, levels=None, optimize=None,
compression=None, encryption_password=None,
clients=[], start_datetime=None, interval=None,
exclude=None, log_file=None, proxy=None,
max_priority=False):
"""Create a new configuration file """
data = {
"name": name,
"container_name": container_name,
"src_file": src_file,
"levels": levels,
"optimize": optimize,
"compression": compression,
"encryption_password": encryption_password,
"clients": clients,
"start_datetime": start_datetime,
"interval": interval,
"exclude": exclude,
"log_file": log_file,
"proxy": proxy,
"max_priority": max_priority
}
return _freezerclient(request).configs.create(data)
def configuration_update(request, config_id=None, name=None,
src_file=None, levels=None, optimize=None,
compression=None, encryption_password=None,
clients=[], start_datetime=None, interval=None,
exclude=None, log_file=None, proxy=None,
max_priority=False, container_name=None,):
"""Update a new configuration file """
data = {
"name": name,
"container_name": container_name,
"src_file": src_file,
"levels": levels,
"optimize": optimize,
"compression": compression,
"encryption_password": encryption_password,
"clients": clients,
"start_datetime": start_datetime,
"interval": interval,
"exclude": exclude,
"log_file": log_file,
"proxy": proxy,
"max_priority": max_priority
}
return _freezerclient(request).configs.update(config_id, data)
def configuration_delete(request, obj_id):
return _freezerclient(request).configs.delete(obj_id)
def configuration_clone(request, config_id):
config_file = _freezerclient(request).configs.get(config_id)
data = config_file[0]['config_file']
data['name'] = '{0}_clone'.format(data['name'])
return _freezerclient(request).configs.create(data)
def configuration_get(request, config_id):
config_file = _freezerclient(request).configs.get(config_id)
if config_file:
return [Configuration(data) for data in config_file]
return []
def configuration_list(request):
configurations = _freezerclient(request).configs.list()
configurations = [Configuration(data) for data in configurations]
return configurations
def clients_in_config(request, config_id):
configuration = configuration_get(request, config_id)
clients = []
last_backup = None
clients_dict = [c.get_dict() for c in configuration]
for client in clients_dict:
for client_id in client['config_file']['clients']:
backups, has_more = backups_list(request, text_match=client_id)
backups = [Backup(data) for data in backups]
backups = [b.get_dict() for b in backups]
for backup in backups:
last_backup = backup.data_dict['backup_metadata']['timestamp']
clients.append(ConfigClient(client_id, last_backup))
return clients
def client_list(request, limit=20):
clients = _freezerclient(request).registration.list(limit=limit)
clients = [Client(client) for client in clients]
return clients
def backups_list(request, offset=0, time_after=None, time_before=None,
text_match=None):
page_size = utils.get_page_size(request)
search = {}
if time_after:
search['time_after'] = time_after
if time_before:
search['time_before'] = time_before
if text_match:
search['match'] = [
{
"_all": text_match,
}
]
backups = _freezerclient(request).backups.list(
limit=page_size + 1,
offset=offset,
search=search)
if len(backups) > page_size:
backups.pop()
has_more = True
else:
has_more = False
# Wrap data in object for easier handling
backups = [Backup(data) for data in backups]
return backups, has_more
def backup_get(request, backup_id):
data = _freezerclient(request).backups.get(backup_id)
if data:
return Backup(data[0])
def restore_action_create(request,
backup_id,
destination_client_id,
destination_path,
description=None,
dry_run=False,
max_prio=False):
c = _freezerclient(request)
backup = c.backups.get(backup_id)[0]
action = {
"job": {
"action": "restore",
"container_name": backup['backup_metadata']['container'],
"restore-abs-path": destination_path,
"backup-name": backup['backup_metadata']['backup_name'],
"restore-from-host": backup['backup_metadata']['host_name'],
"max_cpu_priority": max_prio,
"dry_run": dry_run
},
"description": description,
"client_id": destination_client_id
}
c.actions.create(action)
def actions_list(request, offset=0):
page_size = utils.get_page_size(request)
actions = _freezerclient(request).actions.list(
limit=page_size + 1,
offset=offset)
if len(actions) > page_size:
actions.pop()
has_more = True
else:
has_more = False
# Wrap data in object for easier handling
actions = [Action(data['action']) for data in actions]
return actions, has_more