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

        if 'slave_of' in body['instance']:
            slave_of_id = body['instance']['slave_of']
        else:
            slave_of_id = 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)

        view = views.InstanceDetailView(instance, req=req)
        return wsgi.Result(view.data(), 200)
Example #2
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 #3
0
 def create(self, req, body, tenant_id, instance_id):
     """Creates a set of users."""
     LOG.info(_("Creating users for instance '%s'") % instance_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]
     users = body['users']
     try:
         model_users = populate_users(users)
         models.User.create(context, instance_id, model_users)
     except (ValueError, AttributeError) as e:
         raise exception.BadRequest(msg=str(e))
     return wsgi.Result(None, 202)
Example #4
0
 def create(self, req, body, tenant_id, instance_id):
     """Creates a set of users"""
     LOG.info(_("Creating users for instance '%s'") % instance_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]
     users = body['users']
     try:
         model_users = populate_users(users)
         models.User.create(context, instance_id, model_users)
     except (ValueError, AttributeError) as e:
         raise exception.BadRequest(msg=str(e))
     return wsgi.Result(None, 202)
Example #5
0
 def update_all(self, req, body, tenant_id, instance_id):
     """Change the password of one or more users."""
     LOG.info(_("Updating user passwords for instance '%s'") % instance_id)
     LOG.info(logging.mask_password(_("req : '%s'\n\n") % req))
     context = req.environ[wsgi.CONTEXT_KEY]
     users = body['users']
     model_users = []
     for user in users:
         try:
             mu = guest_models.MySQLUser()
             mu.name = user['name']
             mu.host = user.get('host')
             mu.password = user['password']
             found_user = models.User.load(context, instance_id, mu.name,
                                           mu.host)
             if not found_user:
                 user_and_host = mu.name
                 if mu.host:
                     user_and_host += '@' + mu.host
                 raise exception.UserNotFound(uuid=user_and_host)
             model_users.append(mu)
         except (ValueError, AttributeError) as e:
             raise exception.BadRequest(msg=str(e))
     models.User.change_password(context, instance_id, model_users)
     return wsgi.Result(None, 202)
Example #6
0
 def update_all(self, req, body, tenant_id, instance_id):
     """Change the password of one or more users."""
     LOG.info(_("Updating user passwords for instance '%s'") % instance_id)
     LOG.info(logging.mask_password(_("req : '%s'\n\n") % req))
     context = req.environ[wsgi.CONTEXT_KEY]
     users = body['users']
     model_users = []
     for user in users:
         try:
             mu = guest_models.MySQLUser()
             mu.name = user['name']
             mu.host = user.get('host')
             mu.password = user['password']
             found_user = models.User.load(context, instance_id,
                                           mu.name, mu.host)
             if not found_user:
                 user_and_host = mu.name
                 if mu.host:
                     user_and_host += '@' + mu.host
                 raise exception.UserNotFound(uuid=user_and_host)
             model_users.append(mu)
         except (ValueError, AttributeError) as e:
             raise exception.BadRequest(msg=str(e))
     models.User.change_password(context, instance_id, model_users)
     return wsgi.Result(None, 202)
Example #7
0
    def edit(self, req, id, body, tenant_id):
        """
        Updates the instance to set or unset one or more attributes.
        """
        LOG.info(_("Editing instance for tenant id %s.") % tenant_id)
        LOG.debug(logging.mask_password("req: %s"), req)
        LOG.debug(logging.mask_password("body: %s"), body)
        context = req.environ[wsgi.CONTEXT_KEY]

        instance = models.Instance.load(context, id)

        if 'slave_of' in body['instance']:
            LOG.debug("Detaching replica from source.")
            instance.detach_replica()

        return wsgi.Result(None, 202)
Example #8
0
    def edit(self, req, id, body, tenant_id):
        """
        Updates the instance to set or unset one or more attributes.
        """
        LOG.info(_("Editing instance for tenant id %s.") % tenant_id)
        LOG.debug(logging.mask_password("req: %s"), req)
        LOG.debug(logging.mask_password("body: %s"), body)
        context = req.environ[wsgi.CONTEXT_KEY]

        instance = models.Instance.load(context, id)

        if 'slave_of' in body['instance']:
            LOG.debug("Detaching replica from source.")
            instance.detach_replica()

        return wsgi.Result(None, 202)
Example #9
0
 def authorize(self, request, tenant_id, roles):
     match_for_tenant = self.tenant_scoped_url.match(request.path_info)
     if (match_for_tenant and
             tenant_id == match_for_tenant.group('tenant_id')):
         LOG.debug(logging.mask_password(
                   _("Authorized tenant '%(tenant_id)s' request: "
                     "%(request)s") %
                   {'tenant_id': tenant_id, 'request': request}))
         return True
     msg = _("User with tenant id %s cannot access this resource")
     LOG.debug(msg % tenant_id)
     raise webob.exc.HTTPForbidden(msg)
Example #10
0
    def edit(self, req, id, body, tenant_id):
        """
        Updates the instance to set or unset one or more attributes.
        """
        LOG.info(_LI("Editing instance for tenant id %s."), tenant_id)
        LOG.debug(logging.mask_password("req: %s"), req)
        LOG.debug(logging.mask_password("body: %s"), body)
        context = req.environ[wsgi.CONTEXT_KEY]

        instance = models.Instance.load(context, id)

        if 'slave_of' in body['instance']:
            LOG.debug("Detaching replica from source.")
            instance.detach_replica()

        # If configuration is set, then we will update the instance to
        # use the new configuration. If configuration is empty, we
        # want to disassociate the instance from the configuration
        # group and remove the active overrides file.
        # If instance name is set, then we will update the instance name.

        edit_args = {}
        if 'configuration' in body['instance']:
            configuration_id = self._configuration_parse(context, body)
            if configuration_id:
                instance.assign_configuration(configuration_id)
            else:
                instance.unassign_configuration()
            edit_args['configuration_id'] = configuration_id

        if 'name' in body['instance']:
            edit_args['name'] = body['instance']['name']

        if edit_args:
            instance.update_db(**edit_args)

        return wsgi.Result(None, 202)
Example #11
0
    def edit(self, req, id, body, tenant_id):
        """
        Updates the instance to set or unset one or more attributes.
        """
        LOG.info(_LI("Editing instance for tenant id %s."), tenant_id)
        LOG.debug(logging.mask_password("req: %s"), req)
        LOG.debug(logging.mask_password("body: %s"), body)
        context = req.environ[wsgi.CONTEXT_KEY]

        instance = models.Instance.load(context, id)

        if 'slave_of' in body['instance']:
            LOG.debug("Detaching replica from source.")
            instance.detach_replica()

        # If configuration is set, then we will update the instance to
        # use the new configuration. If configuration is empty, we
        # want to disassociate the instance from the configuration
        # group and remove the active overrides file.
        # If instance name is set, then we will update the instance name.

        edit_args = {}
        if 'configuration' in body['instance']:
            configuration_id = self._configuration_parse(context, body)
            if configuration_id:
                instance.assign_configuration(configuration_id)
            else:
                instance.unassign_configuration()
            edit_args['configuration_id'] = configuration_id

        if 'name' in body['instance']:
            edit_args['name'] = body['instance']['name']

        if edit_args:
            instance.update_db(**edit_args)

        return wsgi.Result(None, 202)
Example #12
0
 def authorize(self, request, tenant_id, roles):
     match_for_tenant = self.tenant_scoped_url.match(request.path_info)
     if (match_for_tenant
             and tenant_id == match_for_tenant.group('tenant_id')):
         LOG.debug(
             logging.mask_password(
                 _("Authorized tenant '%(tenant_id)s' request: "
                   "%(request)s") % {
                       'tenant_id': tenant_id,
                       'request': request
                   }))
         return True
     msg = _("User with tenant id %s cannot access this resource")
     LOG.debug(msg % tenant_id)
     raise webob.exc.HTTPForbidden(msg)
Example #13
0
 def update(self, req, body, tenant_id, instance_id, id):
     """Change attributes for one user."""
     LOG.info(_("Updating user attributes for instance '%s'") % instance_id)
     LOG.info(logging.mask_password(_("req : '%s'\n\n") % req))
     context = req.environ[wsgi.CONTEXT_KEY]
     id = correct_id_with_req(id, req)
     username, hostname = unquote_user_host(id)
     user = None
     user_attrs = body["user"]
     try:
         user = models.User.load(context, instance_id, username, hostname)
     except (ValueError, AttributeError) as e:
         raise exception.BadRequest(msg=str(e))
     if not user:
         raise exception.UserNotFound(uuid=id)
     try:
         models.User.update_attributes(context, instance_id, username, hostname, user_attrs)
     except (ValueError, AttributeError) as e:
         raise exception.BadRequest(msg=str(e))
     return wsgi.Result(None, 202)
Example #14
0
 def update(self, req, body, tenant_id, instance_id, id):
     """Change attributes for one user."""
     LOG.info(_("Updating user attributes for instance '%s'") % instance_id)
     LOG.info(logging.mask_password(_("req : '%s'\n\n") % req))
     context = req.environ[wsgi.CONTEXT_KEY]
     id = correct_id_with_req(id, req)
     username, hostname = unquote_user_host(id)
     user = None
     user_attrs = body['user']
     try:
         user = models.User.load(context, instance_id, username, hostname)
     except (ValueError, AttributeError) as e:
         raise exception.BadRequest(msg=str(e))
     if not user:
         raise exception.UserNotFound(uuid=id)
     try:
         models.User.update_attributes(context, instance_id, username,
                                       hostname, user_attrs)
     except (ValueError, AttributeError) as e:
         raise exception.BadRequest(msg=str(e))
     return wsgi.Result(None, 202)
Example #15
0
def execute(*cmd, **kwargs):
    """Helper method to shell out and execute a command through subprocess.

    Allows optional retry.

    :param cmd:             Passed to subprocess.Popen.
    :type cmd:              string
    :param process_input:   Send to opened process.
    :type process_input:    string
    :param env_variables:   Environment variables and their values that
                            will be set for the process.
    :type env_variables:    dict
    :param check_exit_code: Single bool, int, or list of allowed exit
                            codes.  Defaults to [0].  Raise
                            :class:`ProcessExecutionError` unless
                            program exits with one of these code.
    :type check_exit_code:  boolean, int, or [int]
    :param delay_on_retry:  True | False. Defaults to True. If set to True,
                            wait a short amount of time before retrying.
    :type delay_on_retry:   boolean
    :param attempts:        How many times to retry cmd.
    :type attempts:         int
    :param run_as_root:     True | False. Defaults to False. If set to True,
                            the command is prefixed by the command specified
                            in the root_helper kwarg.
    :type run_as_root:      boolean
    :param root_helper:     command to prefix to commands called with
                            run_as_root=True
    :type root_helper:      string
    :param shell:           whether or not there should be a shell used to
                            execute this command. Defaults to false.
    :type shell:            boolean
    :param loglevel:        log level for execute commands.
    :type loglevel:         int.  (Should be stdlib_logging.DEBUG or
                            stdlib_logging.INFO)
    :returns:               (stdout, stderr) from process execution
    :raises:                :class:`UnknownArgumentError` on
                            receiving unknown arguments
    :raises:                :class:`ProcessExecutionError`
    """

    process_input = kwargs.pop('process_input', None)
    env_variables = kwargs.pop('env_variables', None)
    check_exit_code = kwargs.pop('check_exit_code', [0])
    ignore_exit_code = False
    delay_on_retry = kwargs.pop('delay_on_retry', True)
    attempts = kwargs.pop('attempts', 1)
    run_as_root = kwargs.pop('run_as_root', False)
    root_helper = kwargs.pop('root_helper', '')
    shell = kwargs.pop('shell', False)
    loglevel = kwargs.pop('loglevel', stdlib_logging.DEBUG)

    if isinstance(check_exit_code, bool):
        ignore_exit_code = not check_exit_code
        check_exit_code = [0]
    elif isinstance(check_exit_code, int):
        check_exit_code = [check_exit_code]

    if kwargs:
        raise UnknownArgumentError(_('Got unknown keyword args '
                                     'to utils.execute: %r') % kwargs)

    if run_as_root and hasattr(os, 'geteuid') and os.geteuid() != 0:
        if not root_helper:
            raise NoRootWrapSpecified(
                message=_('Command requested root, but did not '
                          'specify a root helper.'))
        cmd = shlex.split(root_helper) + list(cmd)

    cmd = map(str, cmd)

    while attempts > 0:
        attempts -= 1
        try:
            LOG.log(loglevel, 'Running cmd (subprocess): %s',
                    ' '.join(logging.mask_password(cmd)))
            _PIPE = subprocess.PIPE  # pylint: disable=E1101

            if os.name == 'nt':
                preexec_fn = None
                close_fds = False
            else:
                preexec_fn = _subprocess_setup
                close_fds = True

            obj = subprocess.Popen(cmd,
                                   stdin=_PIPE,
                                   stdout=_PIPE,
                                   stderr=_PIPE,
                                   close_fds=close_fds,
                                   preexec_fn=preexec_fn,
                                   shell=shell,
                                   env=env_variables)
            result = None
            for _i in six.moves.range(20):
                # NOTE(russellb) 20 is an arbitrary number of retries to
                # prevent any chance of looping forever here.
                try:
                    if process_input is not None:
                        result = obj.communicate(process_input)
                    else:
                        result = obj.communicate()
                except OSError as e:
                    if e.errno in (errno.EAGAIN, errno.EINTR):
                        continue
                    raise
                break
            obj.stdin.close()  # pylint: disable=E1101
            _returncode = obj.returncode  # pylint: disable=E1101
            LOG.log(loglevel, 'Result was %s' % _returncode)
            if not ignore_exit_code and _returncode not in check_exit_code:
                (stdout, stderr) = result
                raise ProcessExecutionError(exit_code=_returncode,
                                            stdout=stdout,
                                            stderr=stderr,
                                            cmd=' '.join(cmd))
            return result
        except ProcessExecutionError:
            if not attempts:
                raise
            else:
                LOG.log(loglevel, '%r failed. Retrying.', cmd)
                if delay_on_retry:
                    greenthread.sleep(random.randint(20, 200) / 100.0)
        finally:
            # NOTE(termie): this appears to be necessary to let the subprocess
            #               call clean something up in between calls, without
            #               it two execute calls in a row hangs the second one
            greenthread.sleep(0)
Example #16
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)