Example #1
0
    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.info(logging.mask_password(_("req : '%s'\n\n") % req))
        LOG.info(logging.mask_password(_("body : '%s'\n\n") % body))
        context = req.environ[wsgi.CONTEXT_KEY]
        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(msg=ve)

        if 'volume' in body['instance']:
            volume_size = int(body['instance']['volume']['size'])
        else:
            volume_size = None

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

        if 'availability_zone' in body['instance']:
            availability_zone = body['instance']['availability_zone']
        else:
            availability_zone = None

        if 'nics' in body['instance']:
            nics = body['instance']['nics']
        else:
            nics = None

        instance = models.Instance.create(context, name, flavor_id,
                                          image_id, databases, users,
                                          datastore, datastore_version,
                                          volume_size, backup_id,
                                          availability_zone, nics,
                                          configuration)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
Example #2
0
    def show(self, req, tenant_id, id):
        """Return a single instance."""
        LOG.info(_("req : '%s'\n\n") % req)
        LOG.info(_("Showing a database instance for tenant '%s'") % tenant_id)
        LOG.info(_("id : '%s'\n\n") % id)

        context = req.environ[wsgi.CONTEXT_KEY]
        server = models.load_instance_with_guest(models.DetailInstance,
                                                 context, id)
        return wsgi.Result(views.InstanceDetailView(server,
                                                    req=req).data(), 200)
Example #3
0
    def show(self, req, tenant_id, id):
        """Return a single instance."""
        LOG.info(_LI("Showing database instance '%(instance_id)s' for tenant "
                     "'%(tenant_id)s'"),
                 {'instance_id': id, 'tenant_id': tenant_id})
        LOG.debug("req : '%s'\n\n", req)

        context = req.environ[wsgi.CONTEXT_KEY]
        server = models.load_instance_with_info(models.DetailInstance,
                                                context, id)
        return wsgi.Result(views.InstanceDetailView(server,
                                                    req=req).data(), 200)
Example #4
0
    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.info(_("req : '%s'\n\n") % req)
        LOG.info(_("body : '%s'\n\n") % body)
        context = req.environ[wsgi.CONTEXT_KEY]
        # Set the service type to mysql if its not in the request
        service_type = (body['instance'].get('service_type')
                        or CONF.service_type)
        service = models.ServiceImage.find_by(service_name=service_type)
        image_id = service['image_id']
        name = body['instance']['name']
        flavor_ref = body['instance']['flavorRef']
        flavor_id = utils.get_id_from_href(flavor_ref)
        databases = populate_validated_databases(body['instance'].get(
            'databases', []))
        users = None
        try:
            users = populate_users(body['instance'].get('users', []))
        except ValueError as ve:
            raise exception.BadRequest(msg=ve)

        if 'volume' in body['instance']:
            volume_size = int(body['instance']['volume']['size'])
        else:
            volume_size = None

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

        instance = models.Instance.create(context, name, flavor_id, image_id,
                                          databases, users, service_type,
                                          volume_size, backup_id)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
Example #5
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]
        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(msg=ve)

        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')
        modules = body['instance'].get('modules')
        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)

        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)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
Example #6
0
    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)
Example #7
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)