示例#1
0
    def create(self, req, body, tenant_id):
        LOG.info("Creating a backup for tenant %s", tenant_id)
        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'backup:create')
        data = body['backup']
        instance = data['instance']
        name = data['name']
        desc = data.get('description')
        parent = data.get('parent_id')
        incremental = data.get('incremental')
        swift_container = data.get('swift_container')

        context.notification = notification.DBaaSBackupCreate(context,
                                                              request=req)

        if not swift_container:
            instance_id = utils.get_id_from_href(instance)
            backup_strategy = BackupStrategy.get(context, instance_id)
            if backup_strategy:
                swift_container = backup_strategy.swift_container

        with StartNotification(context,
                               name=name,
                               instance_id=instance,
                               description=desc,
                               parent_id=parent):
            backup = Backup.create(context,
                                   instance,
                                   name,
                                   desc,
                                   parent_id=parent,
                                   incremental=incremental,
                                   swift_container=swift_container)

        return wsgi.Result(views.BackupView(backup).data(), 202)
示例#2
0
    def index(self, req, tenant_id):
        """Return a list of clusters."""
        LOG.debug(("Showing a list of clusters for Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\n") % {"req": req,
                                             "tenant_id": tenant_id})

        context = req.environ[wsgi.CONTEXT_KEY]

        # This theoretically allows the Admin tenant list clusters for
        # only one particular tenant as opposed to listing all clusters for
        # for all tenants.
        # * As far as I can tell this is the only call which actually uses the
        #   passed-in 'tenant_id' for anything.
        if not context.is_admin and context.tenant != tenant_id:
            raise exception.TroveOperationAuthError(tenant_id=context.tenant)

        # The rule checks that the currently authenticated tenant can perform
        # the 'cluster-list' action.
        policy.authorize_on_tenant(context, 'cluster:index')

        # 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)
示例#3
0
    def index(self, req, tenant_id):
        """
        Return all backups information for a tenant ID.
        """
        LOG.debug("Listing backups for tenant %s", tenant_id)
        datastore = req.GET.get('datastore')
        instance_id = req.GET.get('instance_id')
        project_id = req.GET.get('project_id')
        all_projects = strutils.bool_from_string(req.GET.get('all_projects'))
        context = req.environ[wsgi.CONTEXT_KEY]

        if project_id or all_projects:
            policy.authorize_on_tenant(context, 'backup:index:all_projects')
        else:
            policy.authorize_on_tenant(context, 'backup:index')

        backups, marker = Backup.list(context,
                                      datastore=datastore,
                                      instance_id=instance_id,
                                      project_id=project_id,
                                      all_projects=all_projects)
        view = views.BackupViews(backups)
        paged = pagination.SimplePaginatedDataView(req.url, 'backups', view,
                                                   marker)
        return wsgi.Result(paged.data(), 200)
示例#4
0
文件: service.py 项目: wffeige/trove
    def create(self, req, body, tenant_id):

        name = body['module']['name']
        LOG.info("Creating module '%s'", name)

        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'module:create')
        module_type = body['module']['module_type']
        contents = body['module']['contents']

        description = body['module'].get('description')
        all_tenants = body['module'].get('all_tenants', 0)
        module_tenant_id = None if all_tenants else tenant_id
        datastore = body['module'].get('datastore', {}).get('type', None)
        ds_version = body['module'].get('datastore', {}).get('version', None)
        auto_apply = body['module'].get('auto_apply', 0)
        visible = body['module'].get('visible', 1)
        live_update = body['module'].get('live_update', 0)
        priority_apply = body['module'].get('priority_apply', 0)
        apply_order = body['module'].get('apply_order', 5)
        full_access = body['module'].get('full_access', None)

        module = models.Module.create(context, name, module_type, contents,
                                      description, module_tenant_id, datastore,
                                      ds_version, auto_apply, visible,
                                      live_update, priority_apply, apply_order,
                                      full_access)
        view_data = views.DetailedModuleView(module)
        return wsgi.Result(view_data.data(), 200)
示例#5
0
    def create(self, req, body, tenant_id):

        name = body['module']['name']
        LOG.info(_("Creating module '%s'") % name)

        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'module:create')
        module_type = body['module']['module_type']
        contents = body['module']['contents']

        description = body['module'].get('description')
        all_tenants = body['module'].get('all_tenants', 0)
        module_tenant_id = None if all_tenants else tenant_id
        datastore = body['module'].get('datastore', {}).get('type', None)
        ds_version = body['module'].get('datastore', {}).get('version', None)
        auto_apply = body['module'].get('auto_apply', 0)
        visible = body['module'].get('visible', 1)
        live_update = body['module'].get('live_update', 0)
        priority_apply = body['module'].get('priority_apply', 0)
        apply_order = body['module'].get('apply_order', 5)
        full_access = body['module'].get('full_access', None)

        module = models.Module.create(
            context, name, module_type, contents,
            description, module_tenant_id, datastore, ds_version,
            auto_apply, visible, live_update, priority_apply,
            apply_order, full_access)
        view_data = views.DetailedModuleView(module)
        return wsgi.Result(view_data.data(), 200)
示例#6
0
    def index(self, req, tenant_id):
        """Return a list of clusters."""
        LOG.debug(("Showing a list of clusters for Tenant '%(tenant_id)s'\n"
                   "req : '%(req)s'\n\n") % {
                       "req": req,
                       "tenant_id": tenant_id
                   })

        context = req.environ[wsgi.CONTEXT_KEY]

        # This theoretically allows the Admin tenant list clusters for
        # only one particular tenant as opposed to listing all clusters for
        # for all tenants.
        # * As far as I can tell this is the only call which actually uses the
        #   passed-in 'tenant_id' for anything.
        if not context.is_admin and context.tenant != tenant_id:
            raise exception.TroveOperationAuthError(tenant_id=context.tenant)

        # The rule checks that the currently authenticated tenant can perform
        # the 'cluster-list' action.
        policy.authorize_on_tenant(context, 'cluster:index')

        # 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)
示例#7
0
文件: service.py 项目: hejianle/trove
 def index(self, req, tenant_id):
     """Return all instances."""
     LOG.info("Listing database instances for tenant '%s'", tenant_id)
     LOG.debug("req : '%s'\n\n", req)
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'instance:index')
     instances = self._get_instances(req, instance_view=views.InstanceView)
     return wsgi.Result(instances, 200)
示例#8
0
 def authorize_request(cls, req, rule_name):
     """Parameters (configuration templates) bind to a datastore.
     Datastores are not owned by any particular tenant so we only check
     the current tenant is allowed to perform the action.
     """
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'configuration-parameter:%s'
                                % rule_name)
示例#9
0
 def test_authorize_on_tenant(self):
     test_rule = NonCallableMock()
     trove_policy.authorize_on_tenant(self.context, test_rule)
     self.mock_get_enforcer.assert_called_once_with()
     self.mock_enforcer.authorize.assert_called_once_with(
         test_rule, {'tenant': self.context.tenant}, self.context.to_dict(),
         do_raise=True, exc=trove_exceptions.PolicyNotAuthorized,
         action=test_rule)
示例#10
0
 def index(self, req, tenant_id):
     context = req.environ[wsgi.CONTEXT_KEY]
     configs, marker = models.Configurations.load(context)
     policy.authorize_on_tenant(context, 'configuration:index')
     view = views.ConfigurationsView(configs)
     paged = pagination.SimplePaginatedDataView(req.url, 'configurations',
                                                view, marker)
     return wsgi.Result(paged.data(), 200)
示例#11
0
文件: service.py 项目: wffeige/trove
 def authorize_module_action(cls, context, module_rule_name, module):
     """If a module is not owned by any particular tenant just check
     that the current tenant is allowed to perform the action.
     """
     if module.tenant_id is not None:
         policy.authorize_on_target(context, 'module:%s' % module_rule_name,
                                    {'tenant': module.tenant_id})
     else:
         policy.authorize_on_tenant(context, 'module:%s' % module_rule_name)
示例#12
0
 def test_authorize_on_tenant(self):
     test_rule = NonCallableMock()
     trove_policy.authorize_on_tenant(self.context, test_rule)
     self.mock_get_enforcer.assert_called_once_with()
     self.mock_enforcer.enforce.assert_called_once_with(
         test_rule, {'tenant': self.context.tenant},
         self.context.to_dict(),
         do_raise=True,
         exc=trove_exceptions.UnauthorizedRequest)
示例#13
0
 def authorize_module_action(cls, context, module_rule_name, module):
     """If a module is not owned by any particular tenant just check
     that the current tenant is allowed to perform the action.
     """
     if module.tenant_id is not None:
         policy.authorize_on_target(context, 'module:%s' % module_rule_name,
                                    {'tenant': module.tenant_id})
     else:
         policy.authorize_on_tenant(context, 'module:%s' % module_rule_name)
示例#14
0
文件: service.py 项目: wffeige/trove
 def index(self, req, tenant_id):
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'module:index')
     datastore = req.GET.get('datastore', '')
     if datastore and datastore.lower() != models.Modules.MATCH_ALL_NAME:
         ds, ds_ver = datastore_models.get_datastore_version(type=datastore)
         datastore = ds.id
     modules = models.Modules.load(context, datastore=datastore)
     view = views.ModulesView(modules)
     return wsgi.Result(view.data(), 200)
示例#15
0
 def test_authorize_on_tenant(self):
     test_rule = NonCallableMock()
     trove_policy.authorize_on_tenant(self.context, test_rule)
     self.mock_get_enforcer.assert_called_once_with()
     self.mock_enforcer.authorize.assert_called_once_with(
         test_rule, {'tenant': self.context.project_id},
         self.context.to_dict(),
         do_raise=True,
         exc=trove_exceptions.PolicyNotAuthorized,
         action=test_rule)
示例#16
0
 def show(self, req, tenant_id, id):
     """Return a single flavor."""
     context = req.environ[wsgi.CONTEXT_KEY]
     self._validate_flavor_id(id)
     flavor = models.Flavor(context=context, flavor_id=id)
     # Flavors do not bind to a particular tenant.
     # Only authorize the current tenant.
     policy.authorize_on_tenant(context, 'flavor:show')
     # Pass in the request to build accurate links.
     return wsgi.Result(views.FlavorView(flavor, req).data(), 200)
示例#17
0
 def index(self, req, tenant_id):
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'module:index')
     datastore = req.GET.get('datastore', '')
     if datastore and datastore.lower() != models.Modules.MATCH_ALL_NAME:
         ds, ds_ver = datastore_models.get_datastore_version(
             type=datastore)
         datastore = ds.id
     modules = models.Modules.load(context, datastore=datastore)
     view = views.ModulesView(modules)
     return wsgi.Result(view.data(), 200)
示例#18
0
    def index(self, req, tenant_id):
        """
        Return all absolute and rate limit information.
        """
        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'limits:index')
        quotas = QUOTAS.get_all_quotas_by_tenant(tenant_id)
        abs_limits = {k: v['hard_limit'] for k, v in quotas.items()}
        rate_limits = req.environ.get("trove.limits", [])

        return wsgi.Result(views.LimitViews(abs_limits,
                                            rate_limits).data(), 200)
示例#19
0
 def index(self, req, tenant_id):
     """
     Return all backups information for a tenant ID.
     """
     LOG.debug("Listing backups for tenant %s" % tenant_id)
     datastore = req.GET.get('datastore')
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'backup:index')
     backups, marker = Backup.list(context, datastore)
     view = views.BackupViews(backups)
     paged = pagination.SimplePaginatedDataView(req.url, 'backups', view,
                                                marker)
     return wsgi.Result(paged.data(), 200)
示例#20
0
 def index(self, req, tenant_id):
     """
     Return all backups information for a tenant ID.
     """
     LOG.debug("Listing backups for tenant %s", tenant_id)
     datastore = req.GET.get('datastore')
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'backup:index')
     backups, marker = Backup.list(context, datastore)
     view = views.BackupViews(backups)
     paged = pagination.SimplePaginatedDataView(req.url, 'backups', view,
                                                marker)
     return wsgi.Result(paged.data(), 200)
示例#21
0
 def index(self, req, tenant_id):
     """Return all instances."""
     LOG.info(_LI("Listing database instances for tenant '%s'"), tenant_id)
     LOG.debug("req : '%s'\n\n", req)
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'instance:index')
     clustered_q = req.GET.get('include_clustered', '').lower()
     include_clustered = clustered_q == 'true'
     servers, marker = models.Instances.load(context, include_clustered)
     view = views.InstancesView(servers, req=req)
     paged = pagination.SimplePaginatedDataView(req.url, 'instances', view,
                                                marker)
     return wsgi.Result(paged.data(), 200)
示例#22
0
 def index(self, req, tenant_id):
     """Return all instances."""
     LOG.info(_LI("Listing database instances for tenant '%s'"), tenant_id)
     LOG.debug("req : '%s'\n\n", req)
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'instance:index')
     clustered_q = req.GET.get('include_clustered', '').lower()
     include_clustered = clustered_q == 'true'
     servers, marker = models.Instances.load(context, include_clustered)
     view = views.InstancesView(servers, req=req)
     paged = pagination.SimplePaginatedDataView(req.url, 'instances', view,
                                                marker)
     return wsgi.Result(paged.data(), 200)
示例#23
0
    def delete(self, req, tenant_id):
        context = req.environ[wsgi.CONTEXT_KEY]
        instance_id = req.GET.get('instance_id', '')
        tenant_id = req.GET.get('project_id', context.project_id)
        LOG.info('Deleting backup strategies for tenant %s, instance_id=%s',
                 tenant_id, instance_id)

        if tenant_id != context.project_id and not context.is_admin:
            raise exception.TroveOperationAuthError(
                tenant_id=context.project_id)
        policy.authorize_on_tenant(context, 'backup_strategy:delete')

        BackupStrategy.delete(context, tenant_id, instance_id)

        return wsgi.Result(None, 202)
示例#24
0
    def create(self, req, body, tenant_id):
        LOG.info(
            "Creating or updating a backup strategy for tenant %s, "
            "body: %s", tenant_id, body)
        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'backup_strategy:create')
        data = body['backup_strategy']

        instance_id = data.get('instance_id', '')
        swift_container = data.get('swift_container')

        backup_strategy = BackupStrategy.create(context, instance_id,
                                                swift_container)
        return wsgi.Result(
            views.BackupStrategyView(backup_strategy).data(), 202)
示例#25
0
    def index(self, req, tenant_id):
        context = req.environ[wsgi.CONTEXT_KEY]
        instance_id = req.GET.get('instance_id')
        tenant_id = req.GET.get('project_id', context.project_id)
        LOG.info("Listing backup strateies for tenant %s", tenant_id)

        if tenant_id != context.project_id and not context.is_admin:
            raise exception.TroveOperationAuthError(
                tenant_id=context.project_id)
        policy.authorize_on_tenant(context, 'backup_strategy:index')

        result = BackupStrategy.list(context,
                                     tenant_id,
                                     instance_id=instance_id)
        view = views.BackupStrategiesView(result)
        return wsgi.Result(view.data(), 200)
示例#26
0
    def create(self, req, body, tenant_id):
        LOG.debug("req : '%s'\n\n" % req)
        LOG.debug("body : '%s'\n\n" % req)

        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'configuration:create')
        context.notification = notification.DBaaSConfigurationCreate(
            context, request=req)
        name = body['configuration']['name']
        description = body['configuration'].get('description')
        values = body['configuration']['values']

        msg = _("Creating configuration group on tenant "
                "%(tenant_id)s with name: %(cfg_name)s")
        LOG.info(msg % {"tenant_id": tenant_id, "cfg_name": name})

        datastore_args = body['configuration'].get('datastore', {})
        datastore, datastore_version = (
            ds_models.get_datastore_version(**datastore_args))

        with StartNotification(context, name=name, datastore=datastore.name,
                               datastore_version=datastore_version.name):
            configItems = []
            if values:
                # validate that the values passed in are permitted by the
                # operator.
                ConfigurationsController._validate_configuration(
                    body['configuration']['values'],
                    datastore_version,
                    models.DatastoreConfigurationParameters.load_parameters(
                        datastore_version.id))

                for k, v in values.items():
                    configItems.append(DBConfigurationParameter(
                        configuration_key=k,
                        configuration_value=v))

            cfg_group = models.Configuration.create(name, description,
                                                    tenant_id, datastore.id,
                                                    datastore_version.id)
            with EndNotification(context, configuration_id=cfg_group.id):
                cfg_group_items = models.Configuration.create_items(
                    cfg_group.id, values)

        view_data = views.DetailedConfigurationView(cfg_group,
                                                    cfg_group_items)
        return wsgi.Result(view_data.data(), 200)
示例#27
0
 def create(self, req, body, tenant_id):
     LOG.info(_("Creating a backup for tenant %s"), tenant_id)
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'backup:create')
     data = body['backup']
     instance = data['instance']
     name = data['name']
     desc = data.get('description')
     parent = data.get('parent_id')
     incremental = data.get('incremental')
     context.notification = notification.DBaaSBackupCreate(context,
                                                           request=req)
     with StartNotification(context, name=name, instance_id=instance,
                            description=desc, parent_id=parent):
         backup = Backup.create(context, instance, name, desc,
                                parent_id=parent, incremental=incremental)
     return wsgi.Result(views.BackupView(backup).data(), 202)
示例#28
0
 def index(self, req, tenant_id):
     """Return all flavors."""
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'flavor:index')
     flavors = models.Flavors(context=context)
     return wsgi.Result(views.FlavorsView(flavors, req).data(), 200)
示例#29
0
 def authorize_request(cls, req, rule_name):
     """Datastores are not owned by any particular tenant so we only check
     the current tenant is allowed to perform the action.
     """
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'datastore:%s' % rule_name)
示例#30
0
    def create(self, req, body, tenant_id):
        LOG.info("Creating a database instance for tenant '%s'", tenant_id)
        LOG.debug("req : '%s'\n\n", strutils.mask_password(req))
        LOG.debug("body : '%s'\n\n", strutils.mask_password(body))
        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'instance:create')
        context.notification = notification.DBaaSInstanceCreate(context,
                                                                request=req)

        name = body['instance']['name']
        slave_of_id = body['instance'].get('replica_of')
        replica_count = body['instance'].get('replica_count')
        flavor_ref = body['instance'].get('flavorRef')
        datastore_args = body['instance'].get('datastore', {})
        volume_info = body['instance'].get('volume', {})
        availability_zone = body['instance'].get('availability_zone')
        nics = body['instance'].get('nics', [])
        locality = body['instance'].get('locality')
        region_name = body['instance'].get(
            'region_name', CONF.service_credentials.region_name)
        access = body['instance'].get('access', None)

        if slave_of_id:
            if flavor_ref:
                msg = 'Cannot specify flavor when creating replicas.'
                raise exception.BadRequest(message=msg)
            if datastore_args:
                msg = 'Cannot specify datastore when creating replicas.'
                raise exception.BadRequest(message=msg)
            if volume_info:
                msg = 'Cannot specify volume when creating replicas.'
                raise exception.BadRequest(message=msg)
            if locality:
                msg = 'Cannot specify locality when creating replicas.'
                raise exception.BadRequest(message=msg)
            backup_model.verify_swift_auth_token(context)
        else:
            if replica_count and replica_count > 1:
                msg = (f"Replica count only valid when creating replicas. "
                       f"Cannot create {replica_count} instances.")
                raise exception.BadRequest(message=msg)

        flavor_id = utils.get_id_from_href(flavor_ref)

        if volume_info:
            volume_size = int(volume_info.get('size'))
            volume_type = volume_info.get('type')
        else:
            volume_size = None
            volume_type = None

        if slave_of_id:
            try:
                replica_source = models.DBInstance.find_by(context,
                                                           id=slave_of_id,
                                                           deleted=False)
                flavor_id = replica_source.flavor_id
            except exception.ModelNotFoundError:
                LOG.error(f"Cannot create a replica of {slave_of_id} as that "
                          f"instance could not be found.")
                raise exception.NotFound(uuid=slave_of_id)
            if replica_source.slave_of_id:
                raise exception.Forbidden(
                    f"Cannot create a replica of a replica {slave_of_id}")

            datastore_version = ds_models.DatastoreVersion.load_by_uuid(
                replica_source.datastore_version_id)
            datastore = ds_models.Datastore.load(
                datastore_version.datastore_id)
        else:
            datastore, datastore_version = ds_models.get_datastore_version(
                **datastore_args)

        # If only image_tags is configured in the datastore version, get
        # the image ID using the tags.
        glance_client = clients.create_glance_client(context)
        image_id = common_glance.get_image_id(glance_client,
                                              datastore_version.image_id,
                                              datastore_version.image_tags)
        LOG.info(f'Using image {image_id} for creating instance')

        databases = populate_validated_databases(body['instance'].get(
            'databases', []))
        database_names = [database.get('_name', '') for database in databases]
        users = None
        try:
            users = populate_users(body['instance'].get('users', []),
                                   database_names)
        except ValueError as ve:
            raise exception.BadRequest(message=str(ve))
        if slave_of_id and (databases or users):
            raise exception.ReplicaCreateWithUsersDatabasesError()

        configuration = self._configuration_parse(context, body)
        modules = body['instance'].get('modules')

        # The following operations have their own API calls.
        # We need to make sure the same policies are enforced when
        # creating an instance.
        # i.e. if attaching configuration group to an existing instance is not
        # allowed, it should not be possible to create a new instance with the
        # group attached either
        if configuration:
            policy.authorize_on_tenant(context, 'instance:update')
        if modules:
            policy.authorize_on_tenant(context, 'instance:module_apply')
        if users:
            policy.authorize_on_tenant(context,
                                       'instance:extension:user:create')
        if databases:
            policy.authorize_on_tenant(context,
                                       'instance:extension:database:create')

        if 'restorePoint' in body['instance']:
            backupRef = body['instance']['restorePoint']['backupRef']
            backup_id = utils.get_id_from_href(backupRef)
        else:
            backup_id = None

        # Only 1 nic is allowed as defined in API jsonschema.
        # Use list just for backward compatibility.
        if len(nics) > 0:
            nic = nics[0]
            LOG.info('Checking user provided instance network %s', nic)
            if slave_of_id and nic.get('ip_address'):
                msg = "Cannot specify IP address when creating replicas."
                raise exception.BadRequest(message=msg)
            self._check_nic(context, nic)

        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(message=locality_domain_msg)

        instance = models.Instance.create(context,
                                          name,
                                          flavor_id,
                                          image_id,
                                          databases,
                                          users,
                                          datastore,
                                          datastore_version,
                                          volume_size,
                                          backup_id,
                                          availability_zone,
                                          nics,
                                          configuration,
                                          slave_of_id,
                                          replica_count=replica_count,
                                          volume_type=volume_type,
                                          modules=modules,
                                          locality=locality,
                                          region_name=region_name,
                                          access=access)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
示例#31
0
 def authorize_request(cls, req, rule_name):
     """Datastores are not owned by any particular tenant so we only check
     the current tenant is allowed to perform the action.
     """
     context = req.environ[wsgi.CONTEXT_KEY]
     policy.authorize_on_tenant(context, 'datastore:%s' % rule_name)
示例#32
0
文件: service.py 项目: hejianle/trove
    def create(self, req, body, tenant_id):
        # TODO(hub-cap): turn this into middleware
        LOG.info("Creating a database instance for tenant '%s'",
                 tenant_id)
        LOG.debug("req : '%s'\n\n", strutils.mask_password(req))
        LOG.debug("body : '%s'\n\n", strutils.mask_password(body))
        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'instance:create')
        context.notification = notification.DBaaSInstanceCreate(context,
                                                                request=req)
        datastore_args = body['instance'].get('datastore', {})
        datastore, datastore_version = (
            datastore_models.get_datastore_version(**datastore_args))
        image_id = datastore_version.image_id
        name = body['instance']['name']
        flavor_ref = body['instance']['flavorRef']
        flavor_id = utils.get_id_from_href(flavor_ref)

        configuration = self._configuration_parse(context, body)
        databases = populate_validated_databases(
            body['instance'].get('databases', []))
        database_names = [database.get('_name', '') for database in databases]
        users = None
        try:
            users = populate_users(body['instance'].get('users', []),
                                   database_names)
        except ValueError as ve:
            raise exception.BadRequest(message=ve)

        modules = body['instance'].get('modules')

        # The following operations have their own API calls.
        # We need to make sure the same policies are enforced when
        # creating an instance.
        # i.e. if attaching configuration group to an existing instance is not
        # allowed, it should not be possible to create a new instance with the
        # group attached either
        if configuration:
            policy.authorize_on_tenant(context, 'instance:update')
        if modules:
            policy.authorize_on_tenant(context, 'instance:module_apply')
        if users:
            policy.authorize_on_tenant(
                context, 'instance:extension:user:create')
        if databases:
            policy.authorize_on_tenant(
                context, 'instance:extension:database:create')

        if 'volume' in body['instance']:
            volume_info = body['instance']['volume']
            volume_size = int(volume_info['size'])
            volume_type = volume_info.get('type')
        else:
            volume_size = None
            volume_type = None

        if 'restorePoint' in body['instance']:
            backupRef = body['instance']['restorePoint']['backupRef']
            backup_id = utils.get_id_from_href(backupRef)
        else:
            backup_id = None

        availability_zone = body['instance'].get('availability_zone')
        nics = body['instance'].get('nics', [])

        slave_of_id = body['instance'].get('replica_of',
                                           # also check for older name
                                           body['instance'].get('slave_of'))
        replica_count = body['instance'].get('replica_count')
        locality = body['instance'].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(message=locality_domain_msg)
            if slave_of_id:
                dupe_locality_msg = (
                    'Cannot specify locality when adding replicas to existing '
                    'master.')
                raise exception.BadRequest(message=dupe_locality_msg)

        region_name = body['instance'].get(
            'region_name', CONF.service_credentials.region_name
        )
        access = body['instance'].get('access', None)

        instance = models.Instance.create(context, name, flavor_id,
                                          image_id, databases, users,
                                          datastore, datastore_version,
                                          volume_size, backup_id,
                                          availability_zone, nics,
                                          configuration, slave_of_id,
                                          replica_count=replica_count,
                                          volume_type=volume_type,
                                          modules=modules,
                                          locality=locality,
                                          region_name=region_name,
                                          access=access)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
示例#33
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]
        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)
示例#34
0
    def create(self, req, body, tenant_id):
        # TODO(hub-cap): turn this into middleware
        LOG.info(_LI("Creating a database instance for tenant '%s'"),
                 tenant_id)
        LOG.debug("req : '%s'\n\n", strutils.mask_password(req))
        LOG.debug("body : '%s'\n\n", strutils.mask_password(body))
        context = req.environ[wsgi.CONTEXT_KEY]
        policy.authorize_on_tenant(context, 'instance:create')
        context.notification = notification.DBaaSInstanceCreate(context,
                                                                request=req)
        datastore_args = body['instance'].get('datastore', {})
        datastore, datastore_version = (
            datastore_models.get_datastore_version(**datastore_args))
        image_id = datastore_version.image_id

        name = body['instance']['name']
        flavor_ref = body['instance']['flavorRef']
        flavor_id = utils.get_id_from_href(flavor_ref)

        configuration = self._configuration_parse(context, body)
        users, databases = self._parse_users_and_databases(
            datastore_version.manager, body)

        modules = body['instance'].get('modules')

        # The following operations have their own API calls.
        # We need to make sure the same policies are enforced when
        # creating an instance.
        # i.e. if attaching configuration group to an existing instance is not
        # allowed, it should not be possible to create a new instance with the
        # group attached either
        if configuration:
            policy.authorize_on_tenant(context, 'instance:update')
        if modules:
            policy.authorize_on_tenant(context, 'instance:module_apply')
        if users:
            policy.authorize_on_tenant(
                context, 'instance:extension:user:create')
        if databases:
            policy.authorize_on_tenant(
                context, 'instance:extension:database:create')

        modules = body['instance'].get('modules')

        # The following operations have their own API calls.
        # We need to make sure the same policies are enforced when
        # creating an instance.
        # i.e. if attaching configuration group to an existing instance is not
        # allowed, it should not be possible to create a new instance with the
        # group attached either
        if configuration:
            policy.authorize_on_tenant(context, 'instance:update')
        if modules:
            policy.authorize_on_tenant(context, 'instance:module_apply')
        if users:
            policy.authorize_on_tenant(
                context, 'instance:extension:user:create')
        if databases:
            policy.authorize_on_tenant(
                context, 'instance:extension:database:create')

        if 'volume' in body['instance']:
            volume_info = body['instance']['volume']
            volume_size = int(volume_info['size'])
            volume_type = volume_info.get('type')
        else:
            volume_size = None
            volume_type = None

        if 'restorePoint' in body['instance']:
            backupRef = body['instance']['restorePoint']['backupRef']
            backup_id = utils.get_id_from_href(backupRef)
        else:
            backup_id = None

        availability_zone = body['instance'].get('availability_zone')
        nics = body['instance'].get('nics')

        slave_of_id = body['instance'].get('replica_of',
                                           # also check for older name
                                           body['instance'].get('slave_of'))
        replica_count = body['instance'].get('replica_count')
        locality = body['instance'].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)
            if slave_of_id:
                dupe_locality_msg = (
                    'Cannot specify locality when adding replicas to existing '
                    'master.')
                raise exception.BadRequest(msg=dupe_locality_msg)
        region_name = body['instance'].get('region_name', CONF.os_region_name)

        instance = models.Instance.create(context, name, flavor_id,
                                          image_id, databases, users,
                                          datastore, datastore_version,
                                          volume_size, backup_id,
                                          availability_zone, nics,
                                          configuration, slave_of_id,
                                          replica_count=replica_count,
                                          volume_type=volume_type,
                                          modules=modules,
                                          locality=locality,
                                          region_name=region_name)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
示例#35
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]
        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)