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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)