Repository URL to install this package:
|
Version:
6.0.24-6.0 ▾
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 TrilioData, Inc.
# All Rights Reserved.
"""Implementation of SQLAlchemy backend."""
from datetime import datetime, timedelta
import os
import uuid
import json
import warnings
import threading
from oslo_config import cfg
import sqlalchemy
import sqlalchemy.orm as sa_orm
import sqlalchemy.sql as sa_sql
from sqlalchemy import or_
from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import literal_column, cast
from sqlalchemy.sql import func
from sqlalchemy import and_
from sqlalchemy import Integer
from sqlalchemy import asc, desc
from workloadmgr.common import sqlalchemyutils
from workloadmgr import db
from workloadmgr.db.sqlalchemy import models
from workloadmgr.db.sqlalchemy.session import get_session
from workloadmgr import exception
from workloadmgr import flags
from workloadmgr.openstack.common.gettextutils import _
from workloadmgr.openstack.common import log as logging
from workloadmgr.openstack.common import timeutils
from workloadmgr.openstack.common import uuidutils
from workloadmgr.apscheduler import job
from workloadmgr.vault import vault
from workloadmgr.virt import qemuimages
from workloadmgr.openstack.common.gettextutils import _
FLAGS = flags.FLAGS
LOG = logging.getLogger(__name__)
lock = threading.Lock()
CONF = cfg.CONF
def is_admin_context(context):
"""Indicates if the request context is an administrator."""
if not context:
warnings.warn(_('Use of empty request context is deprecated'),
DeprecationWarning)
raise Exception('die')
return context.is_admin
def is_user_context(context):
"""Indicates if the request context is a normal user."""
if not context:
return False
if context.is_admin:
return False
if not context.user_id or not context.project_id:
return False
return True
def authorize_project_context(context, project_id):
"""Ensures a request has permission to access the given project."""
if is_user_context(context):
if not context.project_id:
raise exception.NotAuthorized()
elif context.project_id != project_id:
raise exception.NotAuthorized()
def authorize_user_context(context, user_id):
"""Ensures a request has permission to access the given user."""
if is_user_context(context):
if not context.user_id:
raise exception.NotAuthorized()
elif context.user_id != user_id:
raise exception.NotAuthorized()
def authorize_quota_class_context(context, class_name):
"""Ensures a request has permission to access the given quota class."""
if is_user_context(context):
if not context.quota_class:
raise exception.NotAuthorized()
elif context.quota_class != class_name:
raise exception.NotAuthorized()
def require_admin_context(f):
"""Decorator to require admin request context.
The first argument to the wrapped function must be the context.
"""
def wrapper(*args, **kwargs):
if not is_admin_context(args[0]):
raise exception.AdminRequired()
return f(*args, **kwargs)
return wrapper
def require_context(f):
"""Decorator to require *any* user or admin context.
This does no authorization for user or project access matching, see
:py:func:`authorize_project_context` and
:py:func:`authorize_user_context`.
The first argument to the wrapped function must be the context.
"""
def wrapper(*args, **kwargs):
if not is_admin_context(args[0]) and not is_user_context(args[0]):
raise exception.NotAuthorized()
return f(*args, **kwargs)
return wrapper
def model_query(context, *args, **kwargs):
"""Query helper that accounts for context's `read_deleted` field.
:param context: context to query under
:param session: if present, the session to use
:param read_deleted: if present, overrides context's read_deleted field.
:param project_only: if present and context is user-type, then restrict
query to match the context's project_id.
"""
session = kwargs.get('session') or get_session()
read_deleted = kwargs.get('read_deleted')
if read_deleted is None and context is not None:
read_deleted = context.read_deleted
project_only = kwargs.get('project_only')
query = session.query(*args)
if read_deleted == 'no':
query = query.filter_by(deleted=False)
elif read_deleted == 'yes':
pass # omit the filter to include deleted and active
elif read_deleted == 'only':
query = query.filter_by(deleted=True)
else:
raise Exception(
_("Unrecognized read_deleted value '%s'") %
read_deleted)
if context:
if project_only and project_only == 'yes' and is_user_context(context):
query = query.filter_by(project_id=context.project_id)
elif project_only and project_only == 'yes':
query = query.filter_by(project_id=context.project_id)
if 'get_hidden' in kwargs:
if kwargs.get('get_hidden', False) == False:
query = query.filter_by(hidden=False)
return query
def exact_filter(query, model, filters, legal_keys):
"""Applies exact match filtering to a query.
Returns the updated query. Modifies filters argument to remove
filters consumed.
:param query: query to apply filters to
:param model: model object the query applies to, for IN-style
filtering
:param filters: dictionary of filters; values that are lists,
tuples, sets, or frozensets cause an 'IN' test to
be performed, while exact matching ('==' operator)
is used for other values
:param legal_keys: list of keys to apply exact filtering to
"""
filter_dict = {}
# Walk through all the keys
for key in legal_keys:
# Skip ones we're not filtering on
if key not in filters:
continue
# OK, filtering on this key; what value do we search for?
value = filters.pop(key)
if isinstance(value, (list, tuple, set, frozenset)):
# Looking for values in a list; apply to query directly
column_attr = getattr(model, key)
query = query.filter(column_attr.in_(value))
else:
# OK, simple exact match; save for later
filter_dict[key] = value
# Apply simple exact matches
if filter_dict:
query = query.filter_by(**filter_dict)
return query
#
@require_admin_context
def service_delete(context, service_id):
session = get_session()
with session.begin():
session.query(models.Service).filter_by(id=service_id).delete()
@require_admin_context
def service_get(context, service_id):
session = get_session()
return _service_get(context, service_id, session)
@require_admin_context
def _service_get(context, service_id, session):
result = model_query(
context,
models.Service,
session=session). \
filter_by(id=service_id). \
first()
if not result:
raise exception.ServiceNotFound(service_id=service_id)
return result
@require_admin_context
def service_get_all(context):
session = get_session()
return session.query(models.Service).all()
@require_admin_context
def service_get_all_by_topic(context, topic, read_disabled):
session = get_session()
if read_disabled:
result_query = model_query(
context, models.Service, session=session, read_deleted="no"). \
filter_by(topic=topic)
else:
result_query = model_query(
context, models.Service, session=session, read_deleted="no"). \
filter_by(disabled=False). \
filter_by(topic=topic)
return result_query.all()
@require_admin_context
def service_get_by_host_and_topic(context, host, topic):
session = get_session()
result = model_query(
context, models.Service, session=session, read_deleted="no"). \
filter_by(host=host). \
filter_by(topic=topic). \
first()
if not result:
raise exception.ServiceNotFoundOnHost(topic=topic, host=host)
return result
@require_admin_context
def service_get_all_by_host(context, host):
session = get_session()
return model_query(
context, models.Service, session=session, read_deleted="no"). \
filter_by(host=host). \
all()
@require_admin_context
def _service_get_all_topic_subquery(context, session, topic, subq, label):
sort_value = getattr(subq.c, label)
return model_query(context, models.Service,
func.coalesce(sort_value, 0),
session=session, read_deleted="no"). \
filter_by(topic=topic). \
filter_by(disabled=False). \
outerjoin((subq, models.Service.host == subq.c.host)). \
order_by(sort_value). \
all()
@require_admin_context
def service_get_by_args(context, host, binary):
session = get_session()
result = model_query(context, models.Service, session=session, ). \
filter_by(host=host). \
filter_by(binary=binary). \
filter_by(version=models.DB_VERSION). \
first()
if not result:
raise exception.HostBinaryNotFound(host=host, binary=binary)
return result
@require_admin_context
def service_create(context, values):
session = get_session()
service_ref = models.Service()
service_ref.update(values)
if not FLAGS.enable_new_services:
service_ref.disabled = True
service_ref.save()
return service_ref
@require_admin_context
def service_update(context, service_id, values):
session = get_session()
with session.begin():
service_ref = _service_get(context, service_id, session=session)
service_ref.update(values)
service_ref.save(session=session)
# File search ###############
@require_context
def file_search_get_all(context, **kwargs):
status = kwargs.get('status', None)
time_in_minutes = kwargs.get('time_in_minutes', None)
host = kwargs.get('host', None)
vm_id = kwargs.get('vm_id', None)
query = model_query(context, models.FileSearch, **kwargs)
query = query.filter_by(project_id=context.project_id)
if time_in_minutes is not None:
now = timeutils.utcnow()
minutes_ago = now - timedelta(minutes=int(time_in_minutes))
query = query.filter(models.FileSearch.created_at < minutes_ago)
if vm_id is not None:
query = query.filter_by(vm_id=vm_id)
if host is not None:
query = query.filter(or_(models.FileSearch.host ==
host, models.FileSearch.host is None))
if status is not None:
query = query.filter(
and_(
models.FileSearch.status != status,
models.FileSearch.status != 'error'))
return query.all()
@require_context
def file_search_delete(context, search_id):
session = get_session()
with session.begin():
ref = _file_search_get(context, search_id, session=session)
session.delete(ref)
@require_context
def file_search_get(context, search_id):
session = get_session()
return _file_search_get(context, search_id, session)
@require_context
def _file_search_get(context, search_id, session):
result = model_query(
context,
models.FileSearch,
session=session). \
filter_by(project_id=context.project_id). \
filter_by(id=search_id). \
first()
if not result:
raise exception.FileSearchNotFound(search_id=search_id)
return result
@require_context
def file_search_create(context, values):
session = get_session()
ref = models.FileSearch()
ref.update(values)
ref.save()
return ref
@require_context
def file_search_update(context, search_id, values):
session = get_session()
with session.begin():
ref = _file_search_get(context, search_id, session=session)
ref.update(values)
ref.save(session=session)
# Work load Types #################
""" workload_type functions """
@require_context
def _set_metadata_for_workload_type(context, workload_type_ref, metadata,
purge_metadata, session):
"""
Create or update a set of workload_type_metadata for a given workload_type
:param context: Request context
:param workload_type_ref: An workload_type object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in workload_type_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'workload_type_id': workload_type_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_workload_type_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_workload_type_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_workload_type_metadata_delete(context, metadata_ref, session)
@require_context
def _workload_type_metadata_create(context, values, session):
"""Create an WorkloadTypeMetadata object"""
metadata_ref = models.WorkloadTypeMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _workload_type_metadata_update(
context, metadata_ref, values, session)
@require_context
def workload_type_metadata_create(context, values):
"""Create an WorkloadTypeMetadata object"""
session = get_session()
return _workload_type_metadata_create(context, values, session)
@require_context
def _workload_type_metadata_update(context, metadata_ref, values, session):
"""
Used internally by workload_type_metadata_create and workload_type_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _workload_type_metadata_delete(context, metadata_ref, session):
"""
Used internally by workload_type_metadata_create and workload_type_metadata_update
"""
metadata_ref.delete(session=session)
return metadata_ref
@require_context
def _workload_type_update(
context, values, workload_type_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if workload_type_id:
workload_type_ref = workload_type_get(
context, workload_type_id, session)
else:
workload_type_ref = models.WorkloadTypes()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
workload_type_ref.update(values)
workload_type_ref.save(session)
_set_metadata_for_workload_type(
context,
workload_type_ref,
metadata,
purge_metadata,
session)
return workload_type_ref
@require_context
def workload_type_create(context, values):
session = get_session()
return _workload_type_update(context, values, None, False, session)
@require_context
def workload_type_update_all(context, values):
session = get_session()
if 'project_id' not in values:
values['project_id'] = context.project_id
if 'user_id' not in values:
values['user_id'] = context.user_id
with session.begin():
session.query(models.WorkloadTypes). \
filter_by(deleted=False). \
update(values)
@require_context
def workload_type_update(context, id, values, purge_metadata=False):
session = get_session()
return _workload_type_update(context, values, id, purge_metadata, session)
@require_context
def workload_types_get(context):
session = get_session()
try:
query = model_query(
context,
models.WorkloadTypes,
session=session,
read_deleted="no").options(
sa_orm.joinedload(
models.WorkloadTypes.metadata)).filter(
(models.WorkloadTypes.project_id == context.project_id) | (
models.WorkloadTypes.is_public))
# TODO(gbasava): filter out deleted workload_types if context disallows
# it
workload_types = query.all()
except sa_orm.exc.NoResultFound:
raise exception.WorkloadTypesNotFound()
return workload_types
@require_context
def workload_type_get(context, id):
session = get_session()
try:
query = session.query(
models.WorkloadTypes).options(
sa_orm.joinedload(
models.WorkloadTypes.metadata)).filter_by(
id=id)
# TODO(gbasava): filter out deleted workload_types if context disallows
# it
workload_types = query.first()
except sa_orm.exc.NoResultFound:
raise exception.WorkloadTypeNotFound(workload_type_id=id)
if workload_types is None:
raise exception.WorkloadTypeNotFound(workload_type_id=id)
return workload_types
@require_context
def workload_type_delete(context, id):
session = get_session()
with session.begin():
session.query(models.WorkloadTypes). \
filter_by(id=id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
# Workloads ################################################################
""" workload functions """
def _set_metadata_for_workload(context, workload_ref, metadata,
purge_metadata, session):
"""
Create or update a set of workload_metadata for a given workload
:param context: Request context
:param workload_ref: An workload object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in workload_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'workload_id': workload_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_workload_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_workload_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_workload_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _workload_metadata_create(context, values, session):
"""Create an WorkloadMetadata object"""
metadata_ref = models.WorkloadMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _workload_metadata_update(context, metadata_ref, values, session)
@require_context
def workload_metadata_create(context, values, session):
"""Create an WorkloadMetadata object"""
session = get_session()
return _workload_metadata_create(context, values, session)
@require_context
def _workload_metadata_update(context, metadata_ref, values, session):
"""
Used internally by workload_metadata_create and workload_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _workload_metadata_delete(context, metadata_ref, session):
"""
Used internally by workload_metadata_create and workload_metadata_update
"""
metadata_ref.delete(session=session)
def _workload_update(context, values, workload_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if workload_id:
workload_ref = _workload_get(context, workload_id, session)
else:
workload_ref = models.Workloads()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
workload_ref.update(values)
workload_ref.save(session)
if metadata:
_set_metadata_for_workload(
context,
workload_ref,
metadata,
purge_metadata,
session=session)
return workload_ref
@require_context
def workload_create(context, values):
session = get_session()
return _workload_update(context, values, None, False, session)
@require_context
def workload_update(context, id, values, purge_metadata=False):
session = get_session()
return _workload_update(context, values, id, purge_metadata, session)
@require_context
def workload_get_all(context, **kwargs):
qs = model_query(context, models.Workloads, **kwargs). \
options(sa_orm.joinedload(models.Workloads.metadata))
if is_admin_context(context):
if 'nfs_share' in kwargs and kwargs['nfs_share'] is not None and kwargs['nfs_share'] != '':
qs = qs.filter(
and_(
models.Workloads.metadata.any(
models.WorkloadMetadata.key.in_(
['backup_media_target'])), models.Workloads.metadata.any(
models.WorkloadMetadata.value.in_(
[
kwargs['nfs_share']]))))
else:
if 'dashboard_item' in kwargs:
if kwargs.get('dashboard_item') == 'activities':
if 'time_in_minutes' in kwargs:
time_in_minutes = int(kwargs.get('time_in_minutes'))
else:
time_in_minutes = 0
time_delta = ((time_in_minutes / 60) / 24) * -1
qs = model_query(
context,
models.Workloads.id,
models.Workloads.deleted,
models.Workloads.deleted_at,
models.Workloads.display_name,
models.Workloads.status,
models.Workloads.created_at,
models.Workloads.user_id,
models.Workloads.project_id,
**kwargs).filter(
or_(
models.Workloads.created_at > func.adddate(
func.now(),
time_delta),
models.Workloads.deleted_at > func.adddate(
func.now(),
time_delta)))
if 'project_id' in kwargs and kwargs['project_id'] is not None and kwargs['project_id'] != '':
qs = qs.filter_by(project_id=kwargs['project_id'])
elif 'all_workloads' in kwargs and kwargs['all_workloads'] is not True:
qs = qs.filter_by(project_id=context.project_id)
else:
qs = qs.filter_by(project_id=context.project_id)
if 'project_list' in kwargs and 'user_list' in kwargs:
project_list = kwargs['project_list']
user_list = kwargs['user_list']
if isinstance(project_list, list) and isinstance(user_list, list):
if 'exclude' in kwargs and kwargs['exclude'] is True:
qs = qs.filter(models.Workloads.project_id.notin_(
project_list) | models.Workloads.user_id.notin_(user_list))
else:
qs = qs.filter(
models.Workloads.project_id.in_(project_list),
models.Workloads.user_id.in_(user_list))
else:
error = _('Project list and user list should be list')
raise exception.ErrorOccurred(reason=error)
if 'project_list' in kwargs and 'user_list' not in kwargs:
project_list = kwargs['project_list']
qs = model_query(context, models.Workloads, **kwargs)
if isinstance(project_list, list):
if 'exclude_project' in kwargs and kwargs['exclude_project'] is True:
qs = qs.filter(
(models.Workloads.project_id.notin_(project_list)))
else:
qs = qs.filter((models.Workloads.project_id.in_(project_list)))
else:
error = _('Project list should be list')
raise exception.ErrorOccurred(reason=error)
if 'workload_list' in kwargs:
workload_list = kwargs['workload_list']
if isinstance(workload_list, list):
if len(workload_list):
if 'exclude_workload' in kwargs and kwargs['exclude_workload'] is True:
qs = qs.filter(and_(models.Workloads.id.notin_(workload_list)))
else:
qs = qs.filter(and_(models.Workloads.id.in_(workload_list)))
else:
error = _('Workload list should be list')
raise exception.ErrorOccurred(reason=error)
qs = qs.order_by(models.Workloads.created_at.desc())
if 'page_number' in kwargs and kwargs['page_number'] is not None and kwargs['page_number'] != '':
page_size = setting_get(context, 'page_size')
return qs.limit(int(page_size)).offset(
int(page_size) * (int(kwargs['page_number']) - 1)).all()
else:
return qs.all()
@require_context
def _workload_get(context, wl_id, session, **kwargs):
try:
workload = model_query(
context, models.Workloads, session=session, **kwargs). \
options(sa_orm.joinedload(models.Workloads.metadata)). \
filter_by(id=wl_id).all()
# TODO(gbasava): filter out deleted workloads if context disallows it
if not workload:
raise exception.WorkloadNotFound(workload_id=wl_id)
return workload[0]
except sa_orm.exc.NoResultFound:
raise exception.WorkloadNotFound(workload_id=wl_id)
except Exception as ex:
LOG.exception(ex)
raise exception.WorkloadNotFound(workload_id=wl_id)
@require_context
def _workload_import_get(context, jobid, wl_id, session, **kwargs):
try:
wl_import = model_query(
context, models.WorkloadImport, session=session, **kwargs). \
filter_by(workload_id=wl_id). \
filter_by(jobid=jobid)
# TODO(gbasava): filter out deleted workloads if context disallows it
if not wl_import:
raise exception.WorkloadNotFound(workload_id=wl_id)
return wl_import
except sa_orm.exc.NoResultFound:
raise exception.WorkloadNotFound(workload_id=wl_id)
except Exception as ex:
LOG.exception(ex)
raise exception.WorkloadNotFound(workload_id=wl_id)
@require_admin_context
def get_workload_count(context, project_id):
session = get_session()
with session.begin():
return session.query(models.Workloads).filter_by(
project_id=project_id, deleted=False
).count()
@require_context
def workload_get(context, id, **kwargs):
session = get_session()
with session.begin():
return _workload_get(context, id, session, **kwargs)
@require_context
def workload_delete(context, id):
session = get_session()
with session.begin():
session.query(models.Workloads). \
filter_by(id=id).delete()
# WorkloadVMs #########################################################
""" workload_vms functions """
def _set_metadata_for_workload_vms(context, workload_vm_ref, metadata,
purge_metadata, session):
"""
Create or update a set of workload_vms_metadata for a given workload_vm
:param context: Request context
:param workload_vm_ref: An workload_vm object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in workload_vm_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'workload_vm_id': workload_vm_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_workload_vms_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_workload_vms_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_workload_vms_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _workload_vms_metadata_create(context, values, session):
"""Create an WorkloadMetadata object"""
metadata_ref = models.WorkloadVMMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _workload_vms_metadata_update(
context, metadata_ref, values, session)
@require_context
def workload_vms_metadata_create(context, values, session):
"""Create an WorkloadMetadata object"""
session = get_session()
return _workload_vms_metadata_create(context, values, session)
@require_context
def _workload_vms_metadata_update(context, metadata_ref, values, session):
"""
Used internally by workload_vms_metadata_create and workload_vms_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _workload_vms_metadata_delete(context, metadata_ref, session):
"""
Used internally by workload_vms_metadata_create and workload_vms_metadata_update
"""
metadata_ref.delete(session=session)
return metadata_ref
def _workload_vms_update(context, values, id, purge_metadata, session):
metadata = values.pop('metadata', {})
if id:
workload_vm_ref = _workload_vm_get(context, id, session)
else:
workload_vm_ref = models.WorkloadVMs()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
workload_vm_ref.update(values)
workload_vm_ref.save(session)
if metadata:
_set_metadata_for_workload_vms(
context,
workload_vm_ref,
metadata,
purge_metadata,
session=session)
return workload_vm_ref
@require_context
def workload_vms_create(context, values):
session = get_session()
return _workload_vms_update(context, values, None, False, session)
@require_context
def workload_vms_update(context, id, values, purge_metadata=False):
session = get_session()
return _workload_vms_update(context, values, id, purge_metadata, session)
@require_context
def workload_vms_get(context, workload_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
if workload_id:
query = model_query(context, models.WorkloadVMs,
session=session, read_deleted="no") \
.options(sa_orm.joinedload(models.WorkloadVMs.metadata)) \
.filter_by(workload_id=workload_id) \
.filter(models.WorkloadVMs.status is not None)
else:
query = model_query(context, models.WorkloadVMs,
session=session, read_deleted="no") \
.options(sa_orm.joinedload(models.WorkloadVMs.metadata)) \
.filter(models.WorkloadVMs.status is not None)
if kwargs.get('workload_list'):
query = query.filter(models.WorkloadVMs.workload_id.in_(kwargs['workload_list']))
# TODO(gbasava): filter out deleted workload_vms if context disallows
# it
workload_vms = query.all()
except sa_orm.exc.NoResultFound:
raise exception.WorkloadVMsNotFound(workload_id=workload_id)
return workload_vms
@require_context
def _import_job_get(context, jobid, session):
session = get_session()
with session.begin():
res = session.query(models.Job). \
filter_by(jobid=jobid)
return res
@require_context
def import_job_create(context, values):
session = get_session()
with session.begin():
job_ref = models.Job()
job_ref.created_at = datetime.now()
job_ref.progress = 0
job_ref.status = values.get('status')
job_ref.action = values.get('action')
job_ref.save(session)
return job_ref.jobid
@require_context
def import_job_update(context, jobid, values):
session = get_session()
if jobid:
job_ref = _import_job_get(context, jobid, session)
job_ref.update(values)
@require_context
def import_job_get(context, jobid):
session = get_session()
if jobid:
return _import_job_get(context, jobid)
@require_context
def workload_import_get_all(context, jobid):
return importable_workloads_get_all(context, jobid=jobid)
@require_context
def workload_import_update(context, job_data_id, values):
session = get_session()
job_data_ref = model_query(
context, models.JobDetails, session=session).filter_by(id=job_data_id).first()
if not job_data_ref:
raise exception.JobDataNotFound(job_data_id=job_data_id)
db_values = dict(json.loads(job_data_ref.data))
db_values.update(values)
job_data_ref.update({'jobid': job_data_ref.jobid, 'data':json.dumps(db_values)})
job_data_ref.save(session)
return job_data_ref
@require_context
def workload_import_create(context, values):
session = get_session()
jobid = values.get('jobid')
return importable_workloads_create(context, jobid, {'workload_id': values.get('workload_id'), 'created_at': str(datetime.utcnow()), 'progress': 0, 'status': 'created'})
@require_context
def import_job_get(context, jobid, **kwargs):
session = get_session()
job = None
with session.begin():
job = model_query(
context, models.Job, session=session, **kwargs). \
filter_by(jobid=jobid).all()
if not job:
raise exception.JobNotFound(jobid=jobid)
return job[0]
@require_admin_context
def get_vms_count_by_project_id(context, project_id):
session = get_session()
with session.begin():
return session.query(
models.Workloads.project_id, models.WorkloadVMs.vm_id).join(
models.WorkloadVMs).filter(
and_(models.Workloads.project_id == project_id,
models.Workloads.deleted == False,
models.WorkloadVMs.deleted == False)).count()
@require_context
def workload_vm_get_by_id(context, vm_id, **kwargs):
session = kwargs.get('session') or get_session()
read_deleted = 'no'
if 'read_deleted' in kwargs:
read_deleted = kwargs['read_deleted']
try:
query = model_query(context, models.WorkloadVMs,
session=session, read_deleted=read_deleted) \
.options(sa_orm.joinedload(models.WorkloadVMs.metadata)) \
.join(models.Workloads) \
.filter(models.WorkloadVMs.status is not None) \
.filter(models.WorkloadVMs.vm_id == vm_id) \
.filter(models.Workloads.project_id == context.project_id)
if 'workloads_filter' in kwargs:
query = query.filter(
and_(
models.Workloads.status != kwargs['workloads_filter'],
models.Workloads.status is not None))
vm_found = query.all()
except sa_orm.exc.NoResultFound:
raise exception.WorkloadVMsNotFound(vm_id=vm_id)
return vm_found
@require_context
def _workload_vm_get(context, id, session):
try:
query = session.query(
models.WorkloadVMs).options(
sa_orm.joinedload(
models.WorkloadVMs.metadata)).filter_by(
id=id)
# TODO(gbasava): filter out deleted workload_vms if context disallows
# it
workload_vm = query.first()
except sa_orm.exc.NoResultFound:
raise exception.WorkloadVMNotFound(workload_vm_id=id)
return workload_vm
@require_context
def workload_vm_get(context, id):
session = get_session()
return _workload_vm_get(context, id, session)
@require_context
def workload_vms_delete(context, vm_id, workload_id):
session = get_session()
with session.begin():
session.query(models.WorkloadVMs). \
filter_by(vm_id=vm_id). \
filter_by(workload_id=workload_id).delete()
@require_context
def restored_instance_get(context, instance_id, **kwargs):
""""
Return list of models.WorkloadVMs which are using
vms restored from given instance_id
"""
session = get_session()
query = session.query(models.RestoredVMs.vm_id).join(models.RestoredVMMetadata).filter(
and_(
models.RestoredVMMetadata.key == 'instance_id'), models.RestoredVMMetadata.value == instance_id,
models.RestoredVMs.deleted == False)
restored_vms = [vm.vm_id for vm in query.all()]
restored_vms.append(instance_id)
query = session.query(models.WorkloadVMs).filter(
and_(models.WorkloadVMs.vm_id.in_(restored_vms), models.WorkloadVMs.deleted == False))
return query.all()
#
@require_admin_context
def unlock_workloads_for_host(context, host):
session = get_session()
workloads_query = model_query(context, models.Workloads, session=session)
workloads_query = workloads_query.filter(and_(
models.Workloads.status == 'locked',
models.Workloads.host == host)
)
locked_workloads = workloads_query.all()
for wrklod in locked_workloads:
values = {'status': 'available'}
wrklod.update(values)
session.add(wrklod)
session.flush()
session.close()
@require_admin_context
def workloads_mark_deleting_as_error(context, host):
session = get_session()
workloads_query = model_query(context, models.Workloads, session=session)
workloads_query = workloads_query.filter(and_(
models.Workloads.status == 'deleting',
models.Workloads.host == host)
)
deleting_workloads = workloads_query.all()
for wrklod in deleting_workloads:
values = {'status': 'error'}
wrklod.update(values)
session.add(wrklod)
session.flush()
session.close()
@require_admin_context
def snapshot_mark_incomplete_as_error(context, host):
"""
mark the snapshots that are left hanging from previous run on host as 'error'
"""
session = get_session()
now = timeutils.utcnow()
snapshots_query = model_query(context, models.Snapshots, session=session)
snapshots_query = snapshots_query.filter(and_(
models.Snapshots.status != 'available',
models.Snapshots.status != 'error',
models.Snapshots.status != 'mounted',
models.Snapshots.status != 'cancelled'))
snapshots_query = snapshots_query.filter(or_(
models.Snapshots.host == host,
models.Snapshots.host == ''))
snapshots = snapshots_query.all()
for snapshot in snapshots:
if (snapshot.host == '' and
now - snapshot.created_at <= timedelta(minutes=60)):
continue
if snapshot.status == 'restoring':
values = {'status': 'available'}
else:
values = {'progress_percent': 100, 'progress_msg': '',
'error_msg': 'Snapshot did not finish successfully',
'status': 'error'}
snapshot.update(values)
session.add(snapshot)
session.flush()
session.close()
# Snapshot ################################################################
""" snapshot functions """
def _set_metadata_for_snapshot(context, snapshot_ref, metadata,
purge_metadata, session):
"""
Create or update a set of snapshot_metadata for a given snapshot
:param context: Request context
:param snapshot_ref: A snapshot object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in snapshot_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'snapshot_id': snapshot_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_snapshot_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_snapshot_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_snapshot_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _snapshot_metadata_create(context, values, session):
"""Create a SnapshotMetadata object"""
metadata_ref = models.SnapshotMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _snapshot_metadata_update(context, metadata_ref, values, session)
@require_context
def snapshot_metadata_create(context, values, session):
"""Create an SnapshotMetadata object"""
session = get_session()
return _snapshot_metadata_create(context, values, session)
@require_context
def _snapshot_metadata_update(context, metadata_ref, values, session):
"""
Used internally by snapshot_metadata_create and snapshot_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _snapshot_metadata_delete(context, metadata_ref, session):
"""
Used internally by snapshot_metadata_create and snapshot_metadata_update
"""
metadata_ref.delete(session=session)
def _snapshot_update(context, values, snapshot_id, purge_metadata, session):
try:
lock.acquire()
metadata = values.pop('metadata', {})
if snapshot_id:
snapshot_ref = model_query(
context,
models.Snapshots,
session=session,
read_deleted="yes").filter_by(
id=snapshot_id).first()
if not snapshot_ref:
lock.release()
raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
if not values.get('uploaded_size'):
if values.get('uploaded_size_incremental'):
values['uploaded_size'] = snapshot_ref.uploaded_size + \
values.get('uploaded_size_incremental')
if not values.get(
'progress_percent') and snapshot_ref.size > 0:
values['progress_percent'] = min(
99, (100 * values.get('uploaded_size')) / snapshot_ref.size)
else:
snapshot_ref = models.Snapshots()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not values.get('size'):
values['size'] = 0
if not values.get('restore_size'):
values['restore_size'] = 0
if not values.get('uploaded_size'):
values['uploaded_size'] = 0
if not values.get('progress_percent'):
values['progress_percent'] = 0
snapshot_ref.update(values)
snapshot_ref.save(session)
if metadata:
_set_metadata_for_snapshot(
context,
snapshot_ref,
metadata,
purge_metadata,
session=session)
return snapshot_ref
finally:
lock.release()
return snapshot_ref
@require_context
def _snapshot_get(context, snapshot_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
result = model_query(context, models.Snapshots, **kwargs). \
options(sa_orm.joinedload(models.Snapshots.metadata)). \
filter_by(id=snapshot_id). \
first()
if not result:
raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
return result
@require_admin_context
def get_active_snapshot_count(context, project_id):
session = get_session()
with session.begin():
return session.query(models.Snapshots).filter(and_(
models.Snapshots.project_id==project_id,
models.Snapshots.deleted==False,
models.Snapshots.status.notin_(['error', 'cancelled'])
)).count()
@require_context
def snapshot_get(context, snapshot_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return _snapshot_get(context, snapshot_id, **kwargs)
@require_context
def snapshot_get_metadata_cancel_flag(
context, snapshot_id, return_val=0, process=None, **kwargs):
flag = '0'
snapshot_obj = snapshot_get(context, snapshot_id)
for meta in snapshot_obj.metadata:
if meta.key == 'cancel_requested':
flag = meta.value
if return_val == 1:
return flag
if flag == '1':
if process:
process.kill()
error = _('Cancel requested for snapshot')
raise exception.ErrorOccurred(reason=error)
@require_context
def snapshot_get_running_snapshots_by_host(context, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
result = model_query(context,
models.Snapshots.host,
func.count(models.Snapshots.host),
**kwargs).filter(
and_(~models.Snapshots.status.in_(['available',
'error',
'deleted',
'cancelled'])),
models.Snapshots.host != '').group_by(models.Snapshots.host).all()
return result
@require_context
def migration_get_running_migrations_by_host(context, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
result = model_query(context,
models.Migrations.host,
func.count(models.Migrations.host),
**kwargs).filter(
and_(~models.Migrations.status.in_(['available',
'error',
'deleted',
'cancelled'])),
models.Migrations.host != '').group_by(models.Migrations.host).all()
return result
@require_context
def snapshot_get_all(context, **kwargs):
qs = model_query(context, models.Snapshots, **kwargs)
if kwargs.get('read_metadata', True):
qs = qs.options(sa_orm.joinedload(models.Snapshots.metadata))
elif kwargs.get('read_restores', True):
qs = qs.options(sa_orm.joinedload(models.Snapshots.restores))
if 'workload_id' in kwargs and kwargs['workload_id'] is not None and kwargs['workload_id'] != '':
qs = qs.filter_by(workload_id=kwargs['workload_id'])
if kwargs.get('project_id'):
qs = qs.filter_by(project_id=kwargs['project_id'])
elif kwargs.get('project_list'):
qs = qs.filter(models.Snapshots.project_id.in_(kwargs['project_list']))
if 'host' in kwargs and kwargs['host'] is not None and kwargs['host'] != '':
qs = qs.filter(models.Snapshots.host == kwargs['host'])
if 'date_from' in kwargs and kwargs['date_from'] is not None and kwargs['date_from'] != '':
if 'date_to' in kwargs and kwargs['date_to'] is not None and kwargs['date_to'] != '':
date_to = kwargs['date_to']
else:
date_to = datetime.now()
qs = qs.filter(
and_(
models.Snapshots.created_at >= func.date_format(
kwargs['date_from'],
'%y-%m-%dT%H:%i:%s'),
models.Snapshots.created_at <= func.date_format(
date_to,
'%y-%m-%dT%H:%i:%s')))
if not is_admin_context(context):
qs = qs.filter_by(project_id=context.project_id)
else:
if 'get_all' in kwargs and kwargs['get_all'] is not True:
qs = qs.filter_by(project_id=context.project_id)
if 'status' in kwargs and kwargs['status'] is not None:
if kwargs['status'] == 'available':
qs = qs.filter(or_(models.Snapshots.status ==
'available', models.Snapshots.status == 'mounted'))
elif kwargs['status'] == 'running':
""" All other status except available/mounted/error/cancelled will be considered as Running snapshot by any of the Node."""
qs = qs.filter(and_(models.Snapshots.status != 'available',
models.Snapshots.status != 'mounted',
models.Snapshots.status != 'error',
models.Snapshots.status != 'cancelled',
models.Snapshots.status != 'deleting',
models.Snapshots.status != 'restoring',
models.Snapshots.status != 'mounting'))
else:
qs = qs.filter_by(status=kwargs['status'])
qs = qs.order_by(models.Snapshots.created_at.desc())
if 'end' in kwargs and kwargs['end'] != 0:
qs = qs.limit(kwargs['end'])
if 'start' in kwargs and kwargs['start'] != 0:
qs = qs.offset(kwargs['start'])
if 'get_instances' in kwargs and kwargs['get_instances'] is True:
snapshots = qs.all()
i = 0
for snapshot in snapshots:
instances = []
snapshot_vms = snapshot_vms_get(context, snapshot.id)
for snapshot_vm in snapshot_vms:
instances.append(snapshot_vm)
snapshots[i].instances = instances
i = i + 1
return snapshots
return qs.all()
@require_context
def snapshot_get_all_by_workload(context, workload_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return model_query(context, models.Snapshots, **kwargs). \
options(sa_orm.joinedload(models.Snapshots.metadata)). \
filter_by(workload_id=workload_id). \
order_by(models.Snapshots.created_at.desc()).all()
@require_context
def snapshot_get_all_by_project(context, project_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
authorize_project_context(context, project_id)
return model_query(context, models.Snapshots, **kwargs). \
options(sa_orm.joinedload(models.Snapshots.metadata)). \
filter_by(project_id=project_id).all()
@require_context
def snapshot_get_all_by_project_workload(
context, project_id, workload_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
authorize_project_context(context, project_id)
return model_query(context, models.Snapshots, **kwargs). \
options(sa_orm.joinedload(models.Snapshots.metadata)). \
filter_by(project_id=project_id). \
filter_by(workload_id=workload_id). \
order_by(models.Snapshots.created_at.desc()).all()
@require_context
def snapshot_show(context, snapshot_id, **kwargs):
session = get_session()
result = model_query(
context,
models.Snapshots,
session=session,
**kwargs).options(
sa_orm.joinedload(
models.Snapshots.metadata)).filter_by(
id=snapshot_id).first()
if not result:
raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
return result
@require_context
def snapshot_create(context, values):
session = get_session()
return _snapshot_update(context, values, None, False, session)
@require_context
def snapshot_update(context, snapshot_id, values, purge_metadata=False):
session = get_session()
return _snapshot_update(context, values, snapshot_id,
purge_metadata, session)
def snapshot_next(context, snapshot_id, workload_id, **kwargs):
"""
Args:
context: HTTPRequest Object
snapshot_id: int<snapshot_id>
workload_id: int<snapshot_id>
**kwargs: dict
Returns: Quesryset Object.
"""
session = get_session()
qs_1 = session.query(models.Snapshots). \
filter(models.Snapshots.workload_id == workload_id). \
filter(models.Snapshots.created_at > (session.query(models.Snapshots).
filter(models.Snapshots.workload_id == workload_id).
filter(models.Snapshots.id == snapshot_id).
order_by(asc(models.Snapshots.created_at)).first()).
__dict__.get('created_at')). \
order_by(asc(models.Snapshots.created_at)).limit(2)
if not qs_1:
raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
return qs_1
@require_context
def snapshot_prev(context, snapshot_id, workload_id, **kwargs):
"""
Args:
context: HTTPRequest Object.
snapshot_id: int<snapshot_id>
workload_id: int<snapshot_id>
**kwargs: dict
Returns: Queryset Object.
"""
session = get_session()
qs_1 = session.query(models.Snapshots). \
filter(models.Snapshots.workload_id == workload_id). \
filter(models.Snapshots.created_at < (session.query(models.Snapshots).
filter(models.Snapshots.workload_id == workload_id).
filter(models.Snapshots.id == snapshot_id).
order_by(asc(models.Snapshots.created_at)).first()).
__dict__.get('created_at')). \
order_by(desc(models.Snapshots.created_at)).limit(2)
if not qs_1:
raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
return qs_1
@require_context
def snapshot_type_time_size_update(context, snapshot_id):
snapshot = snapshot_get(context, snapshot_id, read_deleted='yes')
workload = workload_get(context, snapshot['workload_id'])
backup_endpoint = get_metadata_value(workload.metadata,
'backup_media_target')
backup_target = vault.get_backup_target(backup_endpoint)
snapshot_type_full = False
snapshot_type_incremental = False
snapshot_vm_resources = snapshot_resources_get(context, snapshot_id)
time_taken = 0
snapshot_size = 0
snapshot_restore_size = 0
for snapshot_vm_resource in snapshot_vm_resources:
if snapshot_vm_resource.resource_type != 'disk':
continue
if snapshot_vm_resource.snapshot_type == 'full' and \
snapshot_vm_resource.resource_name != 'vda':
snapshot_type_full = True
if snapshot_vm_resource.snapshot_type == 'incremental':
snapshot_type_incremental = True
time_taken = time_taken + snapshot_vm_resource.time_taken
# update size
if snapshot_vm_resource.status != 'deleted':
disk_type = get_metadata_value(
snapshot_vm_resource.metadata, 'disk_type')
vm_disk_resource_snaps = vm_disk_resource_snaps_get(
context, snapshot_vm_resource.id)
snapshot_vm_resource_size = 0
for vm_disk_resource_snap in vm_disk_resource_snaps:
vm_disk_resource_snap_restore_size = 0
if vm_disk_resource_snap.vault_url is None:
continue
resource_snap_path = os.path.join(
backup_target.mount_path,
vm_disk_resource_snap.vault_url.strip(
os.sep))
vm_disk_resource_snap_size = backup_target.get_object_size(
resource_snap_path)
if vm_disk_resource_snap_size == 0:
vm_disk_resource_snap_size = vm_disk_resource_snap.size
disk_format = get_metadata_value(
vm_disk_resource_snap.metadata, 'disk_format')
if disk_format == 'vmdk':
vault_path = os.path.join(
backup_target.mount_path,
vm_disk_resource_snap.vault_url.strip(
os.sep))
vm_disk_resource_snap_restore_size = vault.get_restore_size(
vault_path, disk_format, disk_type)
else:
vm_disk_resource_snap_restore_size = qemuimages.get_effective_size(
resource_snap_path)
# For vmdk
if vm_disk_resource_snap_restore_size == 0:
vm_disk_resource_snap_restore_size = vm_disk_resource_snap_size
vm_disk_resource_snap_backing_id = vm_disk_resource_snap.vm_disk_resource_snap_backing_id
while vm_disk_resource_snap_backing_id:
vm_disk_resource_snap_backing = vm_disk_resource_snap_get(
context, vm_disk_resource_snap_backing_id)
if vm_disk_resource_snap_backing.vm_disk_resource_snap_backing_id:
vm_disk_resource_snap_restore_size = vm_disk_resource_snap_restore_size + \
vm_disk_resource_snap_backing.size
else:
vm_disk_resource_snap_restore_size = vm_disk_resource_snap_restore_size + \
vm_disk_resource_snap_backing.restore_size
vm_disk_resource_snap_backing_id = vm_disk_resource_snap_backing.vm_disk_resource_snap_backing_id
vm_disk_resource_snap_update(
context, vm_disk_resource_snap.id, {
'size': vm_disk_resource_snap_size, 'restore_size': vm_disk_resource_snap_restore_size})
snapshot_vm_resource_size = snapshot_vm_resource_size + \
vm_disk_resource_snap_size
vm_disk_resource_snap_top = vm_disk_resource_snap_get_top(
context, snapshot_vm_resource.id)
snapshot_vm_resource_restore_size = vm_disk_resource_snap_top.restore_size
snapshot_vm_resource_update(
context, snapshot_vm_resource.id, {
'size': snapshot_vm_resource_size, 'restore_size': snapshot_vm_resource_restore_size})
snapshot_size = snapshot_size + snapshot_vm_resource_size
snapshot_restore_size = snapshot_restore_size + \
snapshot_vm_resource_restore_size
snapshot_vms = snapshot_vms_get(context, snapshot_id)
snapshot_data_transfer_time = 0
snapshot_object_store_transfer_time = 0
for snapshot_vm in snapshot_vms:
snapshot_vm_size = 0
snapshot_vm_restore_size = 0
snapshot_vm_data_transfer_time = 0
snapshot_vm_object_store_transfer_time = 0
snapshot_vm_resources = snapshot_vm_resources_get(
context, snapshot_vm.vm_id, snapshot_id)
for snapshot_vm_resource in snapshot_vm_resources:
if snapshot_vm_resource.resource_type != 'disk':
continue
snapshot_vm_size = snapshot_vm_size + snapshot_vm_resource.size
snapshot_vm_restore_size = snapshot_vm_restore_size + \
snapshot_vm_resource.restore_size
snapshot_vm_data_transfer_time += snapshot_vm_resource.time_taken
snapshot_vm_object_store_transfer_time += int(get_metadata_value(
snapshot_vm_resource.metadata, 'object_store_transfer_time', '0'))
snapshot_vm_update(
context,
snapshot_vm.vm_id,
snapshot_id,
{
'size': snapshot_vm_size,
'restore_size': snapshot_vm_restore_size,
'metadata': {
'data_transfer_time': snapshot_vm_data_transfer_time,
'object_store_transfer_time': snapshot_vm_object_store_transfer_time,
},
})
snapshot_data_transfer_time += snapshot_vm_data_transfer_time
snapshot_object_store_transfer_time += snapshot_vm_object_store_transfer_time
if snapshot.finished_at:
time_taken = max(
time_taken, int(
(snapshot.finished_at - snapshot.created_at).total_seconds()))
else:
time_taken = max(
time_taken, int(
(timeutils.utcnow() - snapshot.created_at).total_seconds()))
if snapshot_type_full and snapshot_type_incremental:
snapshot_type = 'mixed'
elif snapshot_type_incremental:
snapshot_type = 'incremental'
elif snapshot_type_full:
snapshot_type = 'full'
else:
snapshot_type = 'full'
return snapshot_update(
context,
snapshot_id,
{
'snapshot_type': snapshot_type,
'time_taken': time_taken,
'size': snapshot_size,
'restore_size': snapshot_restore_size,
'uploaded_size': snapshot_size,
'metadata': {
'data_transfer_time': snapshot_data_transfer_time,
'object_store_transfer_time': snapshot_object_store_transfer_time,
},
})
@require_context
def snapshot_delete(context, snapshot_id, hard_delete=False):
session = get_session()
with session.begin():
if hard_delete:
session.query(models.Snapshots). \
filter_by(id=snapshot_id).delete()
else:
session.query(models.Snapshots). \
filter_by(id=snapshot_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
@require_context
def get_snapshot_children(context, snapshot_id, children):
grand_children = set()
snapshot_vm_resources = snapshot_resources_get(context, snapshot_id)
for snapshot_vm_resource in snapshot_vm_resources:
if snapshot_vm_resource.resource_type != 'disk':
continue
vm_disk_resource_snaps = vm_disk_resource_snaps_get(
context, snapshot_vm_resource.id)
for vm_disk_resource_snap in vm_disk_resource_snaps:
if vm_disk_resource_snap.vm_disk_resource_snap_child_id:
try:
vm_disk_resource_snap_child = vm_disk_resource_snap_get(
context, vm_disk_resource_snap.vm_disk_resource_snap_child_id)
snapshot_vm_resource_child = snapshot_vm_resource_get(
context, vm_disk_resource_snap_child.snapshot_vm_resource_id)
if snapshot_vm_resource_child.snapshot_id not in grand_children:
grand_children.add(
snapshot_vm_resource_child.snapshot_id)
if snapshot_vm_resource_child.snapshot_id != snapshot_id:
grand_children = get_snapshot_children(
context, snapshot_vm_resource_child.snapshot_id, grand_children)
except Exception as ex:
LOG.exception(ex)
if children:
return grand_children.union(children)
else:
return grand_children
@require_context
def get_snapshot_parents(context, snapshot_id, parents):
grand_parents = set()
snapshot_vm_resources = snapshot_resources_get(context, snapshot_id)
for snapshot_vm_resource in snapshot_vm_resources:
if snapshot_vm_resource.resource_type != 'disk':
continue
vm_disk_resource_snaps = vm_disk_resource_snaps_get(
context, snapshot_vm_resource.id)
for vm_disk_resource_snap in vm_disk_resource_snaps:
if vm_disk_resource_snap.vm_disk_resource_snap_backing_id:
try:
vm_disk_resource_snap_parent = vm_disk_resource_snap_get(
context, vm_disk_resource_snap.vm_disk_resource_snap_backing_id)
snapshot_vm_resource_parent = snapshot_vm_resource_get(
context, vm_disk_resource_snap_parent.snapshot_vm_resource_id)
if snapshot_vm_resource_parent.snapshot_id not in grand_parents:
grand_parents.add(
snapshot_vm_resource_parent.snapshot_id)
if snapshot_vm_resource_parent.snapshot_id != snapshot_id:
grand_parents = get_snapshot_parents(
context, snapshot_vm_resource_parent.snapshot_id, grand_parents)
except Exception as ex:
LOG.exception(ex)
if parents:
return grand_parents.union(parents)
else:
return grand_parents
# SnapshotVMs #########################################################
""" snapshot_vms functions """
def _set_metadata_for_snapshot_vms(context, snapshot_vm_ref, metadata,
purge_metadata, session):
"""
Create or update a set of snapshot_vms_metadata for a given snapshot_vm
:param context: Request context
:param snapshot_vm_ref: An snapshot_vm object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in snapshot_vm_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'snapshot_vm_id': snapshot_vm_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_snapshot_vms_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_snapshot_vms_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_snapshot_vms_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _snapshot_vms_metadata_create(context, values, session):
"""Create an SnapshotMetadata object"""
metadata_ref = models.SnapshotVMMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _snapshot_vms_metadata_update(
context, metadata_ref, values, session)
@require_context
def snapshot_vms_metadata_create(context, values, session):
"""Create an SnapshotMetadata object"""
session = get_session()
return _snapshot_vms_metadata_create(context, values, session)
@require_context
def _snapshot_vms_metadata_update(context, metadata_ref, values, session):
"""
Used internally by snapshot_vms_metadata_create and snapshot_vms_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _snapshot_vms_metadata_delete(context, metadata_ref, session):
"""
Used internally by snapshot_vms_metadata_create and snapshot_vms_metadata_update
"""
metadata_ref.delete(session=session)
def _snapshot_vm_update(context, values, vm_id,
snapshot_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if vm_id:
snapshot_vm_ref = _snapshot_vm_get(
context, vm_id, snapshot_id, session)
if snapshot_vm_ref is None:
return
else:
snapshot_vm_ref = models.SnapshotVMs()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not values.get('size'):
values['size'] = 0
if not values.get('restore_size'):
values['restore_size'] = 0
snapshot_vm_ref.update(values)
snapshot_vm_ref.save(session)
if metadata:
_set_metadata_for_snapshot_vms(
context,
snapshot_vm_ref,
metadata,
purge_metadata,
session=session)
return snapshot_vm_ref
@require_context
def snapshot_vm_create(context, values):
session = get_session()
return _snapshot_vm_update(context, values, None, None, False, session)
@require_context
def snapshot_vm_update(context, vm_id, snapshot_id,
values, purge_metadata=False):
session = get_session()
return _snapshot_vm_update(
context, values, vm_id, snapshot_id, purge_metadata, session)
@require_context
def snapshot_vms_get(context, snapshot_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.SnapshotVMs).options(
sa_orm.joinedload(
models.SnapshotVMs.metadata)).filter_by(
snapshot_id=snapshot_id)
snapshot_vms = query.all()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotVMsNotFound(snapshot_id=snapshot_id)
return snapshot_vms
@require_context
def _snapshot_vm_get(context, vm_id, snapshot_id, session):
try:
query = session.query(
models.SnapshotVMs).options(
sa_orm.joinedload(
models.SnapshotVMs.metadata)).filter_by(
vm_id=vm_id)
if snapshot_id is not None:
query = query.filter_by(snapshot_id=snapshot_id)
# TODO(gbasava): filter out deleted snapshot_vm if context disallows it
snapshot_vm = query.first()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotVMsNotFound(snapshot_id=snapshot_id)
return snapshot_vm
@require_context
def snapshot_vm_get(context, vm_id, snapshot_id):
session = get_session()
return _snapshot_vm_get(context, vm_id, snapshot_id, session)
@require_context
def snapshot_vm_delete(context, vm_id, snapshot_id):
session = get_session()
with session.begin():
session.query(models.SnapshotVMs). \
filter_by(vm_id=vm_id). \
filter_by(snapshot_id=snapshot_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
#
@require_context
def vm_recent_snapshot_create(context, values):
vm_recent_snapshot = models.VMRecentSnapshot()
vm_recent_snapshot.update(values)
vm_recent_snapshot.save()
return vm_recent_snapshot
@require_context
def vm_recent_snapshot_get(context, vm_id, **kwargs):
session = kwargs.get('session') or get_session()
result = model_query(context, models.VMRecentSnapshot, session=session). \
filter_by(vm_id=vm_id). \
first()
return result
@require_context
def vm_recent_snapshot_update(context, vm_id, values):
session = get_session()
with session.begin():
vm_recent_snapshot = model_query(context, models.VMRecentSnapshot,
session=session, read_deleted="yes"). \
filter_by(vm_id=vm_id).first()
if not vm_recent_snapshot:
values['vm_id'] = vm_id
vm_recent_snapshot = models.VMRecentSnapshot()
vm_recent_snapshot.update(values)
vm_recent_snapshot.save(session=session)
return vm_recent_snapshot
@require_context
def vm_recent_snapshot_delete(context, vm_id):
session = get_session()
with session.begin():
session.query(models.VMRecentSnapshot). \
filter_by(vm_id=vm_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
""" snapshot vm resource functions """
@require_context
def _set_metadata_for_snapshot_vm_resource(
context,
snapshot_vm_resource_ref,
metadata,
purge_metadata,
session):
"""
Create or update a set of snapshot_vm_resource_metadata for a given snapshot resource
:param context: Request context
:param snapshot_vm_resource_ref: An snapshot_vm_resource object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in snapshot_vm_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'snapshot_vm_resource_id': snapshot_vm_resource_ref.id,
'key': key,
'value': str(value) if isinstance(value, uuid.UUID) else value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_snapshot_vm_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_snapshot_vm_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_snapshot_vm_resource_metadata_delete(
context, metadata_ref, session)
@require_context
def _snapshot_vm_resource_metadata_create(context, values, session):
"""Create an SnapshotVMResourceMetadata object"""
metadata_ref = models.SnapshotVMResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _snapshot_vm_resource_metadata_update(
context, metadata_ref, values, session)
@require_context
def snapshot_vm_resource_metadata_create(context, values):
session = get_session()
return _snapshot_vm_resource_metadata_create(context, values, session)
@require_context
def _snapshot_vm_resource_metadata_update(
context, metadata_ref, values, session):
"""
Used internally by snapshot_vm_resource_metadata_create and snapshot_vm_resource_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _snapshot_vm_resource_metadata_delete(context, metadata_ref, session):
"""
Used internally by snapshot_vm_resource_metadata_create and snapshot_vm_resource_metadata_update
"""
metadata_ref.delete(session=session)
@require_context
def _snapshot_vm_resource_update(
context, values, snapshot_vm_resource_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if snapshot_vm_resource_id:
snapshot_vm_resource_ref = _snapshot_vm_resource_get(
context, snapshot_vm_resource_id, session=session)
else:
snapshot_vm_resource_ref = models.SnapshotVMResources()
if not values.get('size'):
values['size'] = 0
if not values.get('restore_size'):
values['restore_size'] = 0
snapshot_vm_resource_ref.update(values)
snapshot_vm_resource_ref.save(session)
_set_metadata_for_snapshot_vm_resource(
context,
snapshot_vm_resource_ref,
metadata,
purge_metadata,
session)
return snapshot_vm_resource_ref
@require_context
def snapshot_vm_resource_create(context, values):
session = get_session()
return _snapshot_vm_resource_update(context, values, None, False, session)
@require_context
def snapshot_vm_resource_update(
context, snapshot_vm_resource_id, values, purge_metadata=False):
session = get_session()
return _snapshot_vm_resource_update(
context, values, snapshot_vm_resource_id, purge_metadata, session)
@require_context
def snapshot_vm_resources_get(context, vm_id, snapshot_id):
session = get_session()
try:
query = session.query(
models.SnapshotVMResources).options(
sa_orm.joinedload(
models.SnapshotVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
snapshot_id=snapshot_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
snapshot_vm_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotVMResourcesNotFound(
snapshot_vm_id=vm_id, snapshot_id=snapshot_id)
return snapshot_vm_resources
@require_context
def snapshot_resources_get(context, snapshot_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.SnapshotVMResources).options(
sa_orm.joinedload(
models.SnapshotVMResources.metadata)).filter_by(
snapshot_id=snapshot_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
snapshot_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotResourcesNotFound(snapshot_id=snapshot_id)
return snapshot_resources
@require_context
def snapshot_vm_resource_get_by_resource_name(
context, vm_id, snapshot_id, resource_name):
session = get_session()
try:
query = session.query(
models.SnapshotVMResources).options(
sa_orm.joinedload(
models.SnapshotVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
snapshot_id=snapshot_id).filter_by(
resource_name=resource_name)
# TODO(gbasava): filter out deleted snapshots if context disallows it
snapshot_vm_resource = query.first()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotVMResourceWithNameNotFound(
resource_name=resource_name, snapshot_vm_id=vm_id, snapshot_id=snapshot_id)
return snapshot_vm_resource
@require_context
def snapshot_vm_resource_get_by_resource_pit_id(
context, vm_id, snapshot_id, resource_pit_id):
session = get_session()
try:
query = session.query(
models.SnapshotVMResources).options(
sa_orm.joinedload(
models.SnapshotVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
snapshot_id=snapshot_id).filter_by(
resource_pit_id=resource_pit_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
snapshot_vm_resource = query.first()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotVMResourceWithNameNotFound(
resource_pit_id=resource_pit_id, snapshot_vm_id=vm_id, snapshot_id=snapshot_id)
return snapshot_vm_resource
@require_context
def _snapshot_vm_resource_get(context, id, session):
try:
query = session.query(
models.SnapshotVMResources).options(
sa_orm.joinedload(
models.SnapshotVMResources.metadata)).filter_by(
id=id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
snapshot_vm_resource = query.first()
except sa_orm.exc.NoResultFound:
raise exception.SnapshotVMResourceNotFound(snapshot_vm_resource_id=id)
return snapshot_vm_resource
@require_context
def snapshot_vm_resource_get(context, id):
session = get_session()
return _snapshot_vm_resource_get(context, id, session)
@require_context
def snapshot_vm_resource_delete(context, id):
session = get_session()
with session.begin():
session.query(models.SnapshotVMResources). \
filter_by(id=id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
""" disk resource snapshot functions """
def _set_metadata_for_vm_disk_resource_snap(
context,
vm_disk_resource_snap_ref,
metadata,
purge_metadata,
session):
"""
Create or update a set of vm_disk_resource_snap_metadata for a given snapshot
:param context: Request context
:param image_ref: An vm_disk_resource_snap object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in vm_disk_resource_snap_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'vm_disk_resource_snap_id': vm_disk_resource_snap_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_vm_disk_resource_snap_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_vm_disk_resource_snap_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_vm_disk_resource_snap_metadata_delete(
context, metadata_ref, session)
@require_context
def _vm_disk_resource_snap_metadata_create(context, values, session):
"""Create an VMDiskResourceSnapMetadata object"""
metadata_ref = models.VMDiskResourceSnapMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _vm_disk_resource_snap_metadata_update(
context, metadata_ref, values, session)
@require_context
def vm_disk_resource_snap_metadata_create(context, values):
"""Create an VMDiskResourceSnapMetadata object"""
session = get_session()
return _vm_disk_resource_snap_metadata_create(context, values, session)
def _vm_disk_resource_snap_metadata_update(
context, metadata_ref, values, session):
"""
Used internally by vm_disk_resource_snap_metadata_create and vm_disk_resource_snap_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
def _vm_disk_resource_snap_metadata_delete(context, metadata_ref, session):
"""
Used internally by vm_disk_resource_snap_metadata_create and vm_disk_resource_snap_metadata_update
"""
metadata_ref.delete(session=session)
def _vm_disk_resource_snap_update(
context, values, vm_disk_resource_snap_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if vm_disk_resource_snap_id:
vm_disk_resource_snap_ref = _vm_disk_resource_snap_get(
context, vm_disk_resource_snap_id, session)
else:
vm_disk_resource_snap_ref = models.VMDiskResourceSnaps()
if not values.get('size'):
values['size'] = 0
if not values.get('restore_size'):
values['restore_size'] = 0
vm_disk_resource_snap_ref.update(values)
vm_disk_resource_snap_ref.save(session)
_set_metadata_for_vm_disk_resource_snap(
context,
vm_disk_resource_snap_ref,
metadata,
purge_metadata,
session)
return vm_disk_resource_snap_ref
@require_context
def vm_disk_resource_snap_create(context, values):
session = get_session()
return _vm_disk_resource_snap_update(context, values, None, False, session)
@require_context
def vm_disk_resource_snap_update(
context, vm_disk_resource_snap_id, values, purge_metadata=False):
session = get_session()
return _vm_disk_resource_snap_update(
context, values, vm_disk_resource_snap_id, purge_metadata, session)
@require_context
def vm_disk_resource_snaps_get(context, snapshot_vm_resource_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.VMDiskResourceSnaps).options(
sa_orm.joinedload(
models.VMDiskResourceSnaps.metadata)).filter_by(
snapshot_vm_resource_id=snapshot_vm_resource_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
vm_disk_resource_snaps = query.all()
except sa_orm.exc.NoResultFound:
raise exception.VMDiskResourceSnapsNotFound(
snapshot_vm_resource_id=snapshot_vm_resource_id)
return vm_disk_resource_snaps
@require_context
def vm_disk_resource_snap_get_top(context, snapshot_vm_resource_id):
session = get_session()
try:
query = session.query(
models.VMDiskResourceSnaps).options(
sa_orm.joinedload(
models.VMDiskResourceSnaps.metadata)).filter_by(
snapshot_vm_resource_id=snapshot_vm_resource_id).filter_by(
top=True)
# TODO(gbasava): filter out resource snapshots if context disallows it
vm_disk_resource_snap = query.one()
except sa_orm.exc.NoResultFound:
raise exception.VMDiskResourceSnapTopNotFound(
snapshot_vm_resource_id=snapshot_vm_resource_id)
return vm_disk_resource_snap
@require_context
def vm_disk_resource_snap_get_bottom(context, snapshot_vm_resource_id):
vm_disk_resource_snap = db.vm_disk_resource_snap_get_top(
context, snapshot_vm_resource_id)
while vm_disk_resource_snap and vm_disk_resource_snap.vm_disk_resource_snap_backing_id:
vm_disk_resource_snap_backing = db.vm_disk_resource_snap_get(
context, vm_disk_resource_snap.vm_disk_resource_snap_backing_id)
if vm_disk_resource_snap_backing.snapshot_vm_resource_id == vm_disk_resource_snap.snapshot_vm_resource_id:
vm_disk_resource_snap = vm_disk_resource_snap_backing
else:
break
return vm_disk_resource_snap
@require_context
def _vm_disk_resource_snap_get(context, vm_disk_resource_snap_id, session):
try:
query = session.query(
models.VMDiskResourceSnaps).options(
sa_orm.joinedload(
models.VMDiskResourceSnaps.metadata)).filter_by(
id=vm_disk_resource_snap_id)
# TODO(gbasava): filter out deleted resource snapshots if context
# disallows it
vm_disk_resource_snap = query.one()
except sa_orm.exc.NoResultFound:
raise exception.VMDiskResourceSnapNotFound(
vm_disk_resource_snap_id=vm_disk_resource_snap_id)
return vm_disk_resource_snap
@require_context
def vm_disk_resource_snap_get(context, vm_disk_resource_snap_id):
session = get_session()
return _vm_disk_resource_snap_get(
context, vm_disk_resource_snap_id, session)
@require_context
def vm_disk_resource_snap_get_snapshot_vm_resource_id(
context, vm_disk_resource_snap_id):
vm_disk_resource_snap = vm_disk_resource_snap_get(
context, vm_disk_resource_snap_id)
return vm_disk_resource_snap.snapshot_vm_resource_id
@require_context
def vm_disk_resource_snap_delete(context, vm_disk_resource_snap_id):
session = get_session()
with session.begin():
session.query(models.VMDiskResourceSnaps). \
filter_by(id=vm_disk_resource_snap_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
""" network resource snapshot functions """
def _set_metadata_for_vm_network_resource_snap(
context,
vm_network_resource_snap_ref,
metadata,
purge_metadata,
session):
"""
Create or update a set of vm_network_resource_snap_metadata for a given snapshot
:param context: Request context
:param vm_network_resource_snap_ref: An vm_network_resource_snap object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in vm_network_resource_snap_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'vm_network_resource_snap_id': vm_network_resource_snap_ref.vm_network_resource_snap_id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_vm_network_resource_snap_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_vm_network_resource_snap_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_vm_network_resource_snap_metadata_delete(
context, metadata_ref, session)
@require_context
def _vm_network_resource_snap_metadata_create(context, values, session):
"""Create an VMNetworkResourceSnapMetadata object"""
metadata_ref = models.VMNetworkResourceSnapMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _vm_network_resource_snap_metadata_update(
context, metadata_ref, values, session)
@require_context
def vm_network_resource_snap_metadata_create(context, values):
"""Create an VMNetworkResourceSnapMetadata object"""
session = get_session()
return _vm_network_resource_snap_metadata_create(context, values, session)
def _vm_network_resource_snap_metadata_update(
context, metadata_ref, values, session):
"""
Used internally by vm_network_resource_snap_metadata_create and vm_network_resource_snap_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _vm_network_resource_snap_metadata_delete(context, metadata_ref, session):
"""
Used internally by vm_network_resource_snap_metadata_create and vm_network_resource_snap_metadata_update
"""
metadata_ref.delete(session=session)
return metadata_ref
def _vm_network_resource_snap_update(
context, vm_network_resource_snap_id, values, purge_metadata, session):
metadata = values.pop('metadata', {})
if vm_network_resource_snap_id:
vm_network_resource_snap_ref = vm_network_resource_snap_get(
context, vm_network_resource_snap_id, session)
else:
vm_network_resource_snap_ref = models.VMNetworkResourceSnaps()
vm_network_resource_snap_ref.update(values)
vm_network_resource_snap_ref.save(session)
_set_metadata_for_vm_network_resource_snap(
context,
vm_network_resource_snap_ref,
metadata,
purge_metadata,
session=session)
return vm_network_resource_snap_ref
@require_context
def vm_network_resource_snap_create(context, values):
session = get_session()
return _vm_network_resource_snap_update(
context, None, values, False, session)
@require_context
def vm_network_resource_snap_update(
context, vm_network_resource_snap_id, values, purge_metadata=False):
session = get_session()
return _vm_network_resource_snap_update(
context, values, vm_network_resource_snap_id, purge_metadata, session)
@require_context
def vm_network_resource_snaps_get(context, snapshot_vm_resource_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.VMNetworkResourceSnaps).options(
sa_orm.joinedload(
models.VMNetworkResourceSnaps.metadata)).filter_by(
vm_network_resource_snap_id=snapshot_vm_resource_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
vm_network_resource_snaps = query.all()
except sa_orm.exc.NoResultFound:
raise exception.VMNetworkResourceSnapsNotFound(
snapshot_vm_resource_id=snapshot_vm_resource_id)
return vm_network_resource_snaps
@require_context
def vm_network_resource_snap_get(context, vm_network_resource_snap_id):
session = get_session()
try:
query = session.query(
models.VMNetworkResourceSnaps).options(
sa_orm.joinedload(
models.VMNetworkResourceSnaps.metadata)).filter_by(
vm_network_resource_snap_id=vm_network_resource_snap_id)
# TODO(gbasava): filter out deleted resource snapshots if context
# disallows it
vm_network_resource_snap = query.one()
except sa_orm.exc.NoResultFound:
raise exception.VMNetworkResourceSnapNotFound(
vm_network_resource_snap_id=vm_network_resource_snap_id)
return vm_network_resource_snap
@require_context
def vm_network_resource_snap_delete(context, vm_network_resource_snap_id):
session = get_session()
with session.begin():
session.query(models.VMNetworkResourceSnaps). \
filter_by(id=vm_network_resource_snap_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
""" security group rule snapshot functions """
def _set_metadata_for_vm_security_group_rule_snap(
context,
vm_security_group_rule_snap_ref,
metadata,
purge_metadata,
session):
"""
Create or update a set of vm_security_group_rule_snap_metadata for a given snapshot
:param context: Request context
:param vm_security_group_rule_snap_ref: An vm_security_group_rule_snap object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in vm_security_group_rule_snap_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'vm_security_group_rule_snap_id': vm_security_group_rule_snap_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_vm_security_group_rule_snap_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_vm_security_group_rule_snap_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_vm_security_group_rule_snap_metadata_delete(
context, metadata_ref, session)
@require_context
def _vm_security_group_rule_snap_metadata_create(context, values, session):
"""Create an VMSecurityGroupRuleSnapMetadata object"""
metadata_ref = models.VMSecurityGroupRuleSnapMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _vm_security_group_rule_snap_metadata_update(
context, metadata_ref, values, session)
@require_context
def vm_security_group_rule_snap_metadata_create(context, values):
"""Create an VMSecurityGroupRuleSnapMetadata object"""
session = get_session()
return _vm_security_group_rule_snap_metadata_create(
context, values, session)
def _vm_security_group_rule_snap_metadata_update(
context, metadata_ref, values, session):
"""
Used internally by vm_security_group_rule_snap_metadata_create and vm_security_group_rule_snap_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _vm_security_group_rule_snap_metadata_delete(
context, metadata_ref, session):
"""
Used internally by vm_security_group_rule_snap_metadata_create and vm_security_group_rule_snap_metadata_update
"""
metadata_ref.delete(session=session)
def _vm_security_group_rule_snap_update(
context,
id,
vm_security_group_snap_id,
values,
purge_metadata,
session):
metadata = values.pop('metadata', {})
if id and vm_security_group_snap_id:
vm_security_group_rule_snap_ref = vm_security_group_rule_snap_get(
context, id, vm_security_group_snap_id, session)
else:
vm_security_group_rule_snap_ref = models.VMSecurityGroupRuleSnaps()
vm_security_group_rule_snap_ref.update(values)
vm_security_group_rule_snap_ref.save(session)
_set_metadata_for_vm_security_group_rule_snap(
context, vm_security_group_rule_snap_ref, metadata, purge_metadata, session)
return vm_security_group_rule_snap_ref
@require_context
def vm_security_group_rule_snap_create(context, values):
session = get_session()
return _vm_security_group_rule_snap_update(
context, None, None, values, False, session)
@require_context
def vm_security_group_rule_snap_update(
context, id, vm_security_group_snap_id, values, purge_metadata=False):
session = get_session()
return _vm_security_group_rule_snap_update(
context, id, vm_security_group_snap_id, values, purge_metadata, session)
@require_context
def vm_security_group_rule_snaps_get(
context, vm_security_group_snap_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.VMSecurityGroupRuleSnaps).options(
sa_orm.joinedload(
models.VMSecurityGroupRuleSnaps.metadata)).filter_by(
vm_security_group_snap_id=vm_security_group_snap_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
vm_security_group_rule_snaps = query.all()
except sa_orm.exc.NoResultFound:
raise exception.VMSecurityGroupRuleSnapsNotFound(
vm_security_group_snap_id=vm_security_group_snap_id)
return vm_security_group_rule_snaps
@require_context
def vm_security_group_rule_snap_get(context, id, vm_security_group_snap_id):
session = get_session()
try:
query = session.query(
models.VMSecurityGroupRuleSnaps).options(
sa_orm.joinedload(
models.VMSecurityGroupRuleSnaps.metadata)).filter_by(
id=id).filter_by(
vm_security_group_snap_id=vm_security_group_snap_id)
# TODO(gbasava): filter out deleted resource snapshots if context
# disallows it
vm_security_group_rule_snap = query.one()
except sa_orm.exc.NoResultFound:
raise exception.VMSecurityGroupRuleSnapNotFound(
vm_security_group_rule_snap_id=id,
vm_security_group_snap_id=vm_security_group_snap_id)
return vm_security_group_rule_snap
@require_context
def vm_security_group_rule_snap_delete(
context, id, vm_security_group_rule_snap_id):
session = get_session()
with session.begin():
session.query(models.VMSecurityGroupRuleSnaps). \
filter_by(id=id). \
filter_by(id=vm_security_group_rule_snap_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
def get_metadata_value(metadata, key, default=None):
for kvpair in metadata:
if kvpair['key'] == key:
return kvpair['value']
return default
# Restore ################################################################
""" restore functions """
@require_admin_context
def restore_mark_incomplete_as_error(context, host):
"""
mark the restores that are left hanging from previous run on host as 'error'
"""
session = get_session()
restores_query = model_query(context, models.Restores, session=session). \
filter_by(host=host)
restores_query = restores_query.filter(and_(
models.Restores.status != 'available',
models.Restores.status != 'error',
models.Restores.status != 'cancelled'))
restores = restores_query.all()
values = {'progress_percent': 100, 'progress_msg': '',
'error_msg': 'Restore did not finish successfully',
'status': 'error'}
for restore in restores:
restore.update(values)
session.add(restore)
snapshot_update(context, restore.snapshot_id, {
'status': 'available'})
session.flush()
session.close()
def _set_metadata_for_restore(context, restore_ref, metadata,
purge_metadata, session):
"""
Create or update a set of restore_metadata for a given restore
:param context: Request context
:param restore_ref: A restore object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in restore_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'restore_id': restore_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_restore_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_restore_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_restore_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _restore_metadata_create(context, values, session):
"""Create a RestoreMetadata object"""
metadata_ref = models.RestoreMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _restore_metadata_update(context, metadata_ref, values, session)
@require_context
def restore_metadata_create(context, values, session):
"""Create an RestoreMetadata object"""
session = get_session()
return _restore_metadata_create(context, values, session)
@require_context
def _restore_metadata_update(context, metadata_ref, values, session):
"""
Used internally by restore_metadata_create and restore_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _restore_metadata_delete(context, metadata_ref, session):
"""
Used internally by restore_metadata_create and restore_metadata_update
"""
metadata_ref.delete(session=session)
def _restore_update(context, values, restore_id, purge_metadata, session):
try:
lock.acquire()
metadata = values.pop('metadata', {})
if restore_id:
restore_ref = model_query(
context,
models.Restores,
session=session,
read_deleted="yes").filter_by(
id=restore_id).first()
if not restore_ref:
lock.release()
raise exception.RestoreNotFound(restore_id=restore_id)
if not values.get('uploaded_size'):
if values.get('uploaded_size_incremental'):
values['uploaded_size'] = restore_ref.uploaded_size + \
values.get('uploaded_size_incremental')
if not values.get(
'progress_percent') and restore_ref.size > 0:
values['progress_percent'] = min(
99, (100 * values.get('uploaded_size')) / restore_ref.size)
else:
restore_ref = models.Restores()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not values.get('size'):
values['size'] = 0
if not values.get('uploaded_size'):
values['uploaded_size'] = 0
if not values.get('progress_percent'):
values['progress_percent'] = 0
restore_ref.update(values)
restore_ref.save(session)
if metadata:
_set_metadata_for_restore(
context,
restore_ref,
metadata,
purge_metadata,
session=session)
return restore_ref
finally:
lock.release()
return restore_ref
@require_context
def _restore_get(context, restore_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
result = model_query(context, models.Restores, **kwargs). \
options(sa_orm.joinedload(models.Restores.metadata)). \
filter_by(id=restore_id). \
first()
if not result:
raise exception.RestoreNotFound(restore_id=restore_id)
return result
@require_context
def restore_get(context, restore_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return _restore_get(context, restore_id, **kwargs)
@require_context
def restore_get_metadata_cancel_flag(
context, restore_id, return_val=0, process=None, **kwargs):
flag = '0'
restore_obj = restore_get(context, restore_id)
for meta in restore_obj.metadata:
if meta.key == 'cancel_requested':
flag = meta.value
if return_val == 1:
return flag
if flag == '1':
if process:
process.kill()
error = _('Cancel requested for restore')
raise exception.ErrorOccurred(reason=error)
@require_context
def restore_get_all(context, snapshot_id=None, **kwargs):
if not is_admin_context(context):
if snapshot_id:
return restore_get_all_by_snapshot(context, snapshot_id, **kwargs)
else:
return restore_get_all_by_project(
context, context.project_id, **kwargs)
if snapshot_id is None:
if 'dashboard_item' in kwargs:
if kwargs.get('dashboard_item') == 'activities':
if 'time_in_minutes' in kwargs:
time_in_minutes = int(kwargs.get('time_in_minutes'))
else:
time_in_minutes = 0
time_delta = ((time_in_minutes / 60) / 24) * -1
result = \
model_query(context,
models.Restores.id,
models.Restores.deleted,
models.Restores.deleted_at,
models.Restores.display_name,
models.Restores.status,
models.Restores.created_at,
models.Restores.user_id,
models.Restores.project_id,
(models.Snapshots.display_name).label(
'snapshot_name'),
(models.Snapshots.created_at).label(
'snapshot_created_at'),
(models.Workloads.display_name).label(
'workload_name'),
(models.Workloads.created_at).label(
'workload_created_at'),
**kwargs). \
filter(
or_(models.Restores.created_at > func.adddate(func.now(), time_delta),
models.Restores.deleted_at > func.adddate(func.now(), time_delta))). \
outerjoin(models.Snapshots,
models.Restores.snapshot_id == models.Snapshots.id). \
outerjoin(models.Workloads,
models.Snapshots.workload_id == models.Workloads.id). \
order_by(models.Restores.created_at.desc()).all()
return result
else:
return model_query(context, models.Restores, **kwargs). \
options(sa_orm.joinedload(models.Restores.metadata)). \
order_by(models.Restores.created_at.desc()).all()
else:
return model_query(context, models.Restores, **kwargs). \
options(sa_orm.joinedload(models.Restores.metadata)). \
filter_by(snapshot_id=snapshot_id). \
order_by(models.Restores.created_at.desc()).all()
@require_context
def restore_get_all_by_snapshot(context, snapshot_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return model_query(context, models.Restores, **kwargs). \
options(sa_orm.joinedload(models.Restores.metadata)). \
filter_by(snapshot_id=snapshot_id). \
order_by(models.Restores.created_at.desc()).all()
@require_context
def restore_get_all_by_project(context, project_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
authorize_project_context(context, project_id)
return model_query(context, models.Restores, **kwargs). \
options(sa_orm.joinedload(models.Restores.metadata)). \
filter_by(project_id=project_id).all()
@require_context
def restore_get_all_by_project_snapshot(
context, project_id, snapshot_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
authorize_project_context(context, project_id)
return model_query(context, models.Restores, **kwargs). \
options(sa_orm.joinedload(models.Restores.metadata)). \
filter_by(project_id=project_id). \
filter_by(snapshot_id=snapshot_id). \
order_by(models.Restores.created_at.desc()).all()
@require_context
def restore_show(context, restore_id):
session = get_session()
result = model_query(context, models.Restores, session=session). \
options(sa_orm.joinedload(models.Restores.metadata)). \
filter_by(id=restore_id). \
first()
if not result:
raise exception.RestoreNotFound(restore_id=restore_id)
return result
@require_context
def restore_create(context, values):
session = get_session()
return _restore_update(context, values, None, False, session)
@require_context
def restore_update(context, restore_id, values, purge_metadata=False):
session = get_session()
return _restore_update(context, values, restore_id,
purge_metadata, session)
@require_context
def restore_delete(context, restore_id):
session = get_session()
with session.begin():
session.query(models.Restores). \
filter_by(id=restore_id).delete()
# RestoredVMs #########################################################
""" restored_vms functions """
def _set_metadata_for_restored_vms(context, restored_vm_ref, metadata,
purge_metadata, session):
"""
Create or update a set of restored_vms_metadata for a given restored_vm
:param context: Request context
:param restored_vm_ref: An restored_vm object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in restored_vm_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'restored_vm_id': restored_vm_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_restored_vms_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_restored_vms_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_restored_vms_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _restored_vms_metadata_create(context, values, session):
"""Create an RestoredMetadata object"""
metadata_ref = models.RestoredVMMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _restored_vms_metadata_update(
context, metadata_ref, values, session)
@require_context
def restored_vms_metadata_create(context, values, session):
"""Create an RestoredMetadata object"""
session = get_session()
return _restored_vms_metadata_create(context, values, session)
@require_context
def _restored_vms_metadata_update(context, metadata_ref, values, session):
"""
Used internally by restored_vms_metadata_create and restored_vms_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _restored_vms_metadata_delete(context, metadata_ref, session):
"""
Used internally by restored_vms_metadata_create and restored_vms_metadata_update
"""
metadata_ref.delete(session=session)
def _restored_vm_update(context, values, vm_id,
restore_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if vm_id:
restored_vm_ref = _restored_vm_get(context, vm_id, restore_id, session)
else:
restored_vm_ref = models.RestoredVMs()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not values.get('size'):
values['size'] = 0
restored_vm_ref.update(values)
restored_vm_ref.save(session)
if metadata:
_set_metadata_for_restored_vms(
context,
restored_vm_ref,
metadata,
purge_metadata,
session=session)
return restored_vm_ref
@require_context
def restored_vm_create(context, values):
session = get_session()
return _restored_vm_update(context, values, None, None, False, session)
@require_context
def restored_vm_update(context, vm_id, restore_id,
values, purge_metadata=False):
session = get_session()
return _restored_vm_update(
context, values, vm_id, restore_id, purge_metadata, session)
@require_context
def restored_vms_get(context, restore_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.RestoredVMs).options(
sa_orm.joinedload(
models.RestoredVMs.metadata)).filter_by(
restore_id=restore_id)
restored_vms = query.all()
except sa_orm.exc.NoResultFound:
raise exception.RestoredVMsNotFound(restore_id=restore_id)
return restored_vms
@require_context
def _restored_vm_get(context, vm_id, restore_id, session):
try:
query = session.query(
models.RestoredVMs).options(
sa_orm.joinedload(
models.RestoredVMs.metadata)).filter_by(
vm_id=vm_id).filter_by(
restore_id=restore_id)
# TODO(gbasava): filter out deleted restored_vm if context disallows it
restored_vm = query.first()
except sa_orm.exc.NoResultFound:
raise exception.RestoredVMsNotFound(restore_id=restore_id)
return restored_vm
@require_context
def restored_vm_get(context, vm_id, restore_id):
session = get_session()
return _restored_vm_get(context, vm_id, restore_id, session)
@require_context
def restored_vm_delete(context, vm_id, restore_id):
session = get_session()
with session.begin():
session.query(models.RestoredVMs). \
filter_by(vm_id=vm_id). \
filter_by(restore_id=restore_id).delete()
""" restore vm resource functions """
def _set_metadata_for_restored_vm_resource(
context,
restored_vm_resource_ref,
metadata,
purge_metadata,
session):
"""
Create or update a set of restored_vm_resource_metadata for a given restored resource
:param context: Request context
:param restored_vm_resource_ref: An restored_vm_resource object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in restored_vm_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'restored_vm_resource_id': restored_vm_resource_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_restored_vm_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_restored_vm_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
restored_vm_resource_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _restored_vm_resource_metadata_create(context, values, session):
"""Create an RestoredVMResourceMetadata object"""
metadata_ref = models.RestoredVMResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _restored_vm_resource_metadata_update(
context, metadata_ref, values, session)
@require_context
def restored_vm_resource_metadata_create(context, values):
"""Create an RestoredVMResourceMetadata object"""
session = get_session()
return _restored_vm_resource_metadata_create(context, values, session)
def _restored_vm_resource_metadata_update(
context, metadata_ref, values, session):
"""
Used internally by restored_vm_resource_metadata_create and restored_vm_resource_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def restored_vm_resource_metadata_delete(context, metadata_ref):
"""
Used internally by restored_vm_resource_metadata_create and restored_vm_resource_metadata_update
"""
session = get_session()
metadata_ref.delete(session=session)
return metadata_ref
def _restored_vm_resource_update(
context, values, restored_vm_resource_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if restored_vm_resource_id:
restored_vm_resource_ref = restored_vm_resource_get(
context, restored_vm_resource_id, session)
else:
restored_vm_resource_ref = models.RestoredVMResources()
restored_vm_resource_ref.update(values)
restored_vm_resource_ref.save(session)
_set_metadata_for_restored_vm_resource(
context,
restored_vm_resource_ref,
metadata,
purge_metadata,
session)
return restored_vm_resource_ref
@require_context
def restored_vm_resource_create(context, values):
session = get_session()
return _restored_vm_resource_update(context, values, None, False, session)
@require_context
def restored_vm_resource_update(
context, restored_vm_resource_id, values, purge_metadata=False):
session = get_session()
return _restored_vm_resource_update(
context, values, restored_vm_resource_id, purge_metadata, session)
@require_context
def restored_vm_resources_get(context, vm_id, restore_id):
session = get_session()
try:
query = session.query(
models.RestoredVMResources).options(
sa_orm.joinedload(
models.RestoredVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
restore_id=restore_id)
# TODO(gbasava): filter out deleted restores if context disallows it
restored_vm_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.RestoredVMResourcesNotFound(
restore_vm_id=vm_id, restore_id=restore_id)
return restored_vm_resources
@require_context
def restored_vm_resource_get_by_resource_name(
context, vm_id, restore_id, resource_name):
session = get_session()
try:
query = session.query(
models.RestoredVMResources).options(
sa_orm.joinedload(
models.RestoredVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
restore_id=restore_id).filter_by(
resource_name=resource_name)
# TODO(gbasava): filter out deleted restores if context disallows it
restored_vm_resources = query.first()
except sa_orm.exc.NoResultFound:
raise exception.RestoredVMResourceWithNameNotFound(
resource_name=resource_name, restore_vm_id=vm_id, restore_id=restore_id)
return restored_vm_resources
@require_context
def restored_vm_resource_get(context, id):
session = get_session()
try:
query = session.query(
models.RestoredVMResources).options(
sa_orm.joinedload(
models.RestoredVMResources.metadata)).filter_by(
id=id)
# TODO(gbasava): filter out deleted restored if context disallows it
restored_vm_resources = query.first()
except sa_orm.exc.NoResultFound:
raise exception.RestoredVMResourceWithIdNotFound(id=id)
return restored_vm_resources
@require_context
def restored_vm_resource_delete(context, id, vm_id, restore_id):
session = get_session()
with session.begin():
session.query(models.RestoredVMResources). \
filter_by(id=id). \
filter_by(vm_id=vm_id). \
filter_by(restore_id=restore_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
# project quota types ####################################################
def get_all_project_quota_types(quota_type_id=None):
session = get_session()
with session.begin():
if quota_type_id:
return session.query(models.ProjectQuotaTypes).filter_by(
id=quota_type_id
).all()
else:
return session.query(models.ProjectQuotaTypes).all()
def create_project_quota_type(quota_type_data):
session = get_session()
with session.begin():
metadata_ref = models.ProjectQuotaTypes()
metadata_ref.update(quota_type_data)
metadata_ref.save(session=session)
return metadata_ref
def update_project_quota_types(update_dict):
session = get_session()
with session.begin():
session.query(models.ProjectQuotaTypes).update(update_dict)
# project allowed quotas ####################################################
@require_admin_context
def get_allowed_quotas(
context, project_id=None, allowed_quota_id=None, quota_type_id=None
):
session = get_session()
params = {
"deleted": False,
}
if project_id:
params.update({"project_id": project_id})
if allowed_quota_id:
params.update({"id": allowed_quota_id})
if quota_type_id:
params.update({"quota_type_id": quota_type_id})
with session.begin():
return session.query(models.AllowedQuota).filter_by(**params).all()
@require_admin_context
def create_allowed_quotas(context, allowed_quota_data):
session = get_session()
with session.begin():
res = models.AllowedQuota.save_multiple(
allowed_quota_data, session=session
)
return res
@require_admin_context
def modify_allowed_quotas(context, id, allowed_quota_data):
session = get_session()
with session.begin():
project_id = allowed_quota_data["project_id"]
allowed_quota_data.pop("project_id", None)
obj = session.query(models.AllowedQuota).filter_by(
id=id, project_id=project_id, deleted=False
)
return obj.update(allowed_quota_data)
@require_admin_context
def delete_allowed_quota(context, allowed_quota_id):
session = get_session()
with session.begin():
session.query(models.AllowedQuota). \
filter_by(id=allowed_quota_id). \
update({'deleted': True,
'allowed_value': -1,
'high_watermark': -1,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
# Setting ################################################################
""" setting functions """
def _set_metadata_for_setting(context, setting_ref, metadata,
purge_metadata, session):
"""
Create or update a set of setting_metadata for a given setting
:param context: Request context
:param setting_ref: A setting object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in setting_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'settings_name': setting_ref.name,
'settings_project_id': setting_ref.project_id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_setting_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_setting_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_setting_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _setting_metadata_create(context, values, session):
"""Create a SettingMetadata object"""
metadata_ref = models.SettingMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _setting_metadata_update(context, metadata_ref, values, session)
@require_context
def setting_metadata_create(context, values, session):
"""Create a SettingMetadata object"""
session = get_session()
return _setting_metadata_create(context, values, session)
@require_context
def _setting_metadata_update(context, metadata_ref, values, session):
"""
Used internally by setting_metadata_create and setting_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _setting_metadata_delete(context, metadata_ref, session):
"""
Used internally by setting_metadata_create and setting_metadata_update
"""
metadata_ref.delete(session=session)
def _setting_update(context, values, setting_name, purge_metadata, session, cloud_setting=False):
try:
lock.acquire()
metadata = values.pop('metadata', {})
if setting_name:
if cloud_setting is True:
setting_ref = model_query(context, models.Settings, session=session, read_deleted="yes"). \
filter_by(name=setting_name). \
first()
else:
setting_ref = model_query(context, models.Settings, session=session, read_deleted="yes"). \
filter_by(name=setting_name). \
filter_by(project_id=context.project_id). \
first()
if not setting_ref:
lock.release()
raise exception.SettingNotFound(setting_name=setting_name)
else:
setting_ref = models.Settings()
if not values.get('status'):
values['status'] = 'available'
if not values.get('project_id'):
values['project_id'] = context.project_id
if 'is_hidden' in values:
values['hidden'] = int(values['is_hidden'])
setting_ref.update(values)
setting_ref.save(session)
if metadata:
_set_metadata_for_setting(
context,
setting_ref,
metadata,
purge_metadata,
session=session)
return setting_ref
finally:
lock.release()
return setting_ref
@require_context
def _setting_get(context, setting_name, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
get_hidden = kwargs.get('get_hidden', False)
cloud_setting = kwargs.get('cloud_setting', False)
if cloud_setting is True:
result = model_query(context, models.Settings, **kwargs). \
filter_by(hidden=get_hidden). \
options(sa_orm.joinedload(models.Settings.metadata)). \
filter_by(name=setting_name). \
first()
else:
result = model_query(context, models.Settings, **kwargs). \
filter_by(hidden=get_hidden). \
options(sa_orm.joinedload(models.Settings.metadata)). \
filter_by(name=setting_name). \
filter_by(project_id=context.project_id). \
first()
if not result:
if setting_name == 'page_size':
return 10
else:
raise exception.SettingNotFound(setting_name=setting_name)
return result
@require_context
def setting_get(context, setting_name, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return _setting_get(context, setting_name, **kwargs)
def setting_get_all(context, **kwargs):
if context and not is_admin_context(context):
return setting_get_all_by_project(
context, context.project_id, **kwargs)
get_hidden = kwargs.get('get_hidden', False)
setting_type = kwargs.get('type', None)
qs = model_query(context, models.Settings, **kwargs). \
options(sa_orm.joinedload(models.Settings.metadata))
if 'backup_settings' in kwargs:
qs = qs.filter(models.Settings.project_id != 'Configurator')
elif setting_type:
qs = qs.filter_by(hidden=get_hidden, type=setting_type)
else:
qs = qs.filter_by(hidden=get_hidden)
return qs.order_by(models.Settings.created_at.desc()).all()
@require_context
def setting_get_all_by_project(context, project_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
if kwargs.get('is_cloud_admin', False):
kwargs['user_id'] = 'cloud_admin'
kwargs.pop('is_cloud_admin', None)
authorize_project_context(context, project_id)
filter_options = {'project_id': project_id}
valid_keys = ['type', 'user_id']
filter_options.update({key: value for key, value in kwargs.items() if key in valid_keys})
return model_query(context, models.Settings, **kwargs). \
options(sa_orm.joinedload(models.Settings.metadata)). \
filter_by(**filter_options).all()
@require_context
def setting_create(context, values):
session = get_session()
return _setting_update(context, values, None, False, session)
@require_context
def setting_bulk_create(context, setting_values, setting_metadata_values):
session = get_session()
try:
lock.acquire()
# insert all the settings and setting_metadata in bulk
session.bulk_insert_mappings(models.Settings, setting_values)
session.bulk_insert_mappings(models.SettingMetadata, setting_metadata_values)
return True
finally:
lock.release()
@require_context
def setting_update(context, setting_name, values, purge_metadata=False, cloud_setting=False):
session = get_session()
return _setting_update(context, values, setting_name, purge_metadata, session, cloud_setting)
@require_context
def setting_delete(context, setting_name):
session = get_session()
try:
setting = _setting_get(context, setting_name, session=session)
except BaseException:
setting = _setting_get(
context,
setting_name,
session=session,
get_hidden=True)
for metadata_ref in setting.metadata:
metadata_ref.purge(session=session)
session.refresh(setting)
setting.purge(session=session)
"""
Permanent Deletes
"""
@require_context
def purge_snapshot(context, id, session=None):
if session is None:
session = get_session()
for snapshot_vm_resource in snapshot_resources_get(
context, id, session=session):
if snapshot_vm_resource.resource_type == 'disk':
for vm_disk_resource_snap in vm_disk_resource_snaps_get(
context, snapshot_vm_resource.id, session=session):
for metadata_ref in vm_disk_resource_snap.metadata:
metadata_ref.purge(session)
session.refresh(vm_disk_resource_snap)
vm_disk_resource_snap.purge(session)
if snapshot_vm_resource.resource_type == 'network' or \
snapshot_vm_resource.resource_type == 'subnet' or \
snapshot_vm_resource.resource_type == 'router' or \
snapshot_vm_resource.resource_type == 'nic':
for vm_network_resource_snap in vm_network_resource_snaps_get(
context, snapshot_vm_resource.id, session=session):
for metadata_ref in vm_network_resource_snap.metadata:
metadata_ref.purge(session)
session.refresh(vm_network_resource_snap)
vm_network_resource_snap.purge(session)
if snapshot_vm_resource.resource_type == 'security_group':
for vm_security_group_rule_snap in vm_security_group_rule_snaps_get(
context, snapshot_vm_resource.id, session=session):
for metadata_ref in vm_network_resource_snap.metadata:
metadata_ref.purge(session)
session.refresh(vm_security_group_rule_snap)
vm_security_group_rule_snap.purge(session)
for metadata_ref in snapshot_vm_resource.metadata:
metadata_ref.purge(session)
session.refresh(snapshot_vm_resource)
snapshot_vm_resource.purge(session)
for snapshot_vm in snapshot_vms_get(context, id, session=session):
for metadata_ref in snapshot_vm.metadata:
metadata_ref.purge(session)
vm_recent_snapshot = vm_recent_snapshot_get(
context, snapshot_vm.vm_id, session=session)
if vm_recent_snapshot:
vm_recent_snapshot.purge(session)
session.refresh(snapshot_vm)
snapshot_vm.purge(session)
snapshot = snapshot_get(context, id, session=session, read_deleted='yes')
if snapshot:
snapshot.purge(session)
@require_admin_context
def purge_workload(context, id):
try:
session = get_session()
for snapshot in snapshot_get_all(
context, session=session, read_deleted='yes'):
purge_snapshot(context, snapshot.id, session)
for workload_vm in workload_vms_get(context, id, session=session):
for metadata_ref in workload_vm.metadata:
metadata_ref.purge(session)
session.refresh(workload_vm)
workload_vm.purge(session)
workload = _workload_get(context, id, session=session)
if workload:
for metadata_ref in workload.metadata:
metadata_ref.purge(session)
session.refresh(workload)
workload.purge(session)
except Exception as ex:
LOG.exception(ex)
@require_admin_context
def config_workload_update(context, values):
session = get_session()
return _config_workload_update(context, values, session)
@require_admin_context
def config_workload_get(context, **kwargs):
session = get_session()
return _config_workload_get(context, session, **kwargs)
def _config_workload_update(context, values, session):
metadata = values.pop('metadata', {})
try:
config_workload_ref = _config_workload_get(context, session)
except Exception as ex:
config_workload_ref = models.ConfigWorkloads()
if not values.get('id'):
values['id'] = CONF.cloud_unique_id
config_workload_ref.update(values)
config_workload_ref.save(session)
if metadata:
_set_metadata_for_config_workload(
context, config_workload_ref, metadata, session=session)
return config_workload_ref
def _config_workload_get(context, session, **kwargs):
try:
config_workload = model_query(
context, models.ConfigWorkloads, session=session, **kwargs). \
options(sa_orm.joinedload(models.ConfigWorkloads.metadata)). \
filter_by(id=CONF.cloud_unique_id).first()
if config_workload is None:
raise exception.ConfigWorkloadNotFound(id=CONF.cloud_unique_id)
except sa_orm.exc.NoResultFound:
raise exception.ConfigWorkloadNotFound(id=CONF.cloud_unique_id)
return config_workload
def _set_metadata_for_config_workload(
context, config_workload_ref, metadata, session):
"""
Create or update a set of config_workload_metadata for a given config_workload
"""
orig_metadata = {}
for metadata_ref in config_workload_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'config_workload_id': config_workload_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_config_workload_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_config_workload_metadata_create(context, metadata_values, session)
def _config_workload_metadata_create(context, values, session):
"""Create an ConfigWorkloadMetadata object"""
metadata_ref = models.ConfigWorkloadMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _config_workload_metadata_update(
context, metadata_ref, values, session)
@require_admin_context
def config_workload_metadata_create(context, values, session):
"""Create an ConfigWorkloadMetadata object"""
session = get_session()
return _config_workload_metadata_create(context, values, session)
def _config_workload_metadata_update(context, metadata_ref, values, session):
"""
Used internally by config_workload_metadata_create and config_workload_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
def _config_workload_metadata_delete(context, metadata_ref, session):
"""
Used internally by config_workload_metadata_create and config_workload_metadata_create
"""
metadata_ref.delete(session=session)
# Workload Policy API's
@require_admin_context
def _policy_field_update(context, policy_field_id, values, session):
if policy_field_id:
policy_field_ref = _policy_field_get(context, policy_field_id, session)
else:
policy_field_ref = models.WorkloadPolicyFields()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
policy_field_ref.update(values)
policy_field_ref.save(session)
return policy_field_ref
@require_admin_context
def policy_field_create(context, values, **kwargs):
session = get_session()
return _policy_field_update(context, None, values, session)
@require_admin_context
def policy_field_update(context, id, values, **kwargs):
session = get_session()
return _policy_field_update(context, id, values, session)
@require_admin_context
def policy_fields_get_all(context, **kwargs):
session = get_session()
try:
query = model_query(
context, models.WorkloadPolicyFields, session=session,
read_deleted="no")
policy_fields = query.all()
except sa_orm.exc.NoResultFound:
raise exception.PolicyFieldNotFound()
return policy_fields
@require_admin_context
def policy_field_get(context, id, **kwargs):
session = get_session()
return _policy_field_get(context, id, session)
@require_admin_context
def _policy_field_get(context, id, session):
try:
policy_field = model_query(
context, models.WorkloadPolicyFields, session=session, read_deleted="no"). \
filter_by(id=id).first()
except sa_orm.exc.NoResultFound:
raise exception.PolicyFieldNotFound(policy_field_id=id)
if policy_field is None:
raise exception.PolicyFieldNotFound(policy_field_id=id)
return policy_field
@require_admin_context
def policy_field_delete(context, id, **kwargs):
session = get_session()
with session.begin():
session.query(models.WorkloadPolicyFields). \
filter_by(id=id).delete()
@require_admin_context
def _policy_update(context, values, policy_id, purge_metadata, session):
metadata = values.pop('metadata', {})
field_values = values.pop('field_values', {})
if policy_id:
policy_ref = _policy_get(context, policy_id, session)
else:
policy_ref = models.WorkloadPolicy()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
policy_ref.update(values)
policy_ref.save(session)
if metadata:
_set_metadata_for_policy(
context, policy_ref, metadata, purge_metadata, session)
if field_values:
field_values = _set_field_values_for_policy(
context, policy_ref, field_values, session)
return policy_ref
@require_admin_context
def policy_create(context, values, **kwargs):
session = get_session()
return _policy_update(context, values, None, False, session)
@require_admin_context
def policy_update(context, id, values, purge_metadata=False, **kwargs):
session = get_session()
return _policy_update(context, values, id, purge_metadata, session)
@require_admin_context
def policy_get_all(context, **kwargs):
qs = model_query(context, models.WorkloadPolicy, read_deleted="no", **kwargs). \
options(sa_orm.joinedload(models.WorkloadPolicy.metadata)). \
options(sa_orm.joinedload(models.WorkloadPolicy.field_values))
return qs.all()
def _policy_get(context, id, session, **kwargs):
try:
policy = model_query(
context, models.WorkloadPolicy, session=session, read_deleted="no", **kwargs). \
options(sa_orm.joinedload(models.WorkloadPolicy.metadata)). \
options(sa_orm.joinedload(models.WorkloadPolicy.field_values)). \
options(sa_orm.joinedload(models.WorkloadPolicy.policy_assignments)). \
filter_by(id=id).first()
if policy is None:
raise exception.PolicyNotFound(policy_id=id)
except sa_orm.exc.NoResultFound:
raise exception.PolicyNotFound(policy_id=id)
return policy
@require_context
def policy_get(context, id, **kwargs):
session = get_session()
return _policy_get(context, id, session, **kwargs)
@require_admin_context
def policy_delete(context, id, **kwargs):
session = get_session()
with session.begin():
session.query(models.WorkloadPolicy). \
filter_by(id=id).delete()
def _set_metadata_for_policy(context, policy_ref, metadata,
purge_metadata, session):
"""
Create or update a set of policy_metadata for a given policy
:param context: Request context
:param policy_ref: An policy object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in policy_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'policy_id': policy_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_policy_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_policy_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_policy_metadata_delete(context, metadata_ref, session)
def _policy_metadata_create(context, values, session):
"""Create an WorkloadPolicyMetadata object"""
metadata_ref = models.WorkloadPolicyMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _policy_metadata_update(context, metadata_ref, values, session)
@require_admin_context
def policy_metadata_create(context, values, **kwargs):
"""Create an WorkloadPolicyMetadata object"""
session = get_session()
return _policy_metadata_create(context, values, session)
def _policy_metadata_update(context, metadata_ref, values, session):
"""
Used internally by policy_metadata_create and policy_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
def _policy_metadata_delete(context, metadata_ref, session):
"""
Used internally by policy_metadata_create and policy_metadata_update
"""
metadata_ref.delete(session=session)
return metadata_ref
def _set_field_values_for_policy(context, policy_ref, policy_field_values,
session):
"""
Create or update a set of policy_values for a given policy
:param context: Request context
:param policy_ref: An policy object
:param policy_field_values: A dict of policy values to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_field_values = {}
for field_value in policy_ref.field_values:
orig_field_values[field_value.policy_field_name] = field_value
for field_name, field_value in policy_field_values.items():
field_values = {'policy_id': policy_ref.id,
'policy_field_name': field_name,
'value': field_value}
if field_name in orig_field_values:
field_value_ref = orig_field_values[field_name]
_policy_value_update(context, field_value_ref,
field_values, session)
else:
_policy_value_create(context, field_values, session)
def _policy_value_create(context, values, session):
"""Create an WorkloadPolicyValues object"""
policy_value_ref = models.WorkloadPolicyValues()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _policy_value_update(context, policy_value_ref, values, session)
@require_admin_context
def policy_value_create(context, values, **kwargs):
"""Create an WorkloadPolicyValues object"""
session = get_session()
return _policy_value_create(context, values, session)
def _policy_value_update(context, policy_value_ref, values, session):
"""
Used internally by policy_value_create and policy_value_update
"""
values["deleted"] = False
policy_value_ref.update(values)
policy_value_ref.save(session=session)
return policy_value_ref
@require_admin_context
def policy_values_get_all(context, **kwargs):
session = get_session()
try:
query = model_query(
context, models.WorkloadPolicyValues, session=session,
read_deleted="no")
policy_values = query.all()
except sa_orm.exc.NoResultFound:
raise exception.PolicyValueNotFound()
return policy_values
@require_admin_context
def policy_value_get(context, id, **kwargs):
session = get_session()
try:
query = session.query(models.WorkloadPolicyValues) \
.filter_by(id=id)
policy_values = query.first()
except sa_orm.exc.NoResultFound:
raise exception.PolicyValueNotFound(policy_value_id=id)
if policy_values is None:
raise exception.PolicyValueNotFound(policy_value_id=id)
return policy_values
@require_admin_context
def policy_value_delete(context, id, **kwargs):
session = get_session()
with session.begin():
session.query(models.WorkloadPolicyValues). \
filter_by(id=id).delete()
def _policy_assignment_update(context, values, policy_assignment_id, session):
if policy_assignment_id:
policy_assignment_ref = _policy_assignment_get(
context, policy_assignment_id, session)
else:
policy_assignment_ref = models.WorkloadPolicyAssignmnets()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
policy_assignment_ref.update(values)
policy_assignment_ref.save(session)
return policy_assignment_ref
@require_admin_context
def policy_assignment_create(context, values, **kwargs):
session = get_session()
return _policy_assignment_update(context, values, None, session)
@require_admin_context
def policy_assignment_update(context, id, values, **kwargs):
session = get_session()
return _policy_assignment_update(context, values, id, session)
@require_context
def policy_assignments_get_all(context, **kwargs):
session = get_session()
query = session.query(models.WorkloadPolicyAssignmnets)
if 'policy_id' in kwargs and kwargs['policy_id'] is not None:
query = query.filter_by(policy_id=kwargs['policy_id'])
if 'project_id' in kwargs and kwargs['project_id'] is not None:
query = query.filter_by(project_id=kwargs['project_id'])
if (kwargs.get('workloads', False) is True) \
and ('policy_id' in kwargs and kwargs['policy_id'] is not None):
query = session.query(models.Workloads.id).join(models.WorkloadMetadata).filter(
and_(models.WorkloadMetadata.key == 'policy_id'), models.WorkloadMetadata.value == kwargs['policy_id'],
models.Workloads.deleted == False)
if 'project_id' in kwargs and kwargs['project_id'] is not None:
query = query.filter(
models.Workloads.project_id == kwargs['project_id'])
policy_assignments = query.all()
return policy_assignments
def _policy_assignment_get(context, id, session, **kwargs):
try:
policy_assignments = model_query(
context, models.WorkloadPolicyAssignmnets, session=session). \
filter_by(id=id).first()
except sa_orm.exc.NoResultFound:
raise exception.PolicyAssignmentNotFound(policy_assignment_id=id)
if policy_assignments is None:
raise exception.PolicyAssignmentNotFound(policy_assignment_id=id)
return policy_assignments
@require_admin_context
def policy_assignment_get(context, id, **kwargs):
session = get_session()
return _policy_assignment_get(context, id, session)
@require_admin_context
def policy_assignment_delete(context, id, **kwargs):
session = get_session()
with session.begin():
session.query(models.WorkloadPolicyAssignmnets). \
filter_by(id=id).delete()
@require_admin_context
def get_tenants_usage(context, **kwargs):
"""Give storage used by tenant workloads"""
try:
tenant_chargeback = {}
session = get_session()
qry = session.query(models.Snapshots.project_id, func.sum(cast(models.Snapshots.size, Integer))). \
group_by(models.Snapshots.project_id).filter_by(deleted=False)
result = qry.all()
for proj_id, storage_used in result:
if proj_id not in tenant_chargeback:
tenant_chargeback[proj_id] = {}
tenant_chargeback[proj_id]['vms_protected'] = []
tenant_chargeback[proj_id]['used_capacity'] = int(storage_used)
qry = session.query(models.Workloads.project_id, models.WorkloadVMs.vm_id).join(
models.WorkloadVMs).filter_by(deleted=False)
result = qry.all()
for proj_id, vm_protected in result:
if proj_id not in tenant_chargeback:
tenant_chargeback[proj_id] = {
'vms_protected': [], 'used_capacity': 0}
tenant_chargeback[proj_id]['vms_protected'].append(vm_protected)
return tenant_chargeback
except Exception as ex:
LOG.exception(ex)
""" snapshot network resource methods """
@require_context
def snapshot_network_resource_create(context, values):
session = get_session()
return _snapshot_network_resource_update(context, None, values, False, session)
@require_context
def snapshot_network_resource_update(context, id, values, purge_metadata=False):
session = get_session()
return _snapshot_network_resource_update(context, id, values,
purge_metadata, session)
def _snapshot_network_resource_update(context, resource_id, values, purge_metadata, session):
try:
with lock:
metadata = values.pop('metadata', {})
if resource_id:
resource_ref = model_query(
context,
models.SnapNetworkResources,
session=session).filter_by(
id=resource_id).first()
if not resource_ref:
raise exception.NetworkResourceNotFound(
resource_id=resource_id)
else:
resource_ref = models.SnapNetworkResources()
values['id'] = values.get('id', str(uuid.uuid4()))
values['name'] = values.get('name', "")
values['type'] = values.get('type', "")
values['status'] = values.get('status', "available")
resource_ref.update(values)
resource_ref.save(session)
if metadata:
_set_metadata_for_snap_network_resource(
context,
resource_ref,
metadata,
purge_metadata,
session=session)
return resource_ref
except Exception as ex:
LOG.exception(ex)
raise ex
@require_context
def snapshot_network_resource_get(context, resource_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return _snapshot_network_resource_get(context, resource_id, **kwargs)
def _snapshot_network_resource_get(context, resource_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
result = model_query(context, models.SnapNetworkResources, **kwargs). \
options(sa_orm.joinedload(models.SnapNetworkResources.metadata)). \
filter_by(id=resource_id). \
first()
if not result:
raise exception.NetworkResourceNotFound(resource_id=resource_id)
return result
@require_context
def snapshot_network_resources_get(context, snapshot_id, **kwargs):
try:
qs = model_query(context, models.SnapNetworkResources, **kwargs). \
options(sa_orm.joinedload(models.SnapNetworkResources.metadata)). \
filter_by(snapshot_id=snapshot_id)
if 'type' in kwargs:
qs = qs.filter(models.SnapNetworkResources.type == kwargs['type'])
except sa_orm.exc.NoResultFound:
raise exception.NetworkResourcesNotFound(snapshot_id=snapshot_id)
return qs.all()
@require_context
def snapshot_network_resource_delete(context, resource_id):
session = get_session()
with session.begin():
session.query(models.SnapNetworkResources). \
filter_by(id=resource_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
# Metadata
@require_context
def snapshot_network_resource_metadata_create(context, values):
session = get_session()
return _snapshot_network_resource_metadata_create(context, values, session)
def _snapshot_network_resource_metadata_create(context, values, session):
"""Create an SnapshotVMResourceMetadata object"""
metadata_ref = models.SnapNetworkResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _snapshot_network_resource_metadata_update(
context, metadata_ref, values, session)
def _snapshot_network_resource_metadata_update(context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def snapshot_network_resource_metadata_delete(context, metadata_ref, session):
metadata_ref.delete(session=session)
def _set_metadata_for_snap_network_resource(context, resource_ref, metadata,
purge_metadata, session):
orig_metadata = {}
for metadata_ref in resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'snap_network_resource_id': resource_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_snapshot_network_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
snapshot_network_resource_metadata_create(context, metadata_values)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
snapshot_network_resource_metadata_delete(
context, metadata_ref, session=session)
""" Scheduled job resource methods """
@require_context
def job_create(context, values, **kwargs):
""" Create new scheduled job """
session = get_session()
return _job_update(context, values, session, None)
@require_context
def job_update(context, job_id, values, **kwargs):
""" Update existing scheduled jobs """
if not job_id:
message = "Please provide job_id to update"
LOG.exception(message)
raise Exception(message)
session = get_session()
return _job_update(context, values, session, job_id)
def _job_update(context, values, session, job_id):
job_ref = []
if job_id:
kwargs = {'id': job_id}
job_ref = _job_get(context, session, **kwargs)
if not job_ref:
LOG.exception("No job found with job_id: %s for workload: %s" % (job_id, values['workload_id']))
raise exception.ScheduledJobsNotFound(workload_id=values['workload_id'])
else:
job_ref = job_ref[0]
else:
job_ref = models.ScheduledJobs()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not job_ref:
raise Exception("No job found to update")
job_ref.update(values)
job_ref.save(session)
return job_ref
@require_context
def job_get_all(context, **kwargs):
"""List all scheduled jobs"""
session = get_session()
return _job_get(context, session, None, **kwargs)
@require_context
def job_get(context, workload_id, **kwargs):
"""Show given job"""
session = get_session()
jobs = _job_get(context, session, workload_id, **kwargs)
if jobs:
return jobs[0]
def _job_get(context, session, workload_id=None, **kwargs):
try:
if kwargs:
filter_params = set(kwargs.keys())
model_params = set(models.ScheduledJobs.__dict__.keys())
invalid_params = list(filter_params - model_params)
if invalid_params:
raise Exception('Can not filter jobs with these keys: %s' \
% (str(invalid_params)))
qs = model_query(context, models.ScheduledJobs, session=session, **kwargs)
if workload_id:
qs = qs.filter(models.ScheduledJobs.workload_id == workload_id)
if 'id' in kwargs:
qs = qs.filter(models.ScheduledJobs.id == kwargs['id'])
return qs.all()
except sa_orm.exc.NoResultFound:
raise exception.ScheduledJobsNotFound(workload_id=workload_id)
@require_context
def job_delete(context, workload_id, **kwargs):
"""Delete given job"""
session = get_session()
with session.begin():
session.query(models.ScheduledJobs). \
filter_by(workload_id=workload_id). \
delete()
@require_context
def job_multiple_delete(context, job_ids):
"""Delete given jobs"""
session = get_session()
with session.begin():
session.query(models.ScheduledJobs). \
filter(models.ScheduledJobs.id.in_(job_ids)).\
delete(synchronize_session=False)
@require_context
def _migration_plan_metadata_create(context, values, session):
"""Create an WorkloadMetadata object"""
metadata_ref = models.MigrationPlanMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_plan_metadata_update(context, metadata_ref, values, session)
@require_context
def migration_plan_metadata_create(context, values, session):
"""Create an MigrationPlanMetadata object"""
session = get_session()
return _migration_plan_metadata_create(context, values, session)
@require_context
def _migration_plan_metadata_update(context, metadata_ref, values, session):
"""
Used internally by migration_plan_metadata_create and migration_plan_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_plan_metadata_delete(context, metadata_ref, session):
"""
Used internally by migration_plan_metadata_create and migration_plan_metadata_update
"""
metadata_ref.delete(session=session)
def _set_metadata_for_migration_plan(context, migration_plan_ref, metadata,
purge_metadata, session):
"""
Create or update a set of migration_plan_metadata for a given migration_plan
:param context: Request context
:param migration_plan_ref: An migration_plan object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in migration_plan_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'migration_plan_id': migration_plan_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_metadata_delete(
context, metadata_ref, session=session)
@require_context
def migration_plan_create(context, values):
session = get_session()
return _migration_plan_update(context, values, None, False, session)
@require_context
def migration_plan_delete(context, id):
session = get_session()
with session.begin():
session.query(models.MigrationPlans). \
filter_by(id=id).delete()
@require_context
def migration_plan_update(context, id, values, purge_metadata=False):
session = get_session()
return _migration_plan_update(context, values, id, purge_metadata, session)
def _migration_plan_update(context, values, migration_plan_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if migration_plan_id:
migration_plan_ref = _migration_plan_get(context, migration_plan_id, session)
else:
migration_plan_ref = models.MigrationPlans()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
migration_plan_ref.update(values)
migration_plan_ref.save(session)
if metadata:
_set_metadata_for_migration_plan(
context,
migration_plan_ref,
metadata,
purge_metadata,
session=session)
return migration_plan_ref
@require_context
def _migration_plan_get(context, mp_id, session, **kwargs):
try:
migration_plan = model_query(
context, models.MigrationPlans, session=session, **kwargs). \
options(sa_orm.joinedload(models.MigrationPlans.metadata)). \
filter_by(id=mp_id).all()
if not migration_plan:
raise exception.MigrationPlanNotFound(migration_plan_id=mp_id)
return migration_plan[0]
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanNotFound(migration_plan_id=mp_id)
except Exception as ex:
LOG.exception(ex)
raise exception.MigrationPlanNotFound(migration_plan_id=mp_id)
@require_context
def migration_plan_resources_get(context, migration_plan_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationPlanVMResources).options(
sa_orm.joinedload(
models.MigrationPlanVMResources.metadata)).filter_by(
migration_plan_id=migration_plan_id)
migration_plan_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanResourcesNotFound(migration_plan_id=migration_plan_id)
return migration_plan_resources
@require_context
def migration_plan_vms_get(context, migration_plan_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
if migration_plan_id:
query = model_query(context, models.MigrationPlanVMs,
session=session, read_deleted="no") \
.options(sa_orm.joinedload(models.MigrationPlanVMs.metadata)) \
.filter_by(migration_plan_id=migration_plan_id) \
.filter(models.MigrationPlanVMs.status is not None)
else:
query = model_query(context, models.MigrationPlanVMs,
session=session, read_deleted="no") \
.options(sa_orm.joinedload(models.MigrationPlanVMs.metadata)) \
.filter(models.MigrationPlanVMs.status is not None)
# TODO(gbasava): filter out deleted workload_vms if context disallows
# it
migration_plan_vms = query.all()
except sa_orm.exc.NoResultFound:
raise exception.WorkloadVMsNotFound(migration_plan_id=migration_plan_id)
return migration_plan_vms
@require_context
def migration_plan_vms_delete(context, vm_id, migration_plan_id):
session = get_session()
with session.begin():
session.query(models.MigrationPlanVMs). \
filter_by(vm_id=vm_id). \
filter_by(migration_plan_id=migration_plan_id).delete()
@require_context
def migration_plan_vm_get_by_id(context, vm_id, **kwargs):
session = kwargs.get('session') or get_session()
read_deleted = 'no'
if 'read_deleted' in kwargs:
read_deleted = kwargs['read_deleted']
try:
query = model_query(context, models.MigrationPlanVMs,
session=session, read_deleted=read_deleted) \
.options(sa_orm.joinedload(models.MigrationPlanVMs.metadata)) \
.join(models.MigrationPlans) \
.filter(models.MigrationPlanVMs.status is not None) \
.filter(models.MigrationPlanVMs.vm_id == vm_id) \
.filter(models.MigrationPlans.project_id == context.project_id)
if 'migration_plans_filter' in kwargs:
query = query.filter(
and_(
models.MigrationPlans.status != kwargs['migration_plans_filter'],
models.MigrationPlans.status is not None))
if 'migration_plan_id' in kwargs:
query = query.filter(
and_(
models.MigrationPlans.id == kwargs['migration_plan_id']))
vm_found = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMsNotFound(vm_id=vm_id)
return vm_found
@require_context
def migration_plan_vms_create(context, values):
session = get_session()
return _migration_plan_vms_update(context, values, None, False, session)
@require_context
def migration_plan_vms_update(context, id, values, purge_metadata=False):
session = get_session()
return _migration_plan_vms_update(context, values, id, purge_metadata, session)
def _migration_plan_vms_update(context, values, id, purge_metadata, session):
metadata = values.pop('metadata', {})
if id:
migration_plan_vm_ref = _migration_plan_vm_get_for_update(context, id, session)
else:
migration_plan_vm_ref = models.MigrationPlanVMs()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
migration_plan_vm_ref.update(values)
migration_plan_vm_ref.save(session)
if metadata:
_set_metadata_for_migration_plan_vms(
context,
migration_plan_vm_ref,
metadata,
purge_metadata,
session=session)
return migration_plan_vm_ref
@require_context
def _migration_plan_vm_get_for_update(context, id, session):
try:
query = session.query(
models.MigrationPlanVMs).options(
sa_orm.joinedload(
models.MigrationPlanVMs.metadata)).filter_by(
id=id)
# TODO(gbasava): filter out deleted migration_plan_vms if context disallows
# it
migration_plan_vm = query.first()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMNotFound(migration_plan_vm_id=id)
return migration_plan_vm
@require_context
def _migration_plan_vms_metadata_update(context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_plan_vms_metadata_create(context, values, session):
"""Create an MigrationPlanMetadata object"""
metadata_ref = models.MigrationPlanVMMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_plan_vms_metadata_update(
context, metadata_ref, values, session)
def _set_metadata_for_migration_plan_vms(context, migration_plan_vm_ref, metadata,
purge_metadata, session):
"""
Create or update a set of workload_vms_metadata for a given workload_vm
:param context: Request context
:param workload_vm_ref: An workload_vm object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in migration_plan_vm_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'migration_plan_vm_id': migration_plan_vm_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vms_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_vms_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vms_metadata_delete(
context, metadata_ref, session=session)
@require_context
def migration_plan_get_by_vmid(context, **kwargs):
session = kwargs.get('session') or get_session()
vms_obj = model_query(context, models.MigrationPlanVMs,
session=session, read_deleted="no") \
.filter(models.MigrationPlanVMs.status is not None).filter_by(vm_id=kwargs.get('vm_id')).first()
if vms_obj:
qs = model_query(context, models.MigrationPlans, **kwargs). \
options(sa_orm.joinedload(models.MigrationPlans.metadata)).filter_by(project_id=context.project_id, id=vms_obj.migration_plan_id)
return qs.all()
@require_context
def migration_plan_get_all(context, **kwargs):
qs = model_query(context, models.MigrationPlans, **kwargs). \
options(sa_orm.joinedload(models.MigrationPlans.metadata))
if is_admin_context(context):
if 'project_id' in kwargs and kwargs['project_id'] is not None and kwargs['project_id'] != '':
qs = qs.filter_by(project_id=kwargs['project_id'])
elif 'all_migration_plans' in kwargs and kwargs['all_migration_plans'] is not True:
qs = qs.filter_by(project_id=context.project_id)
else:
qs = qs.filter_by(project_id=context.project_id)
if 'project_list' in kwargs and 'user_list' in kwargs:
project_list = kwargs['project_list']
user_list = kwargs['user_list']
if isinstance(project_list, list) and isinstance(user_list, list):
if 'exclude' in kwargs and kwargs['exclude'] is True:
qs = qs.filter(models.MigrationPlans.project_id.notin_(
project_list) | models.MigrationPlans.user_id.notin_(user_list))
else:
qs = qs.filter(
models.MigrationPlans.project_id.in_(project_list),
models.MigrationPlans.user_id.in_(user_list))
else:
error = _('Project list and user list should be list')
raise exception.ErrorOccurred(reason=error)
if 'project_list' in kwargs and 'user_list' not in kwargs:
project_list = kwargs['project_list']
qs = model_query(context, models.MigrationPlans.id, **kwargs)
if isinstance(project_list, list):
if 'exclude_project' in kwargs and kwargs['exclude_project'] is True:
qs = qs.filter(
(models.MigrationPlans.project_id.notin_(project_list)))
else:
qs = qs.filter((models.MigrationPlans.project_id.in_(project_list)))
else:
error = _('Project list should be list')
raise exception.ErrorOccurred(reason=error)
if 'migration_plan_list' in kwargs:
migration_plan_list = kwargs['migration_plan_list']
if isinstance(migration_plan_list, list):
if len(migration_plan_list):
if 'exclude_migration_plan' in kwargs and kwargs['exclude_migration_plan'] is True:
qs = qs.filter(and_(models.MigrationPlans.id.notin_(migration_plan_list)))
else:
qs = qs.filter(and_(models.MigrationPlans.id.in_(migration_plan_list)))
else:
error = _('MigrationPlan list should be list')
raise exception.ErrorOccurred(reason=error)
qs = qs.order_by(models.MigrationPlans.created_at.desc())
if 'page_number' in kwargs and kwargs['page_number'] is not None and kwargs['page_number'] != '':
page_size = setting_get(context, 'page_size')
return qs.limit(int(page_size)).offset(
int(page_size) * (int(kwargs['page_number']) - 1)).all()
else:
return qs.all()
@require_context
def migration_get_all(context, migration_plan_id=None, **kwargs):
if not is_admin_context(context):
if migration_plan_id:
return migration_get_all_by_migration_plan(
context, migration_plan_id, **kwargs)
else:
return migration_get_all_by_project(
context, context.project_id, **kwargs)
if migration_plan_id is None:
return model_query(context, models.Migrations, **kwargs). \
options(sa_orm.joinedload(models.Migrations.metadata)). \
order_by(models.Migrations.created_at.desc()).all()
else:
return model_query(context, models.Migrations, **kwargs). \
options(sa_orm.joinedload(models.Migrations.metadata)). \
filter_by(migration_plan_id=migration_plan_id). \
order_by(models.Migrations.created_at.desc()).all()
def migration_get_all_by_migration_plan(context, migration_plan_id, **kwargs):
return model_query(context, models.Migrations, **kwargs). \
options(sa_orm.joinedload(models.Migrations.metadata)). \
filter_by(migration_plan_id=migration_plan_id). \
order_by(models.Migrations.created_at.desc()).all()
def migration_get_all_by_project(context, project_id, **kwargs):
return model_query(context, models.Migrations, **kwargs). \
options(sa_orm.joinedload(models.Migrations.metadata)). \
filter_by(project_id=project_id). \
order_by(models.Migrations.created_at.desc()).all()
@require_context
def migration_plan_get(context, id, **kwargs):
session = get_session()
with session.begin():
return _migration_plan_get(context, id, session, **kwargs)
@require_context
def _migration_plan_get(context, migration_plan_id, session, **kwargs):
try:
migration_plan = model_query(
context, models.MigrationPlans, session=session, **kwargs). \
options(sa_orm.joinedload(models.MigrationPlans.metadata)). \
filter_by(id=migration_plan_id).all()
if not migration_plan:
raise exception.MigrationPlanNotFound(migration_plan_id=migration_plan_id)
return migration_plan[0]
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanNotFound(migration_plan_id=migration_plan_id)
except Exception as ex:
LOG.exception(ex)
raise exception.MigrationPlanNotFound(migration_plan_id=migration_plan_id)
def _set_metadata_for_migration_plan_vms(context, migration_plan_vm_ref, metadata,
purge_metadata, session):
"""
:param context: Request context
:param snapshot_vm_ref: An migration_plan_vm object
:param metadata: A dict of metadata to set
:param session: A SQLAlchemy session to use (if present)
"""
orig_metadata = {}
for metadata_ref in migration_plan_vm_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'migration_plan_vm_id': migration_plan_vm_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vms_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_vms_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vms_metadata_delete(
context, metadata_ref, session=session)
def _migration_plan_vms_metadata_delete(context, metadata_ref, session):
metadata_ref.delete(session=session)
@require_context
def _migration_plan_vm_resource_get(context, id, session):
try:
query = session.query(
models.MigrationPlanVMResources).options(
sa_orm.joinedload(
models.MigrationPlanVMResources.metadata)).filter_by(
id=id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
migration_plan_vm_resource = query.first()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMResourceNotFound(migration_plan_vm_resource_id=id)
return migration_plan_vm_resource
@require_context
def migration_plan_vm_resource_get(context, id):
session = get_session()
return _migration_plan_vm_resource_get(context, id, session)
@require_context
def _migration_plan_vm_resource_update(
context, values, migration_plan_vm_resource_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if migration_plan_vm_resource_id:
migration_plan_vm_resource_ref = _migration_plan_vm_resource_get(
context, snapshot_vm_resource_id, session=session)
else:
migration_plan_vm_resource_ref = models.MigrationPlanVMResources()
if not values.get('size'):
values['size'] = 0
if not values.get('restore_size'):
values['restore_size'] = 0
migration_plan_vm_resource_ref.update(values)
migration_plan_vm_resource_ref.save(session)
_set_metadata_for_migration_plan_vm_resource(
context,
migration_plan_vm_resource_ref,
metadata,
purge_metadata,
session)
return migration_plan_vm_resource_ref
@require_context
def migration_plan_vm_resource_create(context, values):
session = get_session()
return _migration_plan_vm_resource_update(context, values, None, False, session)
@require_context
def migration_plan_vm_resource_delete(context, id):
session = get_session()
with session.begin():
session.query(models.MigrationPlanVMResources). \
filter_by(id=id). \
delete()
@require_context
def migration_plan_vm_resource_update(
context, migration_plan_vm_resource_id, values, purge_metadata=False):
session = get_session()
return _migration_plan_vm_resource_update(
context, values, migration_plan_vm_resource_id, purge_metadata, session)
@require_context
def migration_plan_resources_get(context, migration_plan_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationPlanVMResources).options(
sa_orm.joinedload(
models.MigrationPlanVMResources.metadata)).filter_by(
migration_plan_id=migration_plan_id)
migration_plan_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanResourcesNotFound(migration_plan_id=migration_plan_id)
return migration_plan_resources
@require_context
def migration_plan_get_metadata_cancel_flag(
context, migration_plan_id, return_val=0, process=None, **kwargs):
flag = '0'
migration_plan_obj = migration_plan_get(context, migration_plan_id)
for meta in migration_plan_obj.metadata:
if meta.key == 'cancel_requested':
flag = meta.value
if return_val == 1:
return flag
if flag == '1':
if process:
process.kill()
error = _('Cancel requested for snapshot')
raise exception.ErrorOccurred(reason=error)
@require_context
def _set_metadata_for_migration_plan_vm_resource(
context,
migration_plan_vm_resource_ref,
metadata,
purge_metadata,
session):
orig_metadata = {}
for metadata_ref in migration_plan_vm_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'migration_plan_vm_resource_id': migration_plan_vm_resource_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_vm_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_resource_metadata_delete(
context, metadata_ref, session)
@require_context
def _migration_plan_vm_resource_metadata_create(context, values, session):
"""Create an MigrationPlanVMResourceMetadata object"""
metadata_ref = models.MigrationPlanVMResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_plan_vm_resource_metadata_update(
context, metadata_ref, values, session)
@require_context
def migration_plan_vm_resource_metadata_create(context, values):
session = get_session()
return _migration_plan_vm_resource_metadata_create(context, values, session)
@require_context
def _migration_plan_vm_resource_metadata_update(
context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_plan_vm_resource_metadata_delete(context, metadata_ref, session):
metadata_ref.delete(session=session)
@require_context
def _migration_plan_vm_resource_update(
context, values, migration_plan_vm_resource_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if migration_plan_vm_resource_id:
migration_plan_vm_resource_ref = _migration_plan_vm_resource_get(
context, migration_plan_vm_resource_id, session=session)
else:
migration_plan_vm_resource_ref = models.MigrationPlanVMResources()
if not values.get('size'):
values['size'] = 0
migration_plan_vm_resource_ref.update(values)
migration_plan_vm_resource_ref.save(session)
_set_metadata_for_migration_plan_vm_resource(
context,
migration_plan_vm_resource_ref,
metadata,
purge_metadata,
session)
return migration_plan_vm_resource_ref
@require_context
def migration_plan_vm_resource_create(context, values):
session = get_session()
return _migration_plan_vm_resource_update(context, values, None, False, session)
@require_context
def migration_plan_vm_resource_update(
context, migration_plan_vm_resource_id, values, purge_metadata=False):
session = get_session()
return _migration_plan_vm_resource_update(
context, values, migration_plan_vm_resource_id, purge_metadata, session)
@require_context
def migration_plan_vm_resources_get(context, vm_id, migration_plan_id):
session = get_session()
try:
query = session.query(
models.MigrationPlanVMResources).options(
sa_orm.joinedload(
models.MigrationPlanVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
migration_plan_id=migration_plan_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
migration_plan_vm_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMResourcesNotFound(
migration_plan_vm_id=vm_id, migration_plan_id=migration_plan_id)
return migration_plan_vm_resources
def _migration_plan_set_metadata_for_vm_network_resource(
context,
vm_network_resource_ref,
metadata,
purge_metadata,
session):
orig_metadata = {}
for metadata_ref in vm_network_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'migration_plan_vm_network_resource_id': vm_network_resource_ref.migration_plan_vm_network_resource_id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_network_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_vm_network_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_network_resource_metadata_delete(
context, metadata_ref, session)
def _set_metadata_for_vm_network_resource(
context,
vm_network_resource_ref,
metadata,
purge_metadata,
session):
orig_metadata = {}
for metadata_ref in vm_network_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'migration_plan_vm_network_resource_id': vm_network_resource_ref.vm_network_resource_id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_vm_network_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_vm_network_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_vm_network_resource_metadata_delete(
context, metadata_ref, session)
@require_context
def _migration_plan_vm_network_resource_metadata_create(context, values, session):
"""Create an MigrationPlanVMNetworkResourceMetadata object"""
metadata_ref = models.MigrationPlanVMNetworkResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_plan_vm_network_resource_metadata_update(
context, metadata_ref, values, session)
@require_context
def migration_plan_vm_network_resource_metadata_create(context, values):
"""Create an MigrationPlanVMNetworkResourceMetadata object"""
session = get_session()
return _migration_plan_vm_network_resource_metadata_create(context, values, session)
def _migration_plan_vm_network_resource_metadata_update(
context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_plan_vm_network_resource_metadata_delete(context, metadata_ref, session):
metadata_ref.delete(session=session)
return metadata_ref
def _migration_plan_vm_network_resource_update(
context, migration_plan_vm_network_resource_id, values, purge_metadata, session):
metadata = values.pop('metadata', {})
if migration_plan_vm_network_resource_id:
migration_plan_vm_network_resource_ref = migration_plan_vm_network_resource_get(
context, migration_plan_vm_network_resource_id, session)
else:
migration_plan_vm_network_resource_ref = models.MigrationPlanVMNetworkResource()
migration_plan_vm_network_resource_ref.update(values)
migration_plan_vm_network_resource_ref.save(session)
_migration_plan_set_metadata_for_vm_network_resource(
context,
migration_plan_vm_network_resource_ref,
metadata,
purge_metadata,
session=session)
return migration_plan_vm_network_resource_ref
@require_context
def migration_plan_vm_network_resource_create(context, values):
session = get_session()
return _migration_plan_vm_network_resource_update(
context, None, values, False, session)
@require_context
def migration_plan_vm_network_resource_update(
context, migration_plan_vm_network_resource_id, values, purge_metadata=False):
session = get_session()
return _migration_plan_vm_network_resource_update(
context, values, vm_network_resource_id, purge_metadata, session)
@require_context
def migration_plan_vm_network_resources_get(context, migration_plan_vm_resource_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationPlanVMNetworkResource).options(
sa_orm.joinedload(
models.MigrationPlanVMNetworkResource.metadata)).filter_by(
migration_plan_vm_network_resource_id=migration_plan_vm_resource_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
migration_plan_vm_network_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMNetworkResourceNotFound(
migration_plan_vm_resource_id=migration_plan_vm_resource_id)
return migration_plan_vm_network_resources
@require_context
def migration_plan_vm_network_resource_get(context, vm_network_resource_id):
session = get_session()
try:
query = session.query(
models.MigrationPlanVMNetworkResource).options(
sa_orm.joinedload(
models.MigrationPlanVMNetworkResource.metadata)).filter_by(
migration_plan_vm_network_resource_id=vm_network_resource_id)
migration_plan_vm_network_resource = query.one()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMNetworkResourceNotFound(
migration_plan_vm_network_resource_id=vm_network_resource_id)
return migration_plan_vm_network_resource
@require_context
def migration_plan_vm_network_resource_delete(context, vm_network_resource_id):
session = get_session()
with session.begin():
session.query(models.MigrationPlanVMNetworkResource). \
filter_by(migration_plan_vm_network_resource_id=vm_network_resource_id). \
delete()
def _migration_plan_vm_disk_resource_metadata_update(
context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
def _migration_plan_vm_disk_resource_metadata_delete(context, metadata_ref, session):
metadata_ref.delete(session=session)
@require_context
def _migration_plan_vm_disk_resource_metadata_create(context, values, session):
metadata_ref = models.MigrationPlanVMDiskResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_plan_vm_disk_resource_metadata_update(
context, metadata_ref, values, session)
def _migration_plan_set_metadata_for_vm_disk_resource(
context,
vm_disk_resource_ref,
metadata,
purge_metadata,
session):
orig_metadata = {}
for metadata_ref in vm_disk_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'migration_plan_vm_disk_resource_id': vm_disk_resource_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_disk_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_vm_disk_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_disk_resource_metadata_delete(
context, metadata_ref, session)
def _migration_plan_vm_disk_resource_update(
context, values, vm_disk_resource_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if vm_disk_resource_id:
vm_disk_resource_ref = _migration_plan_vm_disk_resource_get(
context, vm_disk_resource_id, session)
else:
vm_disk_resource_ref = models.MigrationPlanVMDiskResource()
if not values.get('size'):
values['size'] = 0
if not values.get('restore_size'):
values['restore_size'] = 0
vm_disk_resource_ref.update(values)
vm_disk_resource_ref.save(session)
_migration_plan_set_metadata_for_vm_disk_resource(
context,
vm_disk_resource_ref,
metadata,
purge_metadata,
session)
return vm_disk_resource_ref
@require_context
def migration_plan_vm_disk_resource_create(context, values):
session = get_session()
return _migration_plan_vm_disk_resource_update(context, values, None, False, session)
@require_context
def migration_plan_vm_disk_resource_update(
context, vm_disk_resource_id, values, purge_metadata=False):
session = get_session()
return _migration_plan_vm_disk_resource_update(
context, values, vm_disk_resource_id, purge_metadata, session)
@require_context
def migration_plan_vm_disk_resources_get(context, migration_plan_vm_resource_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationPlanVMDiskResource).options(
sa_orm.joinedload(
models.MigrationPlanVMDiskResource.metadata)).filter_by(
migration_plan_vm_resource_id=migration_plan_vm_resource_id)
vm_disk_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.VMDiskResourceNotFound(
migration_plan__vm_resource_id=migration_plan__vm_resource_id)
return vm_disk_resources
@require_context
def _migration_plan_vm_disk_resource_get(context, vm_disk_resource_id, session):
try:
query = session.query(
models.MigrationPlanVMDiskResource).options(
sa_orm.joinedload(
models.MigrationPlanVMDiskResource.metadata)).filter_by(
id=vm_disk_resource_id)
# TODO(gbasava): filter out deleted resource snapshots if context
# disallows it
vm_disk_resource = query.one()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMDiskResourceNotFound(
migration_plan_vm_disk_resource_id=vm_disk_resource_id)
return vm_disk_resource_snap
@require_context
def migration_plan_vm_disk_resource_get(context, vm_disk_resource_id):
session = get_session()
return _migration_plan_vm_disk_resource_get(
context, vm_disk_resource_id, session)
@require_context
def migration_plan_vm_disk_resource_delete(context, vm_disk_resource_id):
session = get_session()
with session.begin():
session.query(models.MigrationPlanVMDiskResource). \
filter_by(id=vm_disk_resource_id). \
delete()
def _migration_plan_set_metadata_for_vm_security_group_rule(
context,
vm_security_group_rule_ref,
metadata,
purge_metadata,
session):
orig_metadata = {}
for metadata_ref in vm_security_group_rule_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'migration_plan_vm_security_group_rule_id': vm_security_group_rule_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_security_group_rule_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_plan_vm_security_group_rule_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_plan_vm_security_group_rule_metadata_delete(
context, metadata_ref, session)
@require_context
def _migration_plan_vm_security_group_rule_metadata_create(context, values, session):
"""Create an VMSecurityGroupRuleSnapMetadata object"""
metadata_ref = models.MigrationPlanVMSecurityGroupRuleMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_plan_vm_security_group_rule_metadata_update(
context, metadata_ref, values, session)
@require_context
def migration_plan_vm_security_group_rule_metadata_create(context, values):
session = get_session()
return _migration_plan_vm_security_group_rule_metadata_create(
context, values, session)
def _migration_plan_vm_security_group_rule_metadata_update(
context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_plan_vm_security_group_rule_metadata_delete(
context, metadata_ref, session):
metadata_ref.delete(session=session)
def _migration_plan_vm_security_group_rule_update(
context,
id,
vm_security_group_id,
values,
purge_metadata,
session):
metadata = values.pop('metadata', {})
if id and vm_security_group_id:
vm_security_group_rule_ref = migration_plan_vm_security_group_rule_get(
context, id, vm_security_group_id, session)
else:
vm_security_group_rule_ref = models.MigrationPlanVMSecurityGroupRule()
vm_security_group_rule_ref.update(values)
vm_security_group_rule_ref.save(session)
_migration_plan_set_metadata_for_vm_security_group_rule(
context, vm_security_group_rule_ref, metadata, purge_metadata, session)
return vm_security_group_rule_ref
@require_context
def migration_plan_vm_security_group_rule_create(context, values):
session = get_session()
return _migration_plan_vm_security_group_rule_update(
context, None, None, values, False, session)
@require_context
def migration_plan_vm_security_group_rule_update(
context, id, vm_security_group_id, values, purge_metadata=False):
session = get_session()
return _migration_plan_vm_security_group_rule_update(
context, id, vm_security_group_id, values, purge_metadata, session)
@require_context
def migration_plan_vm_security_group_rules_get(
context, vm_security_group_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationPlanVMSecurityGroupRule).options(
sa_orm.joinedload(
models.MigrationPlanVMSecurityGroupRule.metadata)).filter_by(
migration_plan_vm_security_group_id=vm_security_group_id)
# TODO(gbasava): filter out deleted snapshots if context disallows it
vm_security_group_rules = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMSecurityGroupRuleNotFound(
migration_plan_vm_security_group_id=vm_security_group_id)
return vm_security_group_rules
@require_context
def migration_plan_vm_security_group_rule_get(context, id, vm_security_group_id):
session = get_session()
try:
query = session.query(
models.MigrationPlanVMSecurityGroupRule).options(
sa_orm.joinedload(
models.MigrationPlanVMSecurityGroupRule.metadata)).filter_by(
id=id).filter_by(
migration_plan_vm_security_group_id=vm_security_group_id)
vm_security_group_rule = query.one()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMSecurityGroupRuleNotFound(
migration_plan_vm_security_group_rule_snap_id=id)
return vm_security_group_rule
@require_context
def migration_plan_vm_security_group_rule_delete(
context, id):
session = get_session()
with session.begin():
session.query(models.MigrationPlanVMSecurityGroupRule). \
filter_by(id=id). \
delete()
@require_context
def _migration_plan_vm_get(context, vm_id, migration_plan_id, session):
try:
query = session.query(
models.MigrationPlanVMs).options(
sa_orm.joinedload(
models.MigrationPlanVMs.metadata)).filter_by(
vm_id=vm_id)
if migration_plan_id is not None:
query = query.filter_by(migration_plan_id=migration_plan_id)
migration_plan_vm = query.first()
except sa_orm.exc.NoResultFound:
raise exception.MigrationPlanVMsNotFound(migration_plan_id=migration_plant_id)
return migration_plan_vm
@require_context
def migration_plan_vm_get(context, vm_id, migration_plan_id):
session = get_session()
return _migration_plan_vm_get(context, vm_id, migration_plan_id, session)
@require_context
def _migration_metadata_create(context, values, session):
metadata_ref = models.MigrationMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_metadata_update(context, metadata_ref, values, session)
@require_context
def migration_metadata_create(context, values, session):
session = get_session()
return _migration_metadata_create(context, values, session)
@require_context
def _migration_metadata_update(context, metadata_ref, values, session):
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_metadata_delete(context, metadata_ref, session):
metadata_ref.delete(session=session)
def _set_metadata_for_migration(context, migration_ref, metadata,
purge_metadata, session):
orig_metadata = {}
for metadata_ref in migration_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'migration_id': migration_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_metadata_delete(
context, metadata_ref, session=session)
def _migration_update(context, values, migration_id, purge_metadata, session):
try:
lock.acquire()
metadata = values.pop('metadata', {})
if not values.get('uploaded_size'):
values['uploaded_size'] = 0
if not values.get('progress_percent'):
values['progress_percent'] = 0
if migration_id:
migration_ref = model_query(
context,
models.Migrations,
session=session,
read_deleted="yes").filter_by(
id=migration_id).first()
if not migration_ref:
lock.release()
raise exception.MigrationNotFound(migration_id=migration_id)
if migration_ref.uploaded_size:
values['uploaded_size'] = migration_ref.uploaded_size
if migration_ref.progress_percent:
values['progress_percent'] = migration_ref.progress_percent
else:
migration_ref = models.Migrations()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not values.get('size'):
values['size'] = 0
if not values.get('progress_percent'):
values['progress_percent'] = 0
migration_ref.update(values)
migration_ref.save(session)
if metadata:
_set_metadata_for_migration(
context,
migration_ref,
metadata,
purge_metadata,
session=session)
return migration_ref
finally:
lock.release()
return migration_ref
@require_context
def migration_create(context, values):
session = get_session()
return _migration_update(context, values, None, False, session)
@require_context
def migration_update(context, migration_id, values, purge_metadata=False):
session = get_session()
return _migration_update(context, values, migration_id,
purge_metadata, session)
@require_context
def _migration_get(context, migration_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
result = model_query(context, models.Migrations, **kwargs). \
options(sa_orm.joinedload(models.Migrations.metadata)). \
filter_by(id=migration_id). \
first()
if not result:
raise exception.MigrationNotFound(migration_id=migration_id)
return result
@require_context
def migration_get(context, migration_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
return _migration_get(context, migration_id, **kwargs)
@require_context
def migration_vms_get(context, migration_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationVMs).options(
sa_orm.joinedload(
models.MigrationVMs.metadata)).filter_by(
migration_id=migration_id)
migration_vms = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMsNotFound(migration_id=migration_id)
return migration_vms
@require_context
def migration_get_all_by_project_migration_plan(
context, project_id, migration_plan_id, **kwargs):
if kwargs.get('session') is None:
kwargs['session'] = get_session()
authorize_project_context(context, project_id)
return model_query(context, models.Migrations, **kwargs). \
options(sa_orm.joinedload(models.Migrations.metadata)). \
filter_by(project_id=project_id). \
filter_by(migration_plan_id=migration_plan_id). \
order_by(models.Migrations.created_at.desc()).all()
@require_context
def migration_get_metadata_cancel_flag(
context, migration_id, return_val=0, process=None, **kwargs):
flag = '0'
migration_obj = migration_get(context, migration_id)
for meta in migration_obj.metadata:
if meta.key == 'cancel_requested':
flag = meta.value
if return_val == 1:
return flag
if flag == '1':
if process:
process.kill()
error = _('Cancel requested for migration')
raise exception.ErrorOccurred(reason=error)
@require_context
def migration_delete(context, migration_id):
session = get_session()
with session.begin():
session.query(models.Migrations). \
filter_by(id=migration_id).delete()
def _set_metadata_for_migration_vms(context, migration_vm_ref, metadata,
purge_metadata, session):
orig_metadata = {}
for metadata_ref in migration_vm_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'migrated_vm_id': migration_vm_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_vms_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_vms_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
_migration_vms_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _migration_vms_metadata_create(context, values, session):
"""Create an MigrationMetadata object"""
metadata_ref = models.MigrationVMMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_vms_metadata_update(
context, metadata_ref, values, session)
@require_context
def migration_vms_metadata_create(context, values, session):
"""Create an MigrationMetadata object"""
session = get_session()
return _migration_vms_metadata_create(context, values, session)
@require_context
def _migration_vms_metadata_update(context, metadata_ref, values, session):
"""
Used internally by migration_vms_metadata_create and migration_vms_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _migration_vms_metadata_delete(context, metadata_ref, session):
"""
Used internally by migration_vms_metadata_create and migration_vms_metadata_update
"""
metadata_ref.delete(session=session)
def _migration_vm_update(context, values, vm_id,
migration_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if vm_id:
migration_vm_ref = _migration_vm_get(context, vm_id, migration_id, session)
else:
migration_vm_ref = models.MigrationVMs()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
if not values.get('size'):
values['size'] = 0
migration_vm_ref.update(values)
migration_vm_ref.save(session)
if metadata:
_set_metadata_for_migration_vms(
context,
migration_vm_ref,
metadata,
purge_metadata,
session=session)
return migration_vm_ref
@require_context
def migration_vm_create(context, values):
session = get_session()
return _migration_vm_update(context, values, None, None, False, session)
@require_context
def migration_vm_update(context, vm_id, migration_id,
values, purge_metadata=False):
session = get_session()
return _migration_vm_update(
context, values, vm_id, migration_id, purge_metadata, session)
@require_context
def migration_vms_get(context, migration_id, **kwargs):
session = kwargs.get('session') or get_session()
try:
query = session.query(
models.MigrationVMs).options(
sa_orm.joinedload(
models.MigrationVMs.metadata)).filter_by(
migration_id=migration_id)
migration_vms = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMsNotFound(migration_id=migration_id)
return migration_vms
@require_context
def _migration_vm_get(context, vm_id, migration_id, session):
try:
query = session.query(
models.MigrationVMs).options(
sa_orm.joinedload(
models.MigrationVMs.metadata)).filter_by(
vm_id=vm_id).filter_by(
migration_id=migration_id)
migration_vm = query.first()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMsNotFound(migration_id=migration_id)
return migration_vm
@require_context
def migration_vm_get(context, vm_id, migration_id):
session = get_session()
return _migration_vm_get(context, vm_id, migration_id, session)
@require_context
def migration_vm_delete(context, vm_id, migration_id):
session = get_session()
with session.begin():
session.query(models.MigrationVMs). \
filter_by(vm_id=vm_id). \
filter_by(migration_id=migration_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
def _set_metadata_for_migration_vm_resource(
context,
migration_vm_resource_ref,
metadata,
purge_metadata,
session):
orig_metadata = {}
for metadata_ref in migration_vm_resource_ref.metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {
'migration_vm_resource_id': migration_vm_resource_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_migration_vm_resource_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_migration_vm_resource_metadata_create(
context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
migration_vm_resource_metadata_delete(
context, metadata_ref, session=session)
@require_context
def _migration_vm_resource_metadata_create(context, values, session):
metadata_ref = models.MigrationVMResourceMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _migration_vm_resource_metadata_update(
context, metadata_ref, values, session)
@require_context
def migration_vm_resource_metadata_create(context, values):
session = get_session()
return _migration_vm_resource_metadata_create(context, values, session)
def _migration_vm_resource_metadata_update(
context, metadata_ref, values, session):
"""
Used internally by migration_vm_resource_metadata_create and migration_vm_resource_metadata_update
"""
values["deleted"] = False
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def migration_vm_resource_metadata_delete(context, metadata_ref):
"""
Used internally by migration_vm_resource_metadata_create and migration_vm_resource_metadata_update
"""
session = get_session()
metadata_ref.delete(session=session)
return metadata_ref
def _migration_vm_resource_update(
context, values, migration_vm_resource_id, purge_metadata, session):
metadata = values.pop('metadata', {})
if migration_vm_resource_id:
migration_vm_resource_ref = migration_vm_resource_get(
context, migration_vm_resource_id, session)
else:
migration_vm_resource_ref = models.MigrationVMResources()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
migration_vm_resource_ref.update(values)
migration_vm_resource_ref.save(session)
_set_metadata_for_migration_vm_resource(
context,
migration_vm_resource_ref,
metadata,
purge_metadata,
session)
return migration_vm_resource_ref
@require_context
def migration_vm_resource_create(context, values):
session = get_session()
return _migration_vm_resource_update(context, values, None, False, session)
@require_context
def migration_vm_resource_update(
context, migration_vm_resource_id, values, purge_metadata=False):
session = get_session()
return _migration_vm_resource_update(
context, values, migration_vm_resource_id, purge_metadata, session)
@require_context
def migration_vm_resources_get(context, vm_id, migration_id):
session = get_session()
try:
query = session.query(
models.MigrationVMResources).options(
sa_orm.joinedload(
models.MigrationVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
migration_id=migration_id)
migrationd_vm_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMResourcesNotFound(
migration_vm_id=vm_id, migration_id=migration_id)
return migration_vm_resources
@require_context
def migration_vm_resource_get_by_resource_name(
context, vm_id, migration_id, resource_name):
session = get_session()
try:
query = session.query(
models.MigrationVMResources).options(
sa_orm.joinedload(
models.MigrationVMResources.metadata)).filter_by(
vm_id=vm_id).filter_by(
migration_id=migration_id).filter_by(
resource_name=resource_name)
migration_vm_resources = query.first()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMResourceWithNameNotFound(
resource_name=resource_name, migration_vm_id=vm_id, migration_id=migration_id)
return migration_vm_resources
@require_context
def migration_vm_resource_get(context, id):
session = get_session()
try:
query = session.query(
models.MigrationVMResources).options(
sa_orm.joinedload(
models.MigrationVMResources.metadata)).filter_by(
id=id)
migration_vm_resources = query.first()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMResourceWithIdNotFound(id=id)
return migration_vm_resources
@require_context
def migration_vm_resource_delete(context, id, vm_id, migration_id):
session = get_session()
with session.begin():
session.query(models.MigrationVMResources). \
filter_by(id=id). \
filter_by(vm_id=vm_id). \
filter_by(migration_id=migration_id). \
update({'status': 'deleted',
'deleted': True,
'deleted_at': timeutils.utcnow(),
'updated_at': literal_column('updated_at')})
@require_context
def migration_vm_resources_get_all(context, migration_id, **kwargs):
session = get_session()
try:
query = session.query(
models.MigrationVMResources).options(
sa_orm.joinedload(
models.MigrationVMResources.metadata)).filter_by(
migration_id=migration_id)
if kwargs.get('resource_type'):
query = query.filter_by(resource_type=kwargs['resource_type'])
migrated_vm_resources = query.all()
except sa_orm.exc.NoResultFound:
raise exception.MigrationVMResourcesNotFound(migration_id=migration_id)
return migrated_vm_resources
@require_context
def migration_type_time_size_update(context, migration_id):
migration = migration_get(context, migration_id)
migration_vm_resources = migration_vm_resources_get_all(context, migration_id, resource_type='disk')
migration_size = 0
for migration_vm_resource in migration_vm_resources:
if migration_vm_resource.status != 'deleted':
migration_size += migration_vm_resource.size
return migration_update(
context,
migration_id,
{
'time_taken': int((timeutils.utcnow() - migration.created_at).total_seconds()),
'uploaded_size': migration_size,
})
@require_admin_context
def unlock_migration_plans_for_host(context, host):
session = get_session()
migration_plans_query = model_query(context, models.MigrationPlans, session=session)
migration_plans_query = migration_plans_query.filter(and_(
models.MigrationPlans.status != 'available',
models.MigrationPlans.status != 'error',
models.MigrationPlans.host == host)
)
locked_migration_plans = migration_plans_query.all()
for mig_plan in locked_migration_plans:
values = {'status': 'available'}
mig_plan.update(values)
session.add(mig_plan)
session.flush()
session.close()
@require_admin_context
def migration_plans_mark_deleting_as_error(context, host):
session = get_session()
migration_plans_query = model_query(context, models.MigrationPlans, session=session)
migration_plans_query = migration_plans_query.filter(and_(
models.MigrationPlans.status == 'deleting',
models.MigrationPlans.host == host)
)
deleting_migration_plans = migration_plans_query.all()
for mig_plan in deleting_migration_plans:
values = {'status': 'error'}
mig_plan.update(values)
session.add(wrklod)
session.flush()
session.close()
@require_admin_context
def migration_mark_incomplete_as_error(context, host):
"""
mark the migrations that are left hanging from previous run on host as 'error'
"""
session = get_session()
now = timeutils.utcnow()
migrations_query = model_query(context, models.Migrations, session=session)
migrations_query = migrations_query.filter(and_(
models.Migrations.status != 'available',
models.Migrations.status != 'error',
models.Migrations.status != 'mounted',
models.Migrations.status != 'cancelled'))
migrations_query = migrations_query.filter(or_(
models.Migrations.host == host,
models.Migrations.host == ''))
migrations = migrations_query.all()
for migration in migrations:
if (migration.host == '' and
now - migration.created_at <= timedelta(minutes=60)):
continue
if migration.status == 'migrating':
values = {'status': 'available'}
else:
values = {'progress_percent': 100, 'progress_msg': '',
'error_msg': 'Migration did not finish successfully',
'status': 'error'}
migration.update(values)
session.add(migration)
session.flush()
session.close()
""" Backup target APIs """
def _backup_target_get(context, backup_target_id, session):
try:
backup_target_ref = model_query(
context, models.BackupTargets, session=session). \
filter_by(id=backup_target_id).first()
if not backup_target_ref:
raise exception.BackupTargetNotFound(backup_target_id=backup_target_id)
return backup_target_ref
except sa_orm.exc.NoResultFound:
raise exception.BackupTargetNotFound(backup_target_id=backup_target_id)
except Exception as ex:
LOG.exception(ex)
raise exception.BackupTargetNotFound(backup_target_id=backup_target_id)
def _backup_target_update(context, backup_target_id, values, session):
if backup_target_id:
bt_ref = _backup_target_get(context, backup_target_id, session)
else:
bt_ref = models.BackupTargets()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
bt_ref.update(values)
bt_ref.save(session)
return bt_ref
@require_context
def backup_target_create(context, values):
btt_name = values.pop('backup_target_type_name', None)
session = get_session()
bt_ref =_backup_target_update(context, None, values, session)
values.update({'backup_targets_id': bt_ref.id, 'id': None})
backup_target_metadata_create(context, values, session)
backup_target_type_create(context, bt_ref.id, values={'name': btt_name or bt_ref.filesystem_export, 'user_id': context.user_id, 'is_default': bt_ref.is_default}, project_list=[])
return bt_ref
@require_context
def backup_target_update(context, backup_target_id, values):
session = get_session()
return _backup_target_update(context, backup_target_id, values, session)
@require_context
def backup_target_delete(context, backup_target_id):
session = get_session()
session.query(models.BackupTargets). \
filter_by(id=backup_target_id).delete()
@require_context
def backup_target_show(context, backup_target_id):
session = get_session()
try:
bt_ref = model_query(
context, models.BackupTargets, session=session). \
options(sa_orm.joinedload(models.BackupTargets.backup_target_types)). \
filter_by(id=backup_target_id).first()
if not bt_ref:
raise exception.BackupTargetNotFound(backup_target_id=backup_target_id)
return bt_ref
except sa_orm.exc.NoResultFound:
raise exception.BackupTargetNotFound(backup_target_id=backup_target_id)
except Exception as ex:
LOG.exception(ex)
raise exception.BackupTargetNotFound(backup_target_id=backup_target_id)
@require_context
def get_backup_target_by_backend_endpoint(context, backend_endpoint):
session = get_session()
try:
bt_ref = model_query(
context, models.BackupTargets, session=session). \
options(sa_orm.joinedload(models.BackupTargets.backup_target_types)). \
filter_by(filesystem_export=backend_endpoint).first()
if not bt_ref:
raise exception.BackupTargetNotFound(backup_target_id=backend_endpoint)
return bt_ref
except sa_orm.exc.NoResultFound:
raise exception.BackupTargetNotFound(backup_target_id=backend_endpoint)
except Exception as ex:
LOG.exception(ex)
raise exception.BackupTargetNotFound(backup_target_id=backend_endpoint)
@require_context
def backup_target_get_all(context):
session = get_session()
#return session.query(models.BackupTargets).all()
return model_query(context, models.BackupTargets). \
options(sa_orm.joinedload(models.BackupTargets.backup_target_types)). \
order_by(models.BackupTargets.created_at.desc()).all()
@require_context
def get_backup_target_by_btt(context, backup_target_type):
session = get_session()
try:
uuid.UUID(str(backup_target_type))
bt_ref = session.query(models.BackupTargets).join(models.BackupTargetTypes).filter(models.BackupTargetTypes.id == backup_target_type).first()
except ValueError:
bt_ref = session.query(models.BackupTargets).join(models.BackupTargetTypes).filter(models.BackupTargetTypes.name == backup_target_type).first()
return bt_ref
@require_context
def _backup_target_metadata_update(context, metadata_ref, values, session):
"""
Used internally by backup_target_metadata_create and backup_target_metadata_update
"""
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
@require_context
def _backup_target_metadata_create(context, values, session):
"""Create an BackupTargetMetadata object"""
metadata_ref = models.BackupTargetsMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
values['key']='immutable'
values['value']=values.get('immutable', 0)
return _backup_target_type_metadata_update(context, metadata_ref, values, session)
@require_context
def backup_target_metadata_create(context, values, session):
"""Create an BackupTargetMetadata object"""
session = get_session()
return _backup_target_metadata_create(context, values, session)
""" BTT metadata """
@require_context
def _backup_target_type_metadata_create(context, values, session):
"""Create an BackupTargetTypeMetadata object"""
metadata_ref = models.BackupTargetTypeMetadata()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _backup_target_type_metadata_update(context, metadata_ref, values, session)
@require_context
def backup_target_type_metadata_create(context, values, session):
"""Create an BackupTargetTypeMetadata object"""
session = get_session()
return _backup_target_type_metadata_create(context, values, session)
@require_context
def _backup_target_type_metadata_update(context, metadata_ref, values, session):
"""
Used internally by backup_target_type_metadata_create and backup_target_type_metadata_update
"""
metadata_ref.update(values)
metadata_ref.save(session=session)
return metadata_ref
def _set_metadata_for_backup_target_type(context, btt_ref, metadata, purge_metadata, session):
orig_metadata = {}
for metadata_ref in btt_ref.backup_target_type_metadata:
orig_metadata[metadata_ref.key] = metadata_ref
for key, value in metadata.items():
metadata_values = {'backup_target_type_id': btt_ref.id,
'key': key,
'value': value}
if key in orig_metadata:
metadata_ref = orig_metadata[key]
_backup_target_type_metadata_update(
context, metadata_ref, metadata_values, session)
else:
_backup_target_type_metadata_create(context, metadata_values, session)
if purge_metadata:
for key in list(orig_metadata.keys()):
if key not in metadata:
metadata_ref = orig_metadata[key]
session.query(models.BackupTargetTypeMetadata). \
filter_by(id=metadata_ref.id).delete()
""" BTT projects """
@require_context
def _backup_target_type_project_create(context, values, session):
"""Create an BackupTargetTypeProjects object"""
project_ref = models.BackupTargetTypeProjects()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
return _backup_target_type_project_update(context, project_ref, values, session)
@require_context
def backup_target_type_project_create(context, values, session):
"""Create an BackupTargetTypeProjects object"""
session = get_session()
return _backup_target_type_project_create(context, values, session)
@require_context
def _backup_target_type_project_update(context, project_ref, values, session):
"""
Used internally by backup_target_type_project_create and backup_target_type_project_update
"""
project_ref.update(values)
project_ref.save(session=session)
return project_ref
def _set_projects_for_backup_target_type(context, btt_ref, project_list, purge_projects, session):
orig_projects = {}
for btt_project_ref in btt_ref.backup_target_type_projects:
orig_projects[btt_project_ref.project_id] = btt_project_ref
for project_id in project_list:
project_values = {'backup_target_types_id': btt_ref.id,
'project_id': project_id,
}
if project_id not in orig_projects:
_backup_target_type_project_create(context, project_values, session)
if purge_projects:
for key in list(orig_projects.keys()):
if key not in project_list:
project_ref = orig_projects[key]
session.query(models.BackupTargetTypeProjects). \
filter_by(id=project_ref.id).delete()
@require_context
def backup_target_type_remove_projects(context, backup_target_type_id):
session = get_session()
session.query(models.BackupTargetTypeProjects). \
filter_by(backup_target_types_id=backup_target_type_id).delete()
""" BTT APIs """
def _backup_target_type_get(context, backup_target_type_id, session):
try:
backup_target_type_ref = model_query(
context, models.BackupTargetTypes, session=session). \
filter_by(id=backup_target_type_id).first()
if not backup_target_type_ref:
raise exception.BackupTargetTypeNotFound(backup_target_type_id=backup_target_type_id)
return backup_target_type_ref
except sa_orm.exc.NoResultFound:
raise exception.BackupTargetTypeNotFound(backup_target_type_id=backup_target_type_id)
except Exception as ex:
LOG.exception(ex)
raise exception.BackupTargetTypeNotFound(backup_target_type_id=backup_target_type_id)
def backup_target_type_get_by_name(context, backup_target_type_name, session):
try:
backup_target_type_ref = model_query(
context, models.BackupTargetTypes, session=session). \
filter_by(name=backup_target_type_name).first()
if not backup_target_type_ref:
raise exception.BackupTargetTypeByNameNotFound(backup_target_type_name=backup_target_type_name)
return backup_target_type_ref
except sa_orm.exc.NoResultFound:
raise exception.BackupTargetTypeByNameNotFound(backup_target_type_name=backup_target_type_name)
except Exception as ex:
LOG.exception(ex)
raise exception.BackupTargetTypeByNameNotFound(backup_target_type_name=backup_target_type_name)
def _backup_target_type_update(context, backup_target_id, backup_target_type_id, values, project_list, purge_metadata, purge_projects, session):
metadata = values.pop('metadata', {})
new_btt_flag = False
btt_remove_projects = False
if backup_target_type_id:
btt_ref = _backup_target_type_get(context, backup_target_type_id, session)
# user not allowed to change BT of BTT
if values.get('backup_targets_id') and values['backup_targets_id'] != btt_ref.backup_targets_id:
raise exception.BackupTargetTypeUpdateNotAllowed(backup_target_type_id=backup_target_type_id)
# user not allowed to change default BTT
if btt_ref.is_default:
raise exception.BackupTargetTypeDefaultUpdateNotAllowed(backup_target_type_id=backup_target_type_id)
# when user wishes to change private BTT to public then remove all it's assigned projects and make it public
if values.get('is_public') and btt_ref.is_public != values['is_public']:
btt_remove_projects = True
# when user passess project list then make BTT as private
if values.get('project_list'):
values['is_public'] = 0
else:
new_btt_flag = True
btt_ref = models.BackupTargetTypes()
if not values.get('id'):
values['id'] = str(uuid.uuid4())
values['backup_targets_id'] = backup_target_id
btt_ref.update(values)
btt_ref.save(session)
if btt_remove_projects:
backup_target_type_remove_projects(context, btt_ref.id)
try:
if metadata:
_set_metadata_for_backup_target_type(
context,
btt_ref,
metadata,
purge_metadata,
session=session)
if project_list:
_set_projects_for_backup_target_type(
context,
btt_ref,
project_list,
purge_projects,
session=session)
except Exception as ex:
if new_btt_flag:
backup_target_type_delete(context, btt_ref.id)
raise ex
return btt_ref
@require_context
def backup_target_type_create(context, backup_target_id, values, project_list=[], purge_metadata=False, purge_projects=False):
session = get_session()
backup_target_type_ref = model_query(
context, models.BackupTargetTypes, session=session). \
filter_by(name=values.get('name')).first()
if backup_target_type_ref:
raise exception.BackupTargetTypeNameDuplicateNotAllowed(backup_target_type_name=values.get('name'))
if not values.get('user_id'):
values['user_id'] = context.user_id
return _backup_target_type_update(context, backup_target_id, None, values, project_list, purge_metadata, purge_projects, session)
@require_context
def backup_target_type_update(context, backup_target_type_id, values, project_list=[], purge_metadata=False, purge_projects=False):
session = get_session()
return _backup_target_type_update(context, None, backup_target_type_id, values, project_list, purge_metadata, purge_projects, session)
@require_context
def backup_target_type_add_projects(context, backup_target_type_id, project_list=[]):
session = get_session()
btt_ref = _backup_target_type_get(context, backup_target_type_id, session)
_set_projects_for_backup_target_type(
context,
btt_ref,
project_list,
purge_projects=False,
session=session)
return _backup_target_type_get(context, backup_target_type_id, session)
@require_context
def backup_target_type_remove_projects_api(context, backup_target_type_id, project_list=[]):
session = get_session()
for project_id in project_list:
session.query(models.BackupTargetTypeProjects). \
filter_by(backup_target_types_id=backup_target_type_id, project_id=project_id).delete()
@require_context
def backup_target_type_add_metadata(context, backup_target_type_id, metadata={}):
session = get_session()
btt_ref = _backup_target_type_get(context, backup_target_type_id, session)
_set_metadata_for_backup_target_type(
context,
btt_ref,
metadata,
purge_metadata=False,
session=session)
return _backup_target_type_get(context, backup_target_type_id, session)
@require_context
def backup_target_type_remove_metadata(context, backup_target_type_id, metadata=[]):
session = get_session()
for metadata_key in metadata:
session.query(models.BackupTargetTypeMetadata). \
filter_by(backup_target_type_id=backup_target_type_id, key=metadata_key).delete()
@require_context
def backup_target_type_show(context, backup_target_type_id):
session = get_session()
try:
try:
uuid.UUID(backup_target_type_id)
btt_ref = model_query(
context, models.BackupTargetTypes, session=session). \
options(sa_orm.joinedload(models.BackupTargetTypes.backup_target_type_metadata)). \
options(sa_orm.joinedload(models.BackupTargetTypes.backup_target_type_projects)). \
filter_by(id=backup_target_type_id).first()
except ValueError:
# if user provides name then get BTT data by name
btt_ref = model_query(
context, models.BackupTargetTypes, session=session). \
options(sa_orm.joinedload(models.BackupTargetTypes.backup_target_type_metadata)). \
options(sa_orm.joinedload(models.BackupTargetTypes.backup_target_type_projects)). \
filter_by(name=backup_target_type_id).first()
if not btt_ref:
raise exception.BackupTargetTypeNotFound(backup_target_type_id=backup_target_type_id)
return btt_ref
except sa_orm.exc.NoResultFound:
raise exception.BackupTargetTypeNotFound(backup_target_type_id=backup_target_type_id)
except Exception as ex:
LOG.exception(ex)
raise exception.BackupTargetTypeNotFound(backup_target_type_id=backup_target_type_id)
@require_context
def backup_target_type_get_all(context, **kwargs):
session = get_session()
return session.query(models.BackupTargetTypes).all()
@require_context
def backup_target_type_get_all_public_and_by_project_id(context, project_id=None, **kwargs):
session = get_session()
btt_public = session.query(models.BackupTargetTypes).filter_by(is_public=1).order_by(models.BackupTargetTypes.is_default.desc()).all()
btt_private = session.query(models.BackupTargetTypes).join(models.BackupTargetTypeProjects).filter(and_(models.BackupTargetTypes.is_public == 0, models.BackupTargetTypeProjects.project_id == project_id)).all()
btt_ref = list(set(btt_public + btt_private))
return btt_ref
@require_context
def backup_target_type_get_all_by_backup_target(context, backup_target_id, **kwargs):
session = get_session()
return session.query(models.BackupTargetTypes).filter_by(backup_targets_id=backup_target_id).all()
@require_context
def backup_target_type_delete(context, backup_target_type_id):
session = get_session()
btt_ref = _backup_target_type_get(context, backup_target_type_id, session)
if btt_ref.is_default:
raise exception.BackupTargetTypeDefaultDeleteNotAllowed(backup_target_type_id=backup_target_type_id)
session.query(models.BackupTargetTypes). \
filter_by(id=backup_target_type_id).delete()
def set_all_backup_target_type_to_non_default(context, backup_target_id):
session = get_session()
session.query(models.BackupTargetTypes).filter_by(backup_targets_id=backup_target_id).update({'is_default': 0})
def get_default_backup_target_type(context):
session = get_session()
return session.query(models.BackupTargetTypes).filter_by(is_default=1).all()
""" Get importable workloads list APIs """
def _importable_workload_get(context, job_data_id, session):
try:
job_data_ref = model_query(
context, models.JobDetails, session=session). \
filter_by(id=job_data_id).first()
return job_data_ref
except sa_orm.exc.NoResultFound:
raise exception.JobDataNotFound(job_data_id=job_data_id)
except Exception as ex:
LOG.exception(ex)
raise exception.JobdataNotFound(job_data_id=job_data_id)
@require_context
def importable_workloads_create(context, jobid, values):
session = get_session()
job_data_ref = models.JobDetails()
job_data_ref.update({'jobid': jobid, 'data': json.dumps(values)})
job_data_ref.save(session)
return job_data_ref
@require_context
def importable_workloads_update(context, job_data_id, values):
session = get_session()
job_data_ref = model_query(
context, models.JobDetails, session=session).filter_by(id=job_data_id).first()
if not job_data_ref:
raise exception.JobDataNotFound(job_data_id=job_data_id)
db_values = dict(json.loads(job_data_ref.data))
db_values.update(values)
job_data_ref.update({'jobid': job_data_ref.jobid, 'data':json.dumps(db_values)})
job_data_ref.save(session)
return job_data_ref
@require_context
def importable_workload_get(context, job_data_id):
session = get_session()
job_data_ref = model_query(
context, models.JobDetails, session=session).filter_by(id=job_data_id).first()
if not job_data_ref:
raise exception.JobDataNotFound(job_data_id=job_data_id)
return job_data_ref
@require_context
def importable_workloads_get_all(context, **kwargs):
session = get_session()
if kwargs.get('jobid'):
response = session.query(models.JobDetails).filter_by(jobid=kwargs['jobid']).order_by(asc(models.JobDetails.created_at)).all()
else:
response = session.query(models.JobDetails).order_by(asc(models.JobDetails.created_at)).all()
if kwargs.get('workload_id'):
response = [resp for resp in response if json.loads(resp.data)['workload_id'] == kwargs['workload_id']]
if kwargs.get('status'):
response = [resp for resp in response if json.loads(resp.data)['status'] == kwargs['status']]
if kwargs.get('backup_target'):
response = [resp for resp in response if json.loads(resp.data)['backup_target'] == kwargs['backup_target']]
return response
@require_context
def workload_delete_all(context, **kwargs):
deleted_workload_list = []
qs_wl = model_query(context, models.Workloads)
if kwargs.get('workload_ids', None):
qs_wl = qs_wl.filter(
models.Workloads.id.in_(kwargs['workload_ids']))
if kwargs.get('project_list', None):
qs_wl = qs_wl.filter(
models.Workloads.project_id.in_(kwargs['project_list']))
if kwargs.get('user_list', None):
qs_wl = qs_wl.filter(
models.Workloads.user_id.in_(kwargs['user_list']))
if kwargs.get('workload_ids', None) or kwargs.get('all_workloads', None):
deleted_workload_list = qs_wl.all()
qs_wl.delete(synchronize_session=False)
return deleted_workload_list
@require_context
def policy_delete_all(context, **kwargs):
deleted_policy_list = []
qs_policy = model_query(context, models.WorkloadPolicy)
if kwargs.get('policy_ids', None):
qs_policy = qs_policy.filter(
models.WorkloadPolicy.id.in_(kwargs['policy_ids']))
if kwargs.get('project_list'):
qs_policy = qs_policy.filter(
models.WorkloadPolicy.project_id.in_(kwargs['project_list']))
if kwargs.get('user_list', None):
qs_policy = qs_policy.filter(
models.WorkloadPolicy.user_id.in_(kwargs['user_list']))
if kwargs.get('policy_ids', None) or kwargs.get('all_policies', None):
deleted_policy_list = qs_policy.all()
for policy in deleted_policy_list:
# removing the policy assignments before deletion
model_query(context, models.WorkloadPolicyAssignmnets).filter_by(policy_id=policy.id).delete()
qs_policy.delete(synchronize_session=False)
return deleted_policy_list
@require_context
def abandon_resources(context, **kwargs):
deleted_workload_list = workload_delete_all(context, **kwargs)
deleted_policy_list = policy_delete_all(context, **kwargs)
return {'abandon_workload_list': deleted_workload_list, 'abandon_policy_list': deleted_policy_list}