コード例 #1
0
ファイル: service.py プロジェクト: Tesora/tesora-trove
    def action(self, req, body, tenant_id, id):
        LOG.debug(("Committing Action Against Cluster for "
                   "Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nid : '%(id)s'\n\n") %
                  {"req": req, "id": id, "tenant_id": tenant_id})
        if not body:
            raise exception.BadRequest(_("Invalid request body."))

        if len(body) != 1:
            raise exception.BadRequest(_("Action request should have exactly"
                                         " one action specified in body"))
        context = req.environ[wsgi.CONTEXT_KEY]
        cluster = models.Cluster.load(context, id)
        if ('reset-status' in body and
                'force_delete' not in body['reset-status']):
            self.authorize_cluster_action(context, 'reset-status', cluster)
        elif ('reset-status' in body and
                'force_delete' in body['reset-status']):
            self.authorize_cluster_action(context, 'force_delete', cluster)
        else:
            self.authorize_cluster_action(context, 'action', cluster)
        cluster.action(context, req, *next(iter(body.items())))

        view = views.load_view(cluster, req=req, load_servers=False)
        wsgi_result = wsgi.Result(view.data(), 202)

        return wsgi_result
コード例 #2
0
ファイル: service.py プロジェクト: vmazur/trove
 def action(self, req, body, tenant_id, id):
     LOG.debug(("Committing Action Against Cluster for "
                "Tenant '%(tenant_id)s'\n"
                "req : '%(req)s'\n\nid : '%(id)s'\n\n") %
               {"req": req, "id": id, "tenant_id": tenant_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)
     cluster = selected_action(cluster, body)
     if cluster:
         view = views.load_view(cluster, req=req, load_servers=False)
         wsgi_result = wsgi.Result(view.data(), 202)
     else:
         wsgi_result = wsgi.Result(None, 202)
     return wsgi_result
コード例 #3
0
ファイル: service.py プロジェクト: avontd2868/trove
    def action(self, req, body, tenant_id, id):
        LOG.debug(("Committing Action Against Cluster for "
                   "Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nid : '%(id)s'\n\n") % {
                       "req": req,
                       "id": id,
                       "tenant_id": tenant_id
                   })
        if not body:
            raise exception.BadRequest(_("Invalid request body."))

        if len(body) != 1:
            raise exception.BadRequest(
                _("Action request should have exactly"
                  " one action specified in body"))
        context = req.environ[wsgi.CONTEXT_KEY]
        cluster = models.Cluster.load(context, id)
        if ('reset-status' in body
                and 'force_delete' not in body['reset-status']):
            self.authorize_cluster_action(context, 'reset-status', cluster)
        elif ('reset-status' in body
              and 'force_delete' in body['reset-status']):
            self.authorize_cluster_action(context, 'force_delete', cluster)
        else:
            self.authorize_cluster_action(context, 'action', cluster)
        cluster.action(context, req, *next(iter(body.items())))

        view = views.load_view(cluster, req=req, load_servers=False)
        wsgi_result = wsgi.Result(view.data(), 202)

        return wsgi_result
コード例 #4
0
ファイル: service.py プロジェクト: ISCAS-VDI/trove-base
    def create(self, req, body, tenant_id):
        LOG.debug(("Creating a Cluster for Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nbody : '%(body)s'\n\n") % {
                       "tenant_id": tenant_id,
                       "req": req,
                       "body": 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))

        # TODO(saurabhs): add extended_properties to apischema
        extended_properties = body['cluster'].get('extended_properties', {})

        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 = volume_type = nics = availability_zone = None
            if 'volume' in node:
                volume_size = int(node['volume']['size'])
                volume_type = node['volume'].get('volume_type')
            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,
                "volume_type": volume_type,
                "nics": nics,
                "availability_zone": availability_zone
            })

        context.notification = notification.DBaaSClusterCreate(context,
                                                               request=req)
        with StartNotification(context,
                               name=name,
                               datastore=datastore.name,
                               datastore_version=datastore_version.name):
            cluster = models.Cluster.create(context, name, datastore,
                                            datastore_version, instances,
                                            extended_properties)
        view = views.load_view(cluster, req=req, load_servers=False)
        return wsgi.Result(view.data(), 200)
コード例 #5
0
ファイル: service.py プロジェクト: vmazur/trove
    def show(self, req, tenant_id, id):
        """Return a single cluster."""
        LOG.debug(("Showing a Cluster for Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nid : '%(id)s'\n\n") %
                  {"req": req, "id": id, "tenant_id": tenant_id})

        context = req.environ[wsgi.CONTEXT_KEY]
        cluster = models.Cluster.load(context, id)
        return wsgi.Result(views.load_view(cluster, req=req).data(), 200)
コード例 #6
0
    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)
コード例 #7
0
ファイル: service.py プロジェクト: paramtech/tesora-trove
    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))

        # TODO(saurabhs): add extended_properties to apischema
        extended_properties = body['cluster'].get('extended_properties', {})

        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 = volume_type = nics = availability_zone = None
            if 'volume' in node:
                volume_size = int(node['volume']['size'])
                volume_type = node['volume'].get('volume_type')
            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,
                              "volume_type": volume_type,
                              "nics": nics,
                              "availability_zone": availability_zone})

        context.notification = notification.DBaaSClusterCreate(context,
                                                               request=req)
        with StartNotification(context, name=name, datastore=datastore.name,
                               datastore_version=datastore_version.name):
            cluster = models.Cluster.create(context, name, datastore,
                                            datastore_version, instances,
                                            extended_properties)
        view = views.load_view(cluster, req=req, load_servers=False)
        return wsgi.Result(view.data(), 200)
コード例 #8
0
ファイル: service.py プロジェクト: Tesora/tesora-trove
    def get_coordinator_node_id(self, req, tenant_id, cluster_id):
        context = req.environ[wsgi.CONTEXT_KEY]
        cluster = cluster_models.Cluster.load(context, cluster_id)
        cluster_view = cluster_views.load_view(cluster, req)
        cluster_instances, _ = cluster_view.build_instances()
        instance_ids = [instance['id'] for instance in cluster_instances]

        if not instance_ids:
            exception.TroveError(
                _("This cluster does not have any API access nodes."))

        return instance_ids[0]
コード例 #9
0
    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

        def find_action_key():
            for key in body:
                if key in _actions:
                    return key
            else:
                message = _("No action '%(action)s' supplied "
                            "by strategy for manager '%(manager)s'") % (
                                {
                                    'action': key,
                                    'manager': manager
                                })
                raise exception.TroveError(message)

        action_key = find_action_key()
        if action_key == 'grow':
            context.notification = notification.DBaaSClusterGrow(context,
                                                                 request=req)
        elif action_key == 'shrink':
            context.notification = notification.DBaaSClusterShrink(context,
                                                                   request=req)
        with StartNotification(context, cluster_id=id):
            selected_action = _actions[action_key]
            cluster = selected_action(cluster, body)

        if cluster:
            view = views.load_view(cluster, req=req, load_servers=False)
            wsgi_result = wsgi.Result(view.data(), 202)
        else:
            wsgi_result = wsgi.Result(None, 202)

        return wsgi_result
コード例 #10
0
ファイル: service.py プロジェクト: stewie925/trove
    def action(self, req, body, tenant_id, id):
        LOG.debug(("Committing Action Against Cluster for "
                   "Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nid : '%(id)s'\n\n") %
                  {"req": req, "id": id, "tenant_id": tenant_id})
        if not body:
            raise exception.BadRequest(_("Invalid request body."))
        if len(body) != 1:
            raise exception.BadRequest(_("Action request should have exactly"
                                         " one action specified in body"))
        context = req.environ[wsgi.CONTEXT_KEY]
        cluster = models.Cluster.load(context, id)
        cluster.action(context, req, *body.items()[0])

        view = views.load_view(cluster, req=req, load_servers=False)
        wsgi_result = wsgi.Result(view.data(), 202)
        return wsgi_result
コード例 #11
0
    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)
コード例 #12
0
ファイル: service.py プロジェクト: henrylv206/trove
    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)
コード例 #13
0
ファイル: service.py プロジェクト: paramtech/tesora-trove
    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

        def find_action_key():
            for key in body:
                if key in _actions:
                    return key
            else:
                message = _("No action '%(action)s' supplied "
                            "by strategy for manager '%(manager)s'") % (
                                {'action': key, 'manager': manager})
                raise exception.TroveError(message)

        action_key = find_action_key()
        if action_key == 'grow':
            context.notification = notification.DBaaSClusterGrow(context,
                                                                 request=req)
        elif action_key == 'shrink':
            context.notification = notification.DBaaSClusterShrink(context,
                                                                   request=req)
        with StartNotification(context, cluster_id=id):
            selected_action = _actions[action_key]
            cluster = selected_action(cluster, body)

        if cluster:
            view = views.load_view(cluster, req=req, load_servers=False)
            wsgi_result = wsgi.Result(view.data(), 202)
        else:
            wsgi_result = wsgi.Result(None, 202)

        return wsgi_result
コード例 #14
0
ファイル: service.py プロジェクト: CMSS-BCRDB/RDSV1.0
    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'])
            if 'volume' in node:
                volume_size = int(node['volume']['size'])
            else:
                volume_size = None
            instances.append({"flavor_id": flavor_id,
                              "volume_size": volume_size})

        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)
コード例 #15
0
ファイル: service.py プロジェクト: avontd2868/trove
    def create(self, req, body, tenant_id):
        LOG.debug(("Creating a Cluster for Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nbody : '%(body)s'\n\n") % {
                       "tenant_id": tenant_id,
                       "req": req,
                       "body": body
                   })

        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'cluster:create')

        name = body['cluster']['name']
        datastore_args = body['cluster'].get('datastore', {})
        datastore, datastore_version = (datastore_models.get_datastore_version(
            **datastore_args))

        # TODO(saurabhs): add extended_properties to apischema
        extended_properties = body['cluster'].get('extended_properties', {})

        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 = volume_type = nics = availability_zone = None
            modules = None
            if 'volume' in node:
                volume_size = int(node['volume']['size'])
                volume_type = node['volume'].get('type')
            if 'nics' in node:
                nics = node['nics']
            if 'availability_zone' in node:
                availability_zone = node['availability_zone']
            if 'modules' in node:
                modules = node['modules']

            instances.append({
                "flavor_id": flavor_id,
                "volume_size": volume_size,
                "volume_type": volume_type,
                "nics": nics,
                "availability_zone": availability_zone,
                'region_name': node.get('region_name'),
                "modules": modules
            })

        locality = body['cluster'].get('locality')
        if locality:
            locality_domain = ['affinity', 'anti-affinity']
            locality_domain_msg = ("Invalid locality '%s'. "
                                   "Must be one of ['%s']" %
                                   (locality, "', '".join(locality_domain)))
            if locality not in locality_domain:
                raise exception.BadRequest(msg=locality_domain_msg)

        configuration = body['cluster'].get('configuration')

        context.notification = notification.DBaaSClusterCreate(context,
                                                               request=req)
        with StartNotification(context,
                               name=name,
                               datastore=datastore.name,
                               datastore_version=datastore_version.name):
            cluster = models.Cluster.create(context, name, datastore,
                                            datastore_version, instances,
                                            extended_properties, locality,
                                            configuration)
        cluster.locality = locality
        view = views.load_view(cluster, req=req, load_servers=False)
        return wsgi.Result(view.data(), 200)
コード例 #16
0
    def create(self, req, body, tenant_id):
        LOG.debug(
            ("Creating a Cluster for Tenant '%(tenant_id)s'\n" "req : '%(req)s'\n\nbody : '%(body)s'\n\n")
            % {"tenant_id": tenant_id, "req": req, "body": 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)

        # TODO(saurabhs): add extended_properties to apischema
        extended_properties = body["cluster"].get("extended_properties", {})

        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 = volume_type = nics = availability_zone = None
            modules = None
            if "volume" in node:
                volume_size = int(node["volume"]["size"])
                volume_type = node["volume"].get("volume_type")
            if "nics" in node:
                nics = node["nics"]
            if "availability_zone" in node:
                availability_zone = node["availability_zone"]
            if "modules" in node:
                modules = node["modules"]

            instances.append(
                {
                    "flavor_id": flavor_id,
                    "volume_size": volume_size,
                    "volume_type": volume_type,
                    "nics": nics,
                    "availability_zone": availability_zone,
                    "region_name": node.get("region_name"),
                    "modules": modules,
                }
            )

        locality = body["cluster"].get("locality")
        if locality:
            locality_domain = ["affinity", "anti-affinity"]
            locality_domain_msg = "Invalid locality '%s'. " "Must be one of ['%s']" % (
                locality,
                "', '".join(locality_domain),
            )
            if locality not in locality_domain:
                raise exception.BadRequest(msg=locality_domain_msg)

        context.notification = notification.DBaaSClusterCreate(context, request=req)
        with StartNotification(context, name=name, datastore=datastore.name, datastore_version=datastore_version.name):
            cluster = models.Cluster.create(
                context, name, datastore, datastore_version, instances, extended_properties, locality
            )
        cluster.locality = locality
        view = views.load_view(cluster, req=req, load_servers=False)
        return wsgi.Result(view.data(), 200)
コード例 #17
0
ファイル: test_cluster_views.py プロジェクト: vdialani/trove
 def test_load_view(self, *args):
     cluster = Mock()
     cluster.datastore_version.manager = 'mongodb'
     view = load_view(cluster, Mock())
     self.assertTrue(isinstance(view, MongoDbClusterView))
コード例 #18
0
ファイル: service.py プロジェクト: Tesora/tesora-trove
    def create(self, req, body, tenant_id):
        LOG.debug(("Creating a Cluster for Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\nbody : '%(body)s'\n\n") %
                  {"tenant_id": tenant_id, "req": req, "body": body})

        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'cluster:create')

        name = body['cluster']['name']
        datastore_args = body['cluster'].get('datastore', {})
        datastore, datastore_version = (
            datastore_models.get_datastore_version(**datastore_args))

        # TODO(saurabhs): add extended_properties to apischema
        extended_properties = body['cluster'].get('extended_properties', {})

        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 = volume_type = nics = availability_zone = None
            modules = None
            if 'volume' in node:
                volume_size = int(node['volume']['size'])
                volume_type = node['volume'].get('type')
            if 'nics' in node:
                nics = node['nics']
            if 'availability_zone' in node:
                availability_zone = node['availability_zone']
            if 'modules' in node:
                modules = node['modules']
            instance_type = None
            if 'type' in node:
                instance_type = node['type']
                if isinstance(instance_type, six.string_types):
                    instance_type = instance_type.split(',')

            instances.append({"flavor_id": flavor_id,
                              "volume_size": volume_size,
                              "volume_type": volume_type,
                              "nics": nics,
                              "availability_zone": availability_zone,
                              'region_name': node.get('region_name'),
                              "modules": modules,
                              "instance_type": instance_type})

        locality = body['cluster'].get('locality')
        if locality:
            locality_domain = ['affinity', 'anti-affinity']
            locality_domain_msg = ("Invalid locality '%s'. "
                                   "Must be one of ['%s']" %
                                   (locality,
                                    "', '".join(locality_domain)))
            if locality not in locality_domain:
                raise exception.BadRequest(msg=locality_domain_msg)

        configuration = body['cluster'].get('configuration')

        context.notification = notification.DBaaSClusterCreate(context,
                                                               request=req)
        with StartNotification(context, name=name, datastore=datastore.name,
                               datastore_version=datastore_version.name):
            cluster = models.Cluster.create(context, name, datastore,
                                            datastore_version, instances,
                                            extended_properties,
                                            locality, configuration)
        cluster.locality = locality
        view = views.load_view(cluster, req=req, load_servers=False)
        return wsgi.Result(view.data(), 200)