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