daisycloud-core/code/daisy/daisy/api/v1/roles.py

949 lines
40 KiB
Python

# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
/roles endpoint for Daisy v1 API
"""
from oslo_log import log as logging
from webob.exc import HTTPBadRequest
from webob.exc import HTTPConflict
from webob.exc import HTTPForbidden
from webob.exc import HTTPNotFound
from webob import Response
from daisy.api.backends import driver
import ConfigParser
import daisy.api.backends.common as daisy_cmn
from daisy.api import policy
import daisy.api.v1
from daisy.api.v1 import controller
from daisy.api.v1 import filters
from daisy.common import exception
from daisy.common import utils
from daisy.common import wsgi
from daisy import i18n
from daisy import notifier
import daisy.registry.client.v1.api as registry
LOG = logging.getLogger(__name__)
_ = i18n._
_LE = i18n._LE
_LI = i18n._LI
_LW = i18n._LW
SUPPORTED_PARAMS = daisy.api.v1.SUPPORTED_PARAMS
SUPPORTED_FILTERS = daisy.api.v1.SUPPORTED_FILTERS
ACTIVE_IMMUTABLE = daisy.api.v1.ACTIVE_IMMUTABLE
SUPPORTED_DEPLOYMENT_BACKENDS = ('tecs', 'zenic', 'proton', 'kolla')
SUPPORTED_ROLE = (
'CONTROLLER_LB',
'CONTROLLER_HA',
'COMPUTER',
'ZENIC_CTL',
'ZENIC_NFM',
'ZENIC_MDB',
'PROTON',
'CHILD_CELL_1_COMPUTER',
'CONTROLLER_CHILD_CELL_1')
SUPPORT_DISK_LOCATION = ('local', 'share')
def get_backend():
config = ConfigParser.ConfigParser()
config.read(daisy_cmn.daisy_conf_file)
backend = config.get("BACKEND", "default_backend_types")
backend = backend.split(",")
return backend
class Controller(controller.BaseController):
"""
WSGI controller for roles resource in Daisy v1 API
The roles resource API is a RESTful web role for role data. The API
is as follows::
GET /roles -- Returns a set of brief metadata about roles
GET /roles/detail -- Returns a set of detailed metadata about
roles
HEAD /roles/<ID> -- Return metadata about an role with id <ID>
GET /roles/<ID> -- Return role data for role with id <ID>
POST /roles -- Store role data and return metadata about the
newly-stored role
PUT /roles/<ID> -- Update role metadata and/or upload role
data for a previously-reserved role
DELETE /roles/<ID> -- Delete the role with id <ID>
"""
def __init__(self):
self.notifier = notifier.Notifier()
registry.configure_registry_client()
self.policy = policy.Enforcer()
def _enforce(self, req, action, target=None):
"""Authorize an action against our policies"""
if target is None:
target = {}
try:
self.policy.enforce(req.context, action, target)
except exception.Forbidden:
raise HTTPForbidden()
def _get_filters(self, req):
"""
Return a dictionary of query param filters from the request
:param req: the Request object coming from the wsgi layer
:retval a dict of key/value filters
"""
query_filters = {}
for param in req.params:
if param in SUPPORTED_FILTERS:
query_filters[param] = req.params.get(param)
if not filters.validate(param, query_filters[param]):
raise HTTPBadRequest(_('Bad value passed to filter '
'%(filter)s got %(val)s')
% {'filter': param,
'val': query_filters[param]})
return query_filters
def _get_query_params(self, req):
"""
Extracts necessary query params from request.
:param req: the WSGI Request object
:retval dict of parameters that can be used by registry client
"""
params = {'filters': self._get_filters(req)}
for PARAM in SUPPORTED_PARAMS:
if PARAM in req.params:
params[PARAM] = req.params.get(PARAM)
return params
def _raise_404_if_host_deleted(self, req, host_id):
host = self.get_host_meta_or_404(req, host_id)
if host['deleted']:
msg = _("Node with identifier %s has been deleted.") % host_id
raise HTTPNotFound(msg)
def _raise_404_if_service_deleted(self, req, service_id):
service = self.get_service_meta_or_404(req, service_id)
if service['deleted']:
msg = _("Service with identifier %s has been deleted.") % \
service_id
raise HTTPNotFound(msg)
def _raise_404_if_config_set_deleted(self, req, config_set_id):
config_set = self.get_config_set_meta_or_404(req, config_set_id)
if config_set['deleted']:
msg = _("Config_Set with identifier %s has been deleted.") % \
config_set_id
raise HTTPNotFound(msg)
def _raise_404_if_cluster_deleted(self, req, cluster_id):
cluster = self.get_cluster_meta_or_404(req, cluster_id)
if cluster['deleted']:
msg = _("cluster with identifier %s has been deleted.") % \
cluster_id
raise HTTPNotFound(msg)
def _get_service_name_list(self, req, role_service_id_list):
service_name_list = []
for service_id in role_service_id_list:
service_meta = registry.get_service_metadata(
req.context, service_id)
service_name_list.append(service_meta['name'])
return service_name_list
def _get_host_disk_except_os_disk_by_info(self, host_info):
'''
type(host_info): <type 'dict'>
host_disk_except_os_disk_lists: disk_size , type = int
'''
# import pdb;pdb.set_trace()
host_disk_except_os_disk_lists = 0
os_disk_m = host_info.get('root_lv_size', 102400)
swap_size_m = host_info.get('swap_lv_size', None)
if swap_size_m:
swap_size_m = (swap_size_m / 4) * 4
else:
swap_size_m = 0
boot_partition_m = 400
redundant_partiton_m = 600
if not os_disk_m:
os_disk_m = 102400
# host_disk = 1024
host_disks = host_info.get('disks', None)
host_disk_size_m = 0
if host_disks:
for key, value in host_disks.items():
if value['disk'].find("-fc-") != -1 \
or value['disk'].find("-iscsi-") != -1 \
or value['name'].find("mpath") != -1 \
or value['name'].find("spath") != -1 \
or value['removable'] == 'removable':
continue
disk_size_b = str(value.get('size', None))
disk_size_b_str = disk_size_b.strip().split()[0]
if disk_size_b_str:
disk_size_b_int = int(disk_size_b_str)
disk_size_m = disk_size_b_int // (1024 * 1024)
host_disk_size_m = host_disk_size_m + disk_size_m
host_disk_except_os_disk_lists = host_disk_size_m - os_disk_m - \
swap_size_m - boot_partition_m - redundant_partiton_m
LOG.warning(
'----start----host_disk_except_os_disk_lists: %s -----end--' %
host_disk_except_os_disk_lists)
return host_disk_except_os_disk_lists
def _check_host_validity(self, **paras):
'''
paras['db_lv_size'], paras['glance_lv_size'] , paras['disk_size']
'''
disk_size = paras.get('disk_size', None)
LOG.warning('--------disk_size:----- %s' % disk_size)
if disk_size:
disk_size_m = int(disk_size)
else:
disk_size_m = 0
if disk_size_m == 0: # Host hard disk size was 0,
# think that the host does not need to install the system
return # Don't need to ckeck the validity of hard disk size
db_lv_size_m = paras.get('db_lv_size', 300)
if db_lv_size_m:
db_lv_size_m = int(db_lv_size_m)
else:
db_lv_size_m = 0
glance_lv_size_m = paras.get('glance_lv_size', 17100)
if glance_lv_size_m:
glance_lv_size_m = int(glance_lv_size_m)
else:
glance_lv_size_m = 0
nova_lv_size_m = paras.get('nova_lv_size', 0)
if nova_lv_size_m:
nova_lv_size_m = int(nova_lv_size_m)
else:
nova_lv_size_m = 0
if nova_lv_size_m == -1:
nova_lv_size_m = 0
glance_lv_size_m = (glance_lv_size_m / 4) * 4
db_lv_size_m = (db_lv_size_m / 4) * 4
nova_lv_size_m = (nova_lv_size_m / 4) * 4
if glance_lv_size_m + db_lv_size_m + nova_lv_size_m > disk_size_m:
msg = _("There isn't enough disk space to specify database or "
"glance or nova disk, please specify database or "
"glance or nova disk size again")
LOG.debug(msg)
raise HTTPForbidden(msg)
def _check_nodes_exist(self, req, nodes):
for role_host_id in nodes:
self._raise_404_if_host_deleted(req, role_host_id)
def _check_services_exist(self, req, services):
for role_service_id in services:
self._raise_404_if_service_deleted(req, role_service_id)
def _check_config_set_id_exist(self, req, config_set_id):
self._raise_404_if_config_set_deleted(req, config_set_id)
def _check_glance_lv_value(
self,
req,
glance_lv_value,
role_name,
service_name_list):
if int(glance_lv_value) < 0 and int(glance_lv_value) != -1:
msg = _("glance_lv_size can't be negative except -1.")
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
if not service_name_list or 'glance' not in service_name_list:
msg = _("service 'glance' is not in role %s, so can't "
"set the size of glance lv.") % role_name
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
def _check_db_lv_size(self, req, db_lv_size, service_name_list):
if int(db_lv_size) < 0 and int(db_lv_size) != -1:
msg = _("The size of database disk can't be negative except -1.")
LOG.debug(msg)
raise HTTPForbidden(msg)
# Only the role with database service can be formulated the size of
# a database.
if 'mariadb' not in service_name_list and 'mongodb' not in \
service_name_list:
msg = _('The role without database service is unable '
'to specify the size of the database!')
LOG.debug(msg)
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
def _check_nova_lv_size(self, req, nova_lv_size, role_name):
if role_name != "COMPUTER":
msg = _("The role is not COMPUTER, it can't set logic "
"volume disk for nova.")
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
try:
if int(nova_lv_size) < 0 and int(nova_lv_size) != -1:
msg = _("The nova_lv_size must be -1 or [0, N).")
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
except:
msg = _("The nova_lv_size must be -1 or [0, N).")
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
def _check_all_lv_size(self, req, db_lv_size, glance_lv_size, nova_lv_size,
host_id_list, cluster_id, argws):
if db_lv_size or glance_lv_size or nova_lv_size:
for host_id in host_id_list:
host_disk_db_glance_nova_size = \
self.get_host_disk_db_glance_nova_size(
req, host_id, cluster_id)
if host_disk_db_glance_nova_size['db_lv_size'] and \
db_lv_size and int(
db_lv_size) < int(host_disk_db_glance_nova_size[
'db_lv_size']):
argws['db_lv_size'] = host_disk_db_glance_nova_size[
'db_lv_size']
else:
argws['db_lv_size'] = db_lv_size
if host_disk_db_glance_nova_size['glance_lv_size'] and \
glance_lv_size and int(
glance_lv_size) < int(host_disk_db_glance_nova_size[
'glance_lv_size']):
argws['glance_lv_size'] = host_disk_db_glance_nova_size[
'glance_lv_size']
else:
argws['glance_lv_size'] = glance_lv_size
if host_disk_db_glance_nova_size['nova_lv_size'] and \
nova_lv_size and int(
nova_lv_size) < int(host_disk_db_glance_nova_size[
'nova_lv_size']):
argws['nova_lv_size'] = host_disk_db_glance_nova_size[
'nova_lv_size']
else:
argws['nova_lv_size'] = nova_lv_size
argws['disk_size'] = host_disk_db_glance_nova_size['disk_size']
LOG.warning(
'--------host(%s) check_host_validity argws:----- %s' %
(host_id, argws))
self._check_host_validity(**argws)
def _check_deployment_backend(self, req, deployment_backend):
if deployment_backend not in SUPPORTED_DEPLOYMENT_BACKENDS:
msg = "deployment backend '%s' is not supported." % \
deployment_backend
raise HTTPBadRequest(explanation=msg,
request=req,
content_type="text/plain")
def _check_role_type_in_update_role(self, req, role_type, orig_role_meta):
if orig_role_meta['type'].lower() != role_type.lower():
msg = _("Role type can not be updated to other type.")
LOG.debug(msg)
raise HTTPForbidden(msg)
def _check_cluster_id_in_role_update(
self, req, role_cluster, orig_role_meta):
if orig_role_meta['type'].lower() == 'template':
msg = _("The template role does not belong to any cluster.")
LOG.debug(msg)
raise HTTPForbidden(msg)
orig_role_cluster = orig_role_meta['cluster_id']
if orig_role_cluster != role_cluster: # Can not change the cluster
# which the role belongs to
msg = _("Can't update the cluster of the role.")
LOG.debug(msg)
raise HTTPForbidden(msg)
else:
self._raise_404_if_cluster_deleted(req, role_cluster)
def _check_role_name_in_role_update(self, req, role_meta, orig_role_meta):
role_name = role_meta['name']
cluster_id = role_meta.get('cluster_id', orig_role_meta['cluster_id'])
if cluster_id:
self.check_cluster_role_name_repetition(req, role_name, cluster_id)
else: # role type was template, cluster id was None
self.check_template_role_name_repetition(req, role_name)
def _check_all_lv_size_of_nodes_with_role_in_role_update(
self, req, role_meta, orig_role_meta, role_host_id_list):
# check host with this role at the same time
cluster_id = role_meta.get('cluster_id', None)
if not cluster_id: # role with cluster
cluster_id = orig_role_meta['cluster_id']
if not cluster_id: # without cluster id, raise Error
msg = _("The cluster_id parameter can not be None!")
LOG.debug(msg)
raise HTTPForbidden(msg)
argws = dict()
if 'db_lv_size' in role_meta:
db_lv_size = role_meta['db_lv_size']
else: # The db_lv_size has been specified before.
db_lv_size = orig_role_meta.get('db_lv_size')
if 'glance_lv_size' in role_meta:
glance_lv_size = role_meta['glance_lv_size']
else:
glance_lv_size = orig_role_meta.get('glance_lv_size')
if 'nova_lv_size' in role_meta:
nova_lv_size = role_meta['nova_lv_size']
else:
nova_lv_size = orig_role_meta.get('nova_lv_size')
if 'nodes' in role_meta:
host_id_list = list(role_meta['nodes']) + role_host_id_list
else:
host_id_list = role_host_id_list
self._check_all_lv_size(req, db_lv_size, glance_lv_size,
nova_lv_size, host_id_list, cluster_id, argws)
def _check_ntp_server(self, req, role_name):
if role_name != 'CONTROLLER_HA':
msg = 'The role %s need no ntp_server' % role_name
raise HTTPForbidden(explanation=msg)
def _check_role_type_in_role_add(self, req, role_meta):
# role_type == None or not template, cluster id must not be None
role_type = role_meta['type']
if role_type.lower() != 'template':
role_cluster_id = role_meta.get('cluster_id', None)
if not role_cluster_id: # add role without cluster id parameter,
# raise error
msg = _(
"The cluster_id parameter can not be None "
"if role was not a template type.")
LOG.debug(msg)
raise HTTPForbidden(msg)
else: # role_type == template, cluster id is not necessary
if 'cluster_id' in role_meta:
msg = _("Tht template role cannot be added to any cluster.")
LOG.debug(msg)
raise HTTPForbidden(msg)
def _check_all_lv_size_with_role_in_role_add(self, req, role_meta):
cluster_id = role_meta.get('cluster_id', None)
if not cluster_id: # without cluster id, raise Error
msg = _("The cluster_id parameter can not be None!")
LOG.debug(msg)
raise HTTPForbidden(msg)
argws = dict()
db_lv_size = role_meta.get('db_lv_size', 0)
glance_lv_size = role_meta.get('glance_lv_size', 0)
nova_lv_size = role_meta.get('nova_lv_size', 0)
host_id_list = list(role_meta['nodes'])
self._check_all_lv_size(req, db_lv_size, glance_lv_size,
nova_lv_size, host_id_list, cluster_id, argws)
def get_host_disk_db_glance_nova_size(self, req, host_id, cluster_id):
'''
return :
host_disk_db_glance_nova_size['disk_size'] = 1024000
host_disk_db_glance_nova_size['db_lv_size'] = 1011
host_disk_db_glance_nova_size['glance_lv_size'] = 1011
host_disk_db_glance_nova_size['nova_lv_size'] = 1011
'''
# import pdb;pdb.set_trace()
host_disk_db_glance_nova_size = dict()
db_lv_size = list()
glance_lv_size = list()
nova_lv_size = list()
# disk_size = list()
host_info = self.get_host_meta_or_404(req, host_id)
if host_info:
if 'deleted' in host_info and host_info['deleted']:
msg = _("Node with identifier %s has been deleted.") % \
host_info[
'id']
LOG.debug(msg)
raise HTTPNotFound(msg)
# get host disk infomation
host_disk = self._get_host_disk_except_os_disk_by_info(host_info)
host_disk_db_glance_nova_size['disk_size'] = host_disk
# get role_host db/glance/nova infomation
cluster_info = self.get_cluster_meta_or_404(req, cluster_id)
if 'cluster' in host_info: # host with cluster
if host_info['cluster'] != cluster_info['name']:
# type(host_info['cluster']) = list,
# type(cluster_info['name']) = str
msg = _("Role and hosts belong to different cluster.")
LOG.debug(msg)
raise HTTPNotFound(msg)
else:
all_roles = registry.get_roles_detail(req.context)
cluster_roles = [
role for role in all_roles if role['cluster_id'] ==
cluster_id]
# roles infomation saved in cluster_roles
if 'role' in host_info and host_info[
'role']: # host with role
for role in cluster_roles:
if role['name'] in host_info[
'role'] and cluster_roles:
db_lv_size.append(role.get('db_lv_size', None))
glance_lv_size.append(
role.get('glance_lv_size', None))
nova_lv_size.append(
role.get('nova_lv_size', None))
if db_lv_size:
host_disk_db_glance_nova_size['db_lv_size'] = max(db_lv_size)
else: # host without cluster
host_disk_db_glance_nova_size['db_lv_size'] = 0
if glance_lv_size:
host_disk_db_glance_nova_size[
'glance_lv_size'] = max(glance_lv_size)
else:
host_disk_db_glance_nova_size['glance_lv_size'] = 0
if nova_lv_size:
host_disk_db_glance_nova_size['nova_lv_size'] = max(nova_lv_size)
else:
host_disk_db_glance_nova_size['nova_lv_size'] = 0
LOG.warning('--------host(%s)disk_db_glance_nova_size:----- %s' %
(host_id, host_disk_db_glance_nova_size))
return host_disk_db_glance_nova_size
def check_cluster_role_name_repetition(self, req, role_name, cluster_id):
all_roles = registry.get_roles_detail(req.context)
cluster_roles = [role for role in all_roles if role[
'cluster_id'] == cluster_id]
cluster_roles_name = [role['name'].lower() for role in cluster_roles]
if role_name.lower() in cluster_roles_name:
msg = _(
"The role %s has already been in the cluster %s!" %
(role_name, cluster_id))
LOG.debug(msg)
raise HTTPForbidden(msg)
def check_template_role_name_repetition(self, req, role_name):
all_roles = registry.get_roles_detail(req.context)
template_roles = [
role for role in all_roles if role['cluster_id'] is None]
template_roles_name = [role['name'].lower() for role in template_roles]
if role_name.lower() in template_roles_name:
msg = _(
"The role %s has already been in the the template role." %
role_name)
LOG.debug(msg)
raise HTTPForbidden(msg)
def _check_disk_parameters(self, req, role_meta):
if ('disk_location' in role_meta and
role_meta['disk_location'] not in SUPPORT_DISK_LOCATION):
msg = _("value of disk_location is not supported.")
raise HTTPForbidden(msg)
def _check_type_role_reasonable(self, req, role_meta):
if role_meta['role_type'] not in SUPPORTED_ROLE:
msg = 'The role type %s is illegal' % role_meta['role_type']
raise HTTPForbidden(explanation=msg)
def _check_role_update_parameters(self, req, role_meta, orig_role_meta,
role_service_id_list, role_host_id_list):
role_name = orig_role_meta['name']
if role_meta.get('type', None):
self._check_role_type_in_update_role(
req, role_meta['type'], orig_role_meta)
if 'ntp_server' in role_meta:
self._check_ntp_server(req, role_name)
if 'nodes' in role_meta:
self._check_nodes_exist(req, list(role_meta['nodes']))
if 'services' in role_meta:
self._check_services_exist(req, list(role_meta['services']))
role_service_id_list.extend(list(role_meta['services']))
if 'config_set_id' in role_meta:
self._check_config_set_id_exist(
req, role_meta['config_set_id'])
if 'cluster_id' in role_meta:
self._check_cluster_id_in_role_update(
req, role_meta['cluster_id'], orig_role_meta)
if 'name' in role_meta:
self._check_role_name_in_role_update(
req, role_meta, orig_role_meta)
service_name_list = self._get_service_name_list(
req, role_service_id_list)
glance_lv_value = role_meta.get(
'glance_lv_size', orig_role_meta['glance_lv_size'])
if glance_lv_value:
self._check_glance_lv_value(
req, glance_lv_value, role_name, service_name_list)
if role_meta.get('db_lv_size', None) and role_meta['db_lv_size']:
self._check_db_lv_size(
req, role_meta['db_lv_size'], service_name_list)
if role_meta.get('nova_lv_size', None):
self._check_nova_lv_size(req, role_meta['nova_lv_size'], role_name)
if 'nodes' in role_meta or role_host_id_list:
self._check_all_lv_size_of_nodes_with_role_in_role_update(
req, role_meta, orig_role_meta, role_host_id_list)
self._check_disk_parameters(req, role_meta)
if 'deployment_backend' in role_meta:
self._check_deployment_backend(
req, role_meta['deployment_backend'])
if role_meta.get('role_type', None):
self._check_type_role_reasonable(req, role_meta)
def _check_role_add_parameters(self, req, role_meta, role_service_id_list):
role_name = role_meta.get('name', None)
if role_meta.get('type', None):
self._check_role_type_in_role_add(req, role_meta)
if 'nodes' in role_meta:
self._check_nodes_exist(req, list(role_meta['nodes']))
if 'services' in role_meta:
self._check_services_exist(req, list(role_meta['services']))
role_service_id_list.extend(list(role_meta['services']))
if 'config_set_id' in role_meta:
self._check_config_set_id_exist(
req, role_meta['config_set_id'])
if 'cluster_id' in role_meta:
orig_cluster = role_meta['cluster_id']
self._raise_404_if_cluster_deleted(req, orig_cluster)
self.check_cluster_role_name_repetition(
req, role_name, orig_cluster)
else:
self.check_template_role_name_repetition(req, role_name)
service_name_list = self._get_service_name_list(
req, role_service_id_list)
glance_lv_value = role_meta.get('glance_lv_size', None)
if glance_lv_value:
self._check_glance_lv_value(
req, glance_lv_value, role_name, service_name_list)
if role_meta.get('db_lv_size', None) and role_meta['db_lv_size']:
self._check_db_lv_size(
req, role_meta['db_lv_size'], service_name_list)
if role_meta.get('nova_lv_size', None):
self._check_nova_lv_size(req, role_meta['nova_lv_size'], role_name)
if 'nodes' in role_meta:
self._check_all_lv_size_with_role_in_role_add(req, role_meta)
self._check_disk_parameters(req, role_meta)
if 'deployment_backend' in role_meta:
self._check_deployment_backend(
req, role_meta['deployment_backend'])
else:
role_meta['deployment_backend'] = 'tecs'
if role_meta.get('role_type', None):
self._check_type_role_reasonable(req, role_meta)
@utils.mutating
def add_role(self, req, role_meta):
"""
Adds a new role to Daisy.
:param req: The WSGI/Webob Request object
:param image_meta: Mapping of metadata about role
:raises HTTPBadRequest if x-role-name is missing
"""
self._enforce(req, 'add_role')
role_service_id_list = []
self._check_role_add_parameters(req, role_meta, role_service_id_list)
role_name = role_meta["name"]
role_description = role_meta["description"]
if role_meta.get('role_type',
None) == 'CONTROLLER_HA' and not role_meta.get(
'docker_vg_size', None):
role_meta['docker_vg_size'] = 104448
print role_name
print role_description
role_meta = registry.add_role_metadata(req.context, role_meta)
return {'role_meta': role_meta}
@utils.mutating
def delete_role(self, req, id):
"""
Deletes a role from Daisy.
:param req: The WSGI/Webob Request object
:param image_meta: Mapping of metadata about role
:raises HTTPBadRequest if x-role-name is missing
"""
self._enforce(req, 'delete_role')
# role = self.get_role_meta_or_404(req, id)
print "delete_role:%s" % id
try:
registry.delete_role_metadata(req.context, id)
except exception.NotFound as e:
msg = (_("Failed to find role to delete: %s") %
utils.exception_to_str(e))
LOG.warning(msg)
raise HTTPNotFound(explanation=msg,
request=req,
content_type="text/plain")
except exception.Forbidden as e:
msg = (_("Forbidden to delete role: %s") %
utils.exception_to_str(e))
LOG.warning(msg)
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
except exception.InUseByStore as e:
msg = (_("role %(id)s could not be deleted because it is in use: "
"%(exc)s") % {"id": id, "exc": utils.exception_to_str(e)})
LOG.warning(msg)
raise HTTPConflict(explanation=msg,
request=req,
content_type="text/plain")
else:
# self.notifier.info('role.delete', role)
return Response(body='', status=200)
@utils.mutating
def get_role(self, req, id):
"""
Returns metadata about an role in the HTTP headers of the
response object
:param req: The WSGI/Webob Request object
:param id: The opaque role identifier
:raises HTTPNotFound if role metadata is not available to user
"""
self._enforce(req, 'get_role')
role_meta_tmp = self.get_role_meta_or_404(req, id)
params = dict()
neutron_backend_meta = {}
neutron_backends_array = {}
neutron_backends_list = []
neutron_backends = registry.list_neutron_backend_metadata(req.context,
**params)
for neutron_backend_meta_tmp in neutron_backends:
if neutron_backend_meta_tmp['role_id'] == id:
neutron_backend_meta_tmp.pop('created_at')
neutron_backend_meta_tmp.pop('updated_at')
neutron_backend_meta_tmp.pop('role_id')
neutron_backend_meta_tmp.pop('id')
neutron_backend_meta_tmp.pop('deleted_at')
neutron_backend_meta['sdn_controller_type'] =\
neutron_backend_meta_tmp['neutron_backends_type']
neutron_backend_meta['neutron_agent_type'] =\
neutron_backend_meta_tmp['sdn_type']
neutron_backend_meta['zenic_port'] =\
neutron_backend_meta_tmp['port']
neutron_backend_meta['zenic_user_name'] =\
neutron_backend_meta_tmp['user_name']
neutron_backend_meta['zenic_user_password'] =\
neutron_backend_meta_tmp['user_pwd']
neutron_backend_meta['zenic_ip'] =\
neutron_backend_meta_tmp['controller_ip']
neutron_backend_meta['enable_l2_or_l3'] =\
neutron_backend_meta_tmp['enable_l2_or_l3']
neutron_backends_list.append(neutron_backend_meta)
neutron_backend_meta = {}
neutron_backends_array['neutron_backends_array'] =\
neutron_backends_list
role_meta = dict(role_meta_tmp.items() +
neutron_backends_array.items())
return {'role_meta': role_meta}
def detail(self, req):
"""
Returns detailed information for all available roles
:param req: The WSGI/Webob Request object
:retval The response body is a mapping of the following form::
{'roles': [
{'id': <ID>,
'name': <NAME>,
'description': <DESCRIPTION>,
'created_at': <TIMESTAMP>,
'updated_at': <TIMESTAMP>,
'deleted_at': <TIMESTAMP>|<NONE>,}, ...
]}
"""
self._enforce(req, 'get_roles')
params = self._get_query_params(req)
filters = params.get('filters', None)
if 'cluster_id' in filters:
cluster_id = filters['cluster_id']
self._raise_404_if_cluster_deleted(req, cluster_id)
try:
roles = registry.get_roles_detail(req.context, **params)
except exception.Invalid as e:
raise HTTPBadRequest(explanation=e.msg, request=req)
return dict(roles=roles)
@utils.mutating
def update_role(self, req, id, role_meta):
"""
Updates an existing role with the registry.
:param request: The WSGI/Webob Request object
:param id: The opaque image identifier
:retval Returns the updated image information as a mapping
"""
orig_role_meta = self.get_role_meta_or_404(req, id)
role_service_list = registry.get_role_services(req.context, id)
role_service_id_list = [role_service['service_id']
for role_service in role_service_list]
role_host_info_list = registry.get_role_host_metadata(req.context, id)
role_host_id_list = [role_host['host_id']
for role_host in role_host_info_list]
if orig_role_meta['role_type'] == "CONTROLLER_HA":
if not role_meta.get('docker_vg_size',
orig_role_meta['docker_vg_size']):
role_meta['docker_vg_size'] = '104448'
if orig_role_meta['role_type'] != "CONTROLLER_HA" and role_meta.get(
'docker_vg_size', None):
msg = _("only CONTROLLER_HA can be updated with docker_vg_size.")
LOG.debug(msg)
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
self._check_role_update_parameters(
req,
role_meta,
orig_role_meta,
role_service_id_list,
role_host_id_list)
if orig_role_meta['role_type'] == "CONTROLLER_HA":
cluster_meta = {}
cluster_meta['public_vip'] = role_meta.get(
'public_vip') or role_meta.get('vip')
if cluster_meta['public_vip']:
cluster_meta = registry.update_cluster_metadata(
req.context, orig_role_meta['cluster_id'], cluster_meta)
params = dict()
neutron_backends = registry.list_neutron_backend_metadata(req.context,
**params)
if neutron_backends and 'neutron_backends_array' in role_meta:
for neutron_backend in neutron_backends:
if neutron_backend.get('role_id') == id:
registry.delete_neutron_backend_metadata(
req.context,
neutron_backend['id'])
backends = get_backend()
for backend in backends:
backend_driver = driver.load_deployment_driver(backend)
role_meta = backend_driver.config_neutron_backend(
req,
orig_role_meta,
role_meta)
self._enforce(req, 'modify_image')
# orig_role_meta = self.get_role_meta_or_404(req, id)
# Do not allow any updates on a deleted image.
# Fix for LP Bug #1060930
if orig_role_meta['deleted']:
msg = _("Forbidden to update deleted role.")
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
try:
role_meta = registry.update_role_metadata(req.context,
id,
role_meta)
except exception.Invalid as e:
msg = (_("Failed to update role metadata. Got error: %s") %
utils.exception_to_str(e))
LOG.warning(msg)
raise HTTPBadRequest(explanation=msg,
request=req,
content_type="text/plain")
except exception.NotFound as e:
msg = (_("Failed to find role to update: %s") %
utils.exception_to_str(e))
LOG.warning(msg)
raise HTTPNotFound(explanation=msg,
request=req,
content_type="text/plain")
except exception.Forbidden as e:
msg = (_("Forbidden to update role: %s") %
utils.exception_to_str(e))
LOG.warning(msg)
raise HTTPForbidden(explanation=msg,
request=req,
content_type="text/plain")
except (exception.Conflict, exception.Duplicate) as e:
LOG.warning(utils.exception_to_str(e))
raise HTTPConflict(body=_('Host operation conflicts'),
request=req,
content_type='text/plain')
else:
self.notifier.info('role.update', role_meta)
return {'role_meta': role_meta}
class RoleDeserializer(wsgi.JSONRequestDeserializer):
"""Handles deserialization of specific controller method requests."""
def _deserialize(self, request):
result = {}
result["role_meta"] = utils.get_role_meta(request)
return result
def add_role(self, request):
return self._deserialize(request)
def update_role(self, request):
return self._deserialize(request)
class RoleSerializer(wsgi.JSONResponseSerializer):
"""Handles serialization of specific controller method responses."""
def __init__(self):
self.notifier = notifier.Notifier()
def add_role(self, response, result):
role_meta = result['role_meta']
response.status = 201
response.headers['Content-Type'] = 'application/json'
response.body = self.to_json(dict(role=role_meta))
return response
def delete_role(self, response, result):
role_meta = result['role_meta']
response.status = 201
response.headers['Content-Type'] = 'application/json'
response.body = self.to_json(dict(role=role_meta))
return response
def get_role(self, response, result):
role_meta = result['role_meta']
response.status = 201
response.headers['Content-Type'] = 'application/json'
response.body = self.to_json(dict(role=role_meta))
return response
def create_resource():
"""Roles resource factory method"""
deserializer = RoleDeserializer()
serializer = RoleSerializer()
return wsgi.Resource(Controller(), deserializer, serializer)