172 lines
6.8 KiB
Python
172 lines
6.8 KiB
Python
# Copyright 2014 eBay Software 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.
|
|
|
|
from oslo_config.cfg import NoSuchOptError
|
|
|
|
from trove.cluster import models
|
|
from trove.cluster import views
|
|
from trove.common import apischema
|
|
from trove.common import cfg
|
|
from trove.common import exception
|
|
from trove.common.i18n import _
|
|
from trove.common import pagination
|
|
from trove.common.strategies.cluster import strategy
|
|
from trove.common import utils
|
|
from trove.common import wsgi
|
|
from trove.datastore import models as datastore_models
|
|
from trove.openstack.common import log as logging
|
|
|
|
|
|
CONF = cfg.CONF
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class ClusterController(wsgi.Controller):
|
|
|
|
"""Controller for cluster functionality."""
|
|
schemas = apischema.cluster.copy()
|
|
|
|
@classmethod
|
|
def get_action_schema(cls, body, action_schema):
|
|
action_type = body.keys()[0]
|
|
return action_schema.get(action_type, {})
|
|
|
|
@classmethod
|
|
def get_schema(cls, action, body):
|
|
action_schema = super(ClusterController, cls).get_schema(action, body)
|
|
if action == 'action':
|
|
action_schema = cls.get_action_schema(body, action_schema)
|
|
return action_schema
|
|
|
|
def action(self, req, body, tenant_id, id):
|
|
LOG.debug("Committing Action Against Cluster for "
|
|
"Tenant '%s'" % tenant_id)
|
|
LOG.info(_("req : '%s'\n\n") % req)
|
|
LOG.info(_("id : '%s'\n\n") % id)
|
|
if not body:
|
|
raise exception.BadRequest(_("Invalid request body."))
|
|
context = req.environ[wsgi.CONTEXT_KEY]
|
|
cluster = models.Cluster.load(context, id)
|
|
manager = cluster.datastore_version.manager
|
|
api_strategy = strategy.load_api_strategy(manager)
|
|
_actions = api_strategy.cluster_controller_actions
|
|
selected_action = None
|
|
for key in body:
|
|
if key in _actions:
|
|
selected_action = _actions[key]
|
|
break
|
|
else:
|
|
message = _("No action '%(action)s' supplied "
|
|
"by strategy for manager '%(manager)s'") % (
|
|
{'action': key, 'manager': manager})
|
|
raise exception.TroveError(message)
|
|
return selected_action(cluster, body)
|
|
|
|
def show(self, req, tenant_id, id):
|
|
"""Return a single cluster."""
|
|
LOG.debug("Showing a Cluster for Tenant '%s'" % tenant_id)
|
|
LOG.info(_("req : '%s'\n\n") % req)
|
|
LOG.info(_("id : '%s'\n\n") % id)
|
|
|
|
context = req.environ[wsgi.CONTEXT_KEY]
|
|
cluster = models.Cluster.load(context, id)
|
|
return wsgi.Result(views.load_view(cluster, req=req).data(), 200)
|
|
|
|
def show_instance(self, req, tenant_id, cluster_id, instance_id):
|
|
"""Return a single instance belonging to a cluster."""
|
|
LOG.debug("Showing an Instance in a Cluster for Tenant '%s'"
|
|
% tenant_id)
|
|
LOG.info(_("req : '%s'\n\n") % req)
|
|
LOG.info(_("cluster_id : '%s'\n\n") % cluster_id)
|
|
LOG.info(_("instance_id : '%s'\n\n") % instance_id)
|
|
|
|
context = req.environ[wsgi.CONTEXT_KEY]
|
|
cluster = models.Cluster.load(context, cluster_id)
|
|
instance = models.Cluster.load_instance(context, cluster.id,
|
|
instance_id)
|
|
return wsgi.Result(views.ClusterInstanceDetailView(
|
|
instance, req=req).data(), 200)
|
|
|
|
def delete(self, req, tenant_id, id):
|
|
"""Delete a cluster."""
|
|
LOG.debug("Deleting a Cluster for Tenant '%s'" % tenant_id)
|
|
LOG.info(_("req : '%s'\n\n") % req)
|
|
LOG.info(_("id : '%s'\n\n") % id)
|
|
|
|
context = req.environ[wsgi.CONTEXT_KEY]
|
|
cluster = models.Cluster.load(context, id)
|
|
cluster.delete()
|
|
return wsgi.Result(None, 202)
|
|
|
|
def index(self, req, tenant_id):
|
|
"""Return a list of clusters."""
|
|
LOG.debug("Showing a list of clusters for Tenant '%s'" % tenant_id)
|
|
LOG.info(_("req : '%s'\n\n") % req)
|
|
|
|
context = req.environ[wsgi.CONTEXT_KEY]
|
|
if not context.is_admin and context.tenant != tenant_id:
|
|
raise exception.TroveOperationAuthError(tenant_id=context.tenant)
|
|
|
|
# load all clusters and instances for the tenant
|
|
clusters, marker = models.Cluster.load_all(context, tenant_id)
|
|
view = views.ClustersView(clusters, req=req)
|
|
paged = pagination.SimplePaginatedDataView(req.url, 'clusters', view,
|
|
marker)
|
|
return wsgi.Result(paged.data(), 200)
|
|
|
|
def create(self, req, body, tenant_id):
|
|
LOG.debug("Creating a Cluster for Tenant '%s'" % tenant_id)
|
|
LOG.info(_("req : '%s'\n\n") % req)
|
|
LOG.info(_("body : '%s'\n\n") % body)
|
|
|
|
context = req.environ[wsgi.CONTEXT_KEY]
|
|
name = body['cluster']['name']
|
|
datastore_args = body['cluster'].get('datastore', {})
|
|
datastore, datastore_version = (
|
|
datastore_models.get_datastore_version(**datastore_args))
|
|
|
|
try:
|
|
clusters_enabled = (CONF.get(datastore_version.manager)
|
|
.get('cluster_support'))
|
|
except NoSuchOptError:
|
|
clusters_enabled = False
|
|
|
|
if not clusters_enabled:
|
|
raise exception.ClusterDatastoreNotSupported(
|
|
datastore=datastore.name,
|
|
datastore_version=datastore_version.name)
|
|
|
|
nodes = body['cluster']['instances']
|
|
instances = []
|
|
for node in nodes:
|
|
flavor_id = utils.get_id_from_href(node['flavorRef'])
|
|
volume_size = nics = availability_zone = None
|
|
if 'volume' in node:
|
|
volume_size = int(node['volume']['size'])
|
|
if 'nics' in node:
|
|
nics = node['nics']
|
|
if 'availability_zone' in node:
|
|
availability_zone = node['availability_zone']
|
|
|
|
instances.append({"flavor_id": flavor_id,
|
|
"volume_size": volume_size,
|
|
"nics": nics,
|
|
"availability_zone": availability_zone})
|
|
|
|
cluster = models.Cluster.create(context, name, datastore,
|
|
datastore_version, instances)
|
|
view = views.load_view(cluster, req=req, load_servers=False)
|
|
return wsgi.Result(view.data(), 200)
|