Пример #1
0
    def update(self, request, environment_id, body):
        LOG.debug('Environments:Update <Id: {0}, '
                  'Body: {1}>'.format(environment_id, body))
        target = {"environment_id": environment_id}
        policy.check('update_environment', request.context, target)

        session = db_session.get_session()
        environment = session.query(models.Environment).get(environment_id)

        if environment is None:
            LOG.info(_('Environment <EnvId {0}> is not '
                       'found').format(environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(_('User is not authorized to access '
                       'this tenant resources.'))
            raise exc.HTTPUnauthorized

        LOG.debug('ENV NAME: {0}>'.format(body['name']))
        if VALID_NAME_REGEX.match(str(body['name'])):
            environment.update(body)
            environment.save(session)
        else:
            msg = _('Environment name must contain only alphanumeric '
                    'or "_-." characters, must start with alpha')
            LOG.exception(msg)
            raise exc.HTTPClientError(msg)

        return environment.to_dict()
Пример #2
0
    def _validate_change(self, change):
        change_path = change['path'][0]
        change_op = change['op']
        allowed_methods = self.allowed_operations.get(change_path)

        if not allowed_methods:
            msg = _("Attribute '{0}' is invalid").format(change_path)
            raise webob.exc.HTTPForbidden(explanation=unicode(msg))

        if change_op not in allowed_methods:
            msg = _("Method '{method}' is not allowed for a path with name "
                    "'{name}'. Allowed operations are: '{ops}'").format(
                    method=change_op,
                    name=change_path,
                    ops=', '.join(allowed_methods))

            raise webob.exc.HTTPForbidden(explanation=unicode(msg))

        property_to_update = {change_path: change['value']}

        try:
            jsonschema.validate(property_to_update, schemas.PKG_UPDATE_SCHEMA)
        except jsonschema.ValidationError as e:
            LOG.exception(e)
            raise webob.exc.HTTPBadRequest(explanation=e.message)
Пример #3
0
    def configure(self, request, environment_id):
        LOG.debug('Session:Configure <EnvId: {0}>'.format(environment_id))

        unit = db_session.get_session()
        environment = unit.query(models.Environment).get(environment_id)

        if environment is None:
            msg = _('Environment <EnvId {0}>'
                    ' is not found').format(environment_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if environment.tenant_id != request.context.tenant:
            msg = _('User is not authorized to access '
                    'this tenant resources.')
            LOG.error(msg)
            raise exc.HTTPUnauthorized(explanation=msg)

        # no new session can be opened if environment has deploying status
        env_status = envs.EnvironmentServices.get_status(environment_id)
        if env_status in (states.EnvironmentStatus.DEPLOYING,
                          states.EnvironmentStatus.DELETING):
            msg = _('Could not open session for environment <EnvId: {0}>,'
                    'environment has deploying status.').format(environment_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        user_id = request.context.user
        session = sessions.SessionServices.create(environment_id, user_id)

        return session.to_dict()
Пример #4
0
    def __inner(self, request, *args, **kwargs):
        if hasattr(request, 'context') and not request.context.session:
            LOG.info(_('Session is required for this call'))
            raise exc.HTTPForbidden()

        session_id = request.context.session

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        if session is None:
            LOG.info(_('Session <SessionId {0}> '
                       'is not found').format(session_id))
            raise exc.HTTPForbidden()

        if not sessions.SessionServices.validate(session):
            LOG.info(_('Session <SessionId {0}> '
                       'is invalid').format(session_id))
            raise exc.HTTPForbidden()

        if session.state == states.SessionState.DEPLOYING:
            LOG.info(_('Session <SessionId {0}> is already in '
                       'deployment state').format(session_id))
            raise exc.HTTPForbidden()
        return func(self, request, *args, **kwargs)
Пример #5
0
    def delete(self, request, environment_id, session_id):
        LOG.debug('Session:Delete <SessionId: {0}>'.format(session_id))

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        self._check_session(environment_id, session, session_id)

        user_id = request.context.user
        if session.user_id != user_id:
            msg = _('User <UserId {0}> is not authorized to access session'
                    '<SessionId {1}>.').format(user_id, session_id)
            LOG.error(msg)
            raise exc.HTTPUnauthorized(explanation=msg)

        if session.state == states.SessionState.DEPLOYING:
            msg = _('Session <SessionId: {0}> is in deploying state and '
                    'could not be deleted').format(session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        with unit.begin():
            unit.delete(session)

        return None
Пример #6
0
def ssh_execute(ssh,
                cmd,
                process_input=None,
                addl_env=None,
                check_exit_code=True):
    LOG.debug('Running cmd (SSH): %s', cmd)
    if addl_env:
        raise InvalidArgumentError(_('Environment not supported over SSH'))

    if process_input:
        # This is (probably) fixable if we need it...
        raise InvalidArgumentError(_('process_input not supported over SSH'))

    stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd)
    channel = stdout_stream.channel

    # NOTE(justinsb): This seems suspicious...
    # ...other SSH clients have buffering issues with this approach
    stdout = stdout_stream.read()
    stderr = stderr_stream.read()
    stdin_stream.close()

    exit_status = channel.recv_exit_status()

    # exit_status == -1 if no exit code was returned
    if exit_status != -1:
        LOG.debug('Result was %s' % exit_status)
        if check_exit_code and exit_status != 0:
            raise ProcessExecutionError(exit_code=exit_status,
                                        stdout=stdout,
                                        stderr=stderr,
                                        cmd=cmd)

    return (stdout, stderr)
Пример #7
0
    def show(self, request, environment_id, session_id):
        LOG.debug("Session:Show <SessionId: {0}>".format(session_id))

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        if session is None:
            LOG.error(_("Session <SessionId {0}> " "is not found").format(session_id))
            raise exc.HTTPNotFound()

        if session.environment_id != environment_id:
            LOG.error(
                _("Session <SessionId {0}> is not tied with Environment " "<EnvId {1}>").format(
                    session_id, environment_id
                )
            )
            raise exc.HTTPNotFound()

        user_id = request.context.user
        if session.user_id != user_id:
            LOG.error(
                _("User <UserId {0}> is not authorized to access session" "<SessionId {1}>.").format(
                    user_id, session_id
                )
            )
            raise exc.HTTPUnauthorized()

        if not sessions.SessionServices.validate(session):
            LOG.error(_("Session <SessionId {0}> " "is invalid").format(session_id))
            raise exc.HTTPForbidden()

        return session.to_dict()
Пример #8
0
    def __inner(self, request, *args, **kwargs):
        if hasattr(request, 'context') and not request.context.session:
            LOG.info(_('Session is required for this call'))
            raise exc.HTTPForbidden()

        session_id = request.context.session

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        if session is None:
            LOG.info(
                _('Session <SessionId {0}> '
                  'is not found').format(session_id))
            raise exc.HTTPForbidden()

        if not sessions.SessionServices.validate(session):
            LOG.info(
                _('Session <SessionId {0}> '
                  'is invalid').format(session_id))
            raise exc.HTTPForbidden()

        if session.state == states.SessionState.DEPLOYING:
            LOG.info(
                _('Session <SessionId {0}> is already in '
                  'deployment state').format(session_id))
            raise exc.HTTPForbidden()
        return func(self, request, *args, **kwargs)
Пример #9
0
def ssh_execute(ssh, cmd, process_input=None,
                addl_env=None, check_exit_code=True):
    LOG.debug('Running cmd (SSH): %s', cmd)
    if addl_env:
        raise InvalidArgumentError(_('Environment not supported over SSH'))

    if process_input:
        # This is (probably) fixable if we need it...
        raise InvalidArgumentError(_('process_input not supported over SSH'))

    stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd)
    channel = stdout_stream.channel

    # NOTE(justinsb): This seems suspicious...
    # ...other SSH clients have buffering issues with this approach
    stdout = stdout_stream.read()
    stderr = stderr_stream.read()
    stdin_stream.close()

    exit_status = channel.recv_exit_status()

    # exit_status == -1 if no exit code was returned
    if exit_status != -1:
        LOG.debug('Result was %s' % exit_status)
        if check_exit_code and exit_status != 0:
            raise ProcessExecutionError(exit_code=exit_status,
                                        stdout=stdout,
                                        stderr=stderr,
                                        cmd=cmd)

    return (stdout, stderr)
Пример #10
0
    def configure(self, request, environment_id):
        LOG.debug('Session:Configure <EnvId: {0}>'.format(environment_id))

        unit = db_session.get_session()
        environment = unit.query(models.Environment).get(environment_id)

        if environment is None:
            msg = _('Environment <EnvId {0}>'
                    ' is not found').format(environment_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if environment.tenant_id != request.context.tenant:
            msg = _('User is not authorized to access '
                    'this tenant resources.')
            LOG.error(msg)
            raise exc.HTTPUnauthorized(explanation=msg)

        # no new session can be opened if environment has deploying status
        env_status = envs.EnvironmentServices.get_status(environment_id)
        if env_status in (envs.EnvironmentStatus.DEPLOYING,
                          envs.EnvironmentStatus.DELETING):
            msg = _('Could not open session for environment <EnvId: {0}>,'
                    'environment has deploying status.').format(environment_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        user_id = request.context.user
        session = sessions.SessionServices.create(environment_id, user_id)

        return session.to_dict()
Пример #11
0
    def update(self, request, environment_id, body):
        LOG.debug('Environments:Update <Id: {0}, '
                  'Body: {1}>'.format(environment_id, body))
        target = {"environment_id": environment_id}
        policy.check('update_environment', request.context, target)

        session = db_session.get_session()
        environment = session.query(models.Environment).get(environment_id)

        if environment is None:
            LOG.info(
                _('Environment <EnvId {0}> is not '
                  'found').format(environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(
                _('User is not authorized to access '
                  'this tenant resources.'))
            raise exc.HTTPUnauthorized

        LOG.debug('ENV NAME: {0}>'.format(body['name']))
        if VALID_NAME_REGEX.match(str(body['name'])):
            environment.update(body)
            environment.save(session)
        else:
            msg = _('Environment name must contain only alphanumeric '
                    'or "_-." characters, must start with alpha')
            LOG.exception(msg)
            raise exc.HTTPClientError(msg)

        return environment.to_dict()
Пример #12
0
    def configure(self, request, environment_id):
        LOG.debug("Session:Configure <EnvId: {0}>".format(environment_id))

        unit = db_session.get_session()
        environment = unit.query(models.Environment).get(environment_id)

        if environment is None:
            LOG.info(_("Environment <EnvId {0}> " "is not found").format(environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(_("User is not authorized to access " "this tenant resources."))
            raise exc.HTTPUnauthorized

        # no new session can be opened if environment has deploying status
        env_status = envs.EnvironmentServices.get_status(environment_id)
        if env_status == envs.EnvironmentStatus.deploying:
            LOG.info(
                _("Could not open session for environment <EnvId: {0}>," "environment has deploying " "status.").format(
                    environment_id
                )
            )
            raise exc.HTTPForbidden()

        user_id = request.context.user
        session = sessions.SessionServices.create(environment_id, user_id)

        return session.to_dict()
Пример #13
0
    def deploy(self, request, environment_id, session_id):
        LOG.debug("Session:Deploy <SessionId: {0}>".format(session_id))

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        if session is None:
            LOG.error(_("Session <SessionId {0}> " "is not found").format(session_id))
            raise exc.HTTPNotFound()

        if session.environment_id != environment_id:
            LOG.error(
                _("Session <SessionId {0}> is not tied with Environment " "<EnvId {1}>").format(
                    session_id, environment_id
                )
            )
            raise exc.HTTPNotFound()

        if not sessions.SessionServices.validate(session):
            LOG.error(_("Session <SessionId {0}> " "is invalid").format(session_id))
            raise exc.HTTPForbidden()

        if session.state != sessions.SessionState.open:
            LOG.error(
                _("Session <SessionId {0}> is already deployed or " "deployment is in progress").format(session_id)
            )
            raise exc.HTTPForbidden()

        sessions.SessionServices.deploy(session, unit, request.context.auth_token)
Пример #14
0
    def _validate_change(self, change):
        change_path = change['path'][0]
        change_op = change['op']
        allowed_methods = self.allowed_operations.get(change_path)

        if not allowed_methods:
            msg = _("Attribute '{0}' is invalid").format(change_path)
            raise webob.exc.HTTPForbidden(explanation=unicode(msg))

        if change_op not in allowed_methods:
            msg = _("Method '{method}' is not allowed for a path with name "
                    "'{name}'. Allowed operations are: "
                    "'{ops}'").format(method=change_op,
                                      name=change_path,
                                      ops=', '.join(allowed_methods))

            raise webob.exc.HTTPForbidden(explanation=unicode(msg))

        property_to_update = {change_path: change['value']}

        try:
            jsonschema.validate(property_to_update, schemas.PKG_UPDATE_SCHEMA)
        except jsonschema.ValidationError as e:
            LOG.exception(e)
            raise webob.exc.HTTPBadRequest(explanation=e.message)
Пример #15
0
    def show(self, request, environment_id):
        LOG.debug('Environments:Show <Id: {0}>'.format(environment_id))
        target = {"environment_id": environment_id}
        policy.check('show_environment', request.context, target)

        session = db_session.get_session()
        environment = session.query(models.Environment).get(environment_id)

        if environment is None:
            LOG.info(_('Environment <EnvId {0}> is not found').format(
                environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(_('User is not authorized to access '
                       'this tenant resources.'))
            raise exc.HTTPUnauthorized

        env = environment.to_dict()
        env['status'] = envs.EnvironmentServices.get_status(env['id'])

        session_id = None
        if hasattr(request, 'context') and request.context.session:
            session_id = request.context.session

        #add services to env
        get_data = core_services.CoreServices.get_data
        env['services'] = get_data(environment_id, '/services', session_id)

        return env
Пример #16
0
    def delete(self, request, environment_id, session_id):
        LOG.debug('Session:Delete <SessionId: {0}>'.format(session_id))

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        self._check_session(environment_id, session, session_id)

        user_id = request.context.user
        if session.user_id != user_id:
            msg = _('User <UserId {0}> is not authorized to access session'
                    '<SessionId {1}>.').format(user_id, session_id)
            LOG.error(msg)
            raise exc.HTTPUnauthorized(explanation=msg)

        if session.state == sessions.SessionState.DEPLOYING:
            msg = _('Session <SessionId: {0}> is in deploying state and '
                    'could not be deleted').format(session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        with unit.begin():
            unit.delete(session)

        return None
Пример #17
0
    def __init__(self,
                 stdout=None,
                 stderr=None,
                 exit_code=None,
                 cmd=None,
                 description=None):
        self.exit_code = exit_code
        self.stderr = stderr
        self.stdout = stdout
        self.cmd = cmd
        self.description = description

        if description is None:
            description = _("Unexpected error while running command.")
        if exit_code is None:
            exit_code = '-'
        message = _('%(description)s\n'
                    'Command: %(cmd)s\n'
                    'Exit code: %(exit_code)s\n'
                    'Stdout: %(stdout)r\n'
                    'Stderr: %(stderr)r') % {
                        'description': description,
                        'cmd': cmd,
                        'exit_code': exit_code,
                        'stdout': stdout,
                        'stderr': stderr
                    }
        super(ProcessExecutionError, self).__init__(message)
Пример #18
0
    def show(self, request, environment_id):
        LOG.debug('Environments:Show <Id: {0}>'.format(environment_id))
        target = {"environment_id": environment_id}
        policy.check('show_environment', request.context, target)

        session = db_session.get_session()
        environment = session.query(models.Environment).get(environment_id)

        if environment is None:
            LOG.info(
                _('Environment <EnvId {0}> is not found').format(
                    environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(
                _('User is not authorized to access '
                  'this tenant resources.'))
            raise exc.HTTPUnauthorized

        env = environment.to_dict()
        env['status'] = envs.EnvironmentServices.get_status(env['id'])

        session_id = None
        if hasattr(request, 'context') and request.context.session:
            session_id = request.context.session

        #add services to env
        get_data = core_services.CoreServices.get_data
        env['services'] = get_data(environment_id, '/services', session_id)

        return env
Пример #19
0
 def _from_json(self, datastring):
     value = datastring
     try:
         LOG.debug(_("Trying deserialize '{0}' to json".format(datastring)))
         value = jsonutils.loads(datastring)
     except ValueError:
         LOG.debug(_("Unable deserialize to json, using raw text"))
     return value
Пример #20
0
 def _from_json(self, datastring):
     value = datastring
     try:
         LOG.debug(_("Trying deserialize '{0}' to json".format(datastring)))
         value = jsonutils.loads(datastring)
     except ValueError:
         LOG.debug(_("Unable deserialize to json, using raw text"))
     return value
Пример #21
0
def verify_and_get_env(db_session, environment_id, request):
    environment = db_session.query(models.Environment).get(environment_id)
    if not environment:
        LOG.info(_('Environment with id {0} not found').format(environment_id))
        raise exc.HTTPNotFound

    if environment.tenant_id != request.context.tenant:
        LOG.info(_('User is not authorized to access this tenant resources.'))
        raise exc.HTTPUnauthorized
    return environment
Пример #22
0
    def _check_session(self, environment_id, session, session_id):
        if session is None:
            msg = _('Session <SessionId {0}> is not found').format(session_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if session.environment_id != environment_id:
            msg = _('Session <SessionId {0}> is not tied with Environment '
                    '<EnvId {1}>').format(session_id, environment_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)
Пример #23
0
    def _check_session(self, environment_id, session, session_id):
        if session is None:
            msg = _('Session <SessionId {0}> is not found').format(session_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if session.environment_id != environment_id:
            msg = _('Session <SessionId {0}> is not tied with Environment '
                    '<EnvId {1}>').format(session_id, environment_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)
Пример #24
0
    def upload(self, req, body=None):
        """Upload new file archive for the new package
           together with package metadata.
        """
        policy.check("upload_package", req.context)

        _check_content_type(req, 'multipart/form-data')
        file_obj, package_meta = _validate_body(body)
        if package_meta:
            try:
                jsonschema.validate(package_meta, schemas.PKG_UPLOAD_SCHEMA)
            except jsonschema.ValidationError as e:
                LOG.exception(e)
                raise exc.HTTPBadRequest(explanation=e.message)
        else:
            package_meta = {}

        with tempfile.NamedTemporaryFile(delete=False) as tempf:
            LOG.debug("Storing package archive in a temporary file")
            content = file_obj.file.read()
            if not content:
                msg = _("Uploading file can't be empty")
                LOG.error(msg)
                raise exc.HTTPBadRequest(msg)
            tempf.write(content)
            package_meta['archive'] = content
        try:
            pkg_to_upload = load_utils.load_from_file(tempf.name,
                                                      target_dir=None,
                                                      drop_dir=True)
        except pkg_exc.PackageLoadError as e:
            LOG.exception(e)
            raise exc.HTTPBadRequest(e)
        finally:
            LOG.debug("Deleting package archive temporary file")
            os.remove(tempf.name)

        # extend dictionary for update db
        for k, v in PKG_PARAMS_MAP.iteritems():
            if hasattr(pkg_to_upload, k):
                package_meta[v] = getattr(pkg_to_upload, k)

        if req.params.get('is_public', '').lower() == 'true':
            policy.check('publicize_image', req.context)
            package_meta['is_public'] = True

        try:
            package = db_api.package_upload(package_meta, req.context.tenant)
        except db_exc.DBDuplicateEntry:
            msg = _('Package with specified full name is already registered')
            LOG.exception(msg)
            raise exc.HTTPServerError(msg)
        return package.to_dict()
Пример #25
0
    def upload(self, req, body=None):
        """Upload new file archive for the new package
           together with package metadata.
        """
        policy.check("upload_package", req.context)

        _check_content_type(req, 'multipart/form-data')
        file_obj, package_meta = _validate_body(body)
        if package_meta:
            try:
                jsonschema.validate(package_meta, schemas.PKG_UPLOAD_SCHEMA)
            except jsonschema.ValidationError as e:
                LOG.exception(e)
                raise exc.HTTPBadRequest(explanation=e.message)
        else:
            package_meta = {}

        with tempfile.NamedTemporaryFile(delete=False) as tempf:
            LOG.debug("Storing package archive in a temporary file")
            content = file_obj.file.read()
            if not content:
                msg = _("Uploading file can't be empty")
                LOG.error(msg)
                raise exc.HTTPBadRequest(msg)
            tempf.write(content)
            package_meta['archive'] = content
        try:
            pkg_to_upload = load_utils.load_from_file(
                tempf.name, target_dir=None, drop_dir=True)
        except pkg_exc.PackageLoadError as e:
            LOG.exception(e)
            raise exc.HTTPBadRequest(e)
        finally:
            LOG.debug("Deleting package archive temporary file")
            os.remove(tempf.name)

        # extend dictionary for update db
        for k, v in PKG_PARAMS_MAP.iteritems():
            if hasattr(pkg_to_upload, k):
                package_meta[v] = getattr(pkg_to_upload, k)

        if req.params.get('is_public', '').lower() == 'true':
            policy.check('publicize_image', req.context)
            package_meta['is_public'] = True

        try:
            package = db_api.package_upload(package_meta, req.context.tenant)
        except db_exc.DBDuplicateEntry:
            msg = _('Package with specified full name is already registered')
            LOG.exception(msg)
            raise exc.HTTPServerError(msg)
        return package.to_dict()
Пример #26
0
def verify_and_get_deployment(db_session, environment_id, deployment_id):
    deployment = db_session.query(models.Task).get(deployment_id)
    if not deployment:
        LOG.info(_('Deployment with id {0} not found').format(deployment_id))
        raise exc.HTTPNotFound
    if deployment.environment_id != environment_id:
        LOG.info(_('Deployment with id {0} not found'
                   ' in environment {1}').format(deployment_id,
                                                 environment_id))
        raise exc.HTTPBadRequest

    deployment.description = _patch_description(deployment.description)
    return deployment
Пример #27
0
    def __inner(self, request, environment_id, *args, **kwargs):
        unit = db_session.get_session()
        environment = unit.query(models.Environment).get(environment_id)
        if environment is None:
            LOG.info(_("Environment with id '{0}'"
                       " not found").format(environment_id))
            raise exc.HTTPNotFound()

        if hasattr(request, 'context'):
            if environment.tenant_id != request.context.tenant:
                LOG.info(_('User is not authorized to access'
                           ' this tenant resources'))
                raise exc.HTTPUnauthorized()

        return func(self, request, environment_id, *args, **kwargs)
Пример #28
0
def _authorize_package(package, context, allow_public=False):
    if context.is_admin:
        return

    if package.owner_id != context.tenant:
        if not allow_public:
            msg = _("Package '{0}' is not owned by "
                    "tenant '{1}'").format(package.id, context.tenant)
            LOG.error(msg)
            raise exc.HTTPForbidden(msg)
        if not package.is_public:
            msg = _("Package '{0}' is not public and not owned by "
                    "tenant '{1}' ").format(package.id, context.tenant)
            LOG.error(msg)
            raise exc.HTTPForbidden(msg)
Пример #29
0
    def __inner(self, request, environment_id, *args, **kwargs):
        unit = db_session.get_session()
        environment = unit.query(models.Environment).get(environment_id)
        if environment is None:
            LOG.info(_("Environment with id '{0}'"
                       " not found").format(environment_id))
            raise exc.HTTPNotFound()

        if hasattr(request, 'context'):
            if environment.tenant_id != request.context.tenant:
                LOG.info(_('User is not authorized to access'
                           ' this tenant resources'))
                raise exc.HTTPUnauthorized()

        return func(self, request, environment_id, *args, **kwargs)
Пример #30
0
def _authorize_package(package, context, allow_public=False):
    if context.is_admin:
        return

    if package.owner_id != context.tenant:
        if not allow_public:
            msg = _("Package '{0}' is not owned by "
                    "tenant '{1}'").format(package.id, context.tenant)
            LOG.error(msg)
            raise exc.HTTPForbidden(msg)
        if not package.is_public:
            msg = _("Package '{0}' is not public and not owned by "
                    "tenant '{1}' ").format(package.id, context.tenant)
            LOG.error(msg)
            raise exc.HTTPForbidden(msg)
Пример #31
0
def _get_not_supported_column(col_name_col_instance, column_name):
    try:
        column = col_name_col_instance[column_name]
    except KeyError:
        msg = _("Please specify column %s in col_name_col_instance "
                "param. It is required because column has unsupported "
                "type by sqlite).")
        raise ColumnError(msg % column_name)

    if not isinstance(column, Column):
        msg = _("col_name_col_instance param has wrong type of "
                "column instance for column %s It should be instance "
                "of sqlalchemy.Column.")
        raise ColumnError(msg % column_name)
    return column
Пример #32
0
def _db_schema_sanity_check(engine):
    """Ensure all database tables were created with required parameters.

    :param engine:  SQLAlchemy engine instance for a given database

    """

    if engine.name == 'mysql':
        onlyutf8_sql = ('SELECT TABLE_NAME,TABLE_COLLATION '
                        'from information_schema.TABLES '
                        'where TABLE_SCHEMA=%s and '
                        'TABLE_COLLATION NOT LIKE "%%utf8%%"')

        # NOTE(morganfainberg): exclude the sqlalchemy-migrate and alembic
        # versioning tables from the tables we need to verify utf8 status on.
        # Non-standard table names are not supported.
        EXCLUDED_TABLES = ['migrate_version', 'alembic_version']

        table_names = [res[0] for res in
                       engine.execute(onlyutf8_sql, engine.url.database) if
                       res[0].lower() not in EXCLUDED_TABLES]

        if len(table_names) > 0:
            raise ValueError(_('Tables "%s" have non utf8 collation, '
                               'please make sure all tables are CHARSET=utf8'
                               ) % ','.join(table_names))
Пример #33
0
def _check_content_type(req, content_type):
    try:
        req.get_content_type((content_type,))
    except exception.InvalidContentType:
        msg = _("Content-Type must be '{0}'").format(content_type)
        LOG.error(msg)
        raise exc.HTTPBadRequest(explanation=msg)
Пример #34
0
    def acquire(self):
        basedir = os.path.dirname(self.fname)

        if not os.path.exists(basedir):
            fileutils.ensure_tree(basedir)
            LOG.info(_LI('Created lock path: %s'), basedir)

        self.lockfile = open(self.fname, 'w')

        while True:
            try:
                # Using non-blocking locks since green threads are not
                # patched to deal with blocking locking calls.
                # Also upon reading the MSDN docs for locking(), it seems
                # to have a laughable 10 attempts "blocking" mechanism.
                self.trylock()
                LOG.debug('Got file lock "%s"', self.fname)
                return True
            except IOError as e:
                if e.errno in (errno.EACCES, errno.EAGAIN):
                    # external locks synchronise things like iptables
                    # updates - give it some time to prevent busy spinning
                    time.sleep(0.01)
                else:
                    raise threading.ThreadError(
                        _("Unable to acquire lock on"
                          " `%(filename)s` due to"
                          " %(exception)s") % {
                              'filename': self.fname,
                              'exception': e,
                          })
Пример #35
0
    def deprecated(self, msg, *args, **kwargs):
        """Call this method when a deprecated feature is used.

        If the system is configured for fatal deprecations then the message
        is logged at the 'critical' level and :class:`DeprecatedConfig` will
        be raised.

        Otherwise, the message will be logged (once) at the 'warn' level.

        :raises: :class:`DeprecatedConfig` if the system is configured for
                 fatal deprecations.

        """
        stdmsg = _("Deprecated: %s") % msg
        if CONF.fatal_deprecations:
            self.critical(stdmsg, *args, **kwargs)
            raise DeprecatedConfig(msg=stdmsg)

        # Using a list because a tuple with dict can't be stored in a set.
        sent_args = self._deprecated_messages_sent.setdefault(msg, list())

        if args in sent_args:
            # Already logged this message, so don't log it again.
            return

        sent_args.append(args)
        self.warn(stdmsg, *args, **kwargs)
Пример #36
0
def bool_from_string(subject, strict=False, default=False):
    """Interpret a string as a boolean.

    A case-insensitive match is performed such that strings matching 't',
    'true', 'on', 'y', 'yes', or '1' are considered True and, when
    `strict=False`, anything else returns the value specified by 'default'.

    Useful for JSON-decoded stuff and config file parsing.

    If `strict=True`, unrecognized values, including None, will raise a
    ValueError which is useful when parsing values passed in from an API call.
    Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
    """
    if not isinstance(subject, six.string_types):
        subject = six.text_type(subject)

    lowered = subject.strip().lower()

    if lowered in TRUE_STRINGS:
        return True
    elif lowered in FALSE_STRINGS:
        return False
    elif strict:
        acceptable = ', '.join("'%s'" % s
                               for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
        msg = _("Unrecognized value '%(val)s', acceptable values are:"
                " %(acceptable)s") % {
                    'val': subject,
                    'acceptable': acceptable
                }
        raise ValueError(msg)
    else:
        return default
Пример #37
0
def db_sync(engine, abs_path, version=None, init_version=0, sanity_check=True):
    """Upgrade or downgrade a database.

    Function runs the upgrade() or downgrade() functions in change scripts.

    :param engine:       SQLAlchemy engine instance for a given database
    :param abs_path:     Absolute path to migrate repository.
    :param version:      Database will upgrade/downgrade until this version.
                         If None - database will update to the latest
                         available version.
    :param init_version: Initial database version
    :param sanity_check: Require schema sanity checking for all tables
    """

    if version is not None:
        try:
            version = int(version)
        except ValueError:
            raise exception.DbMigrationError(
                message=_("version should be an integer"))

    current_version = db_version(engine, abs_path, init_version)
    repository = _find_migrate_repo(abs_path)
    if sanity_check:
        _db_schema_sanity_check(engine)
    if version is None or version > current_version:
        return versioning_api.upgrade(engine, repository, version)
    else:
        return versioning_api.downgrade(engine, repository,
                                        version)
Пример #38
0
        def _validate_limit(value):
            if value is None:
                return
            try:
                value = int(value)
            except ValueError:
                msg = _("limit param must be an integer")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)

            if value <= 0:
                msg = _("limit param must be positive")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)

            return value
Пример #39
0
    def acquire(self):
        basedir = os.path.dirname(self.fname)

        if not os.path.exists(basedir):
            fileutils.ensure_tree(basedir)
            LOG.info(_LI('Created lock path: %s'), basedir)

        self.lockfile = open(self.fname, 'w')

        while True:
            try:
                # Using non-blocking locks since green threads are not
                # patched to deal with blocking locking calls.
                # Also upon reading the MSDN docs for locking(), it seems
                # to have a laughable 10 attempts "blocking" mechanism.
                self.trylock()
                LOG.debug('Got file lock "%s"', self.fname)
                return True
            except IOError as e:
                if e.errno in (errno.EACCES, errno.EAGAIN):
                    # external locks synchronise things like iptables
                    # updates - give it some time to prevent busy spinning
                    time.sleep(0.01)
                else:
                    raise threading.ThreadError(_("Unable to acquire lock on"
                                                  " `%(filename)s` due to"
                                                  " %(exception)s") %
                                                {
                                                    'filename': self.fname,
                                                    'exception': e,
                                                })
Пример #40
0
def bool_from_string(subject, strict=False, default=False):
    """Interpret a string as a boolean.

    A case-insensitive match is performed such that strings matching 't',
    'true', 'on', 'y', 'yes', or '1' are considered True and, when
    `strict=False`, anything else returns the value specified by 'default'.

    Useful for JSON-decoded stuff and config file parsing.

    If `strict=True`, unrecognized values, including None, will raise a
    ValueError which is useful when parsing values passed in from an API call.
    Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
    """
    if not isinstance(subject, six.string_types):
        subject = six.text_type(subject)

    lowered = subject.strip().lower()

    if lowered in TRUE_STRINGS:
        return True
    elif lowered in FALSE_STRINGS:
        return False
    elif strict:
        acceptable = ', '.join(
            "'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
        msg = _("Unrecognized value '%(val)s', acceptable values are:"
                " %(acceptable)s") % {'val': subject,
                                      'acceptable': acceptable}
        raise ValueError(msg)
    else:
        return default
Пример #41
0
        def _validate_limit(value):
            if value is None:
                return
            try:
                value = int(value)
            except ValueError:
                msg = _("limit param must be an integer")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)

            if value <= 0:
                msg = _("limit param must be positive")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)

            return value
Пример #42
0
def _check_content_type(req, content_type):
    try:
        req.get_content_type((content_type, ))
    except exception.InvalidContentType:
        msg = _("Content-Type must be '{0}'").format(content_type)
        LOG.error(msg)
        raise exc.HTTPBadRequest(explanation=msg)
Пример #43
0
    def deprecated(self, msg, *args, **kwargs):
        """Call this method when a deprecated feature is used.

        If the system is configured for fatal deprecations then the message
        is logged at the 'critical' level and :class:`DeprecatedConfig` will
        be raised.

        Otherwise, the message will be logged (once) at the 'warn' level.

        :raises: :class:`DeprecatedConfig` if the system is configured for
                 fatal deprecations.

        """
        stdmsg = _("Deprecated: %s") % msg
        if CONF.fatal_deprecations:
            self.critical(stdmsg, *args, **kwargs)
            raise DeprecatedConfig(msg=stdmsg)

        # Using a list because a tuple with dict can't be stored in a set.
        sent_args = self._deprecated_messages_sent.setdefault(msg, list())

        if args in sent_args:
            # Already logged this message, so don't log it again.
            return

        sent_args.append(args)
        self.warn(stdmsg, *args, **kwargs)
Пример #44
0
 def _wrap(*args, **kw):
     try:
         return f(*args, **kw)
     except Exception as e:
         if not isinstance(e, Error):
             logging.exception(_('Uncaught exception'))
             raise Error(str(e))
         raise
Пример #45
0
def _read_deleted_filter(query, db_model, read_deleted):
    if 'deleted' not in db_model.__table__.columns:
        raise ValueError(_("There is no `deleted` column in `%s` table. "
                           "Project doesn't use soft-deleted feature.")
                         % db_model.__name__)

    default_deleted_value = db_model.__table__.c.deleted.default.arg
    if read_deleted == 'no':
        query = query.filter(db_model.deleted == default_deleted_value)
    elif read_deleted == 'yes':
        pass  # omit the filter to include deleted and active
    elif read_deleted == 'only':
        query = query.filter(db_model.deleted != default_deleted_value)
    else:
        raise ValueError(_("Unrecognized read_deleted value '%s'")
                         % read_deleted)
    return query
Пример #46
0
 def _wrap(*args, **kw):
     try:
         return f(*args, **kw)
     except Exception as e:
         if not isinstance(e, Error):
             logging.exception(_('Uncaught exception'))
             raise Error(str(e))
         raise
Пример #47
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        try:
            action, action_args, accept = self.deserialize_request(request)
        except exception.InvalidContentType:
            msg = _("Unsupported Content-Type")
            return webob.exc.HTTPUnsupportedMediaType(explanation=msg)
        except exception.MalformedRequestBody:
            msg = _("Malformed request body")
            return webob.exc.HTTPBadRequest(explanation=msg)

        action_result = self.execute_action(action, request, **action_args)
        try:
            return self.serialize_response(action, action_result, accept)
        # return unserializable result (typically a webob exc)
        except Exception:
            return action_result
Пример #48
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        try:
            action, action_args, accept = self.deserialize_request(request)
        except exception.InvalidContentType:
            msg = _("Unsupported Content-Type")
            return webob.exc.HTTPUnsupportedMediaType(explanation=msg)
        except exception.MalformedRequestBody:
            msg = _("Malformed request body")
            return webob.exc.HTTPBadRequest(explanation=msg)

        action_result = self.execute_action(action, request, **action_args)
        try:
            return self.serialize_response(action, action_result, accept)
        # return unserializable result (typically a webob exc)
        except Exception:
            return action_result
Пример #49
0
def string_to_bytes(text, unit_system='IEC', return_int=False):
    """Converts a string into an float representation of bytes.

    The units supported for IEC ::

        Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it)
        KB, KiB, MB, MiB, GB, GiB, TB, TiB

    The units supported for SI ::

        kb(it), Mb(it), Gb(it), Tb(it)
        kB, MB, GB, TB

    Note that the SI unit system does not support capital letter 'K'

    :param text: String input for bytes size conversion.
    :param unit_system: Unit system for byte size conversion.
    :param return_int: If True, returns integer representation of text
                       in bytes. (default: decimal)
    :returns: Numerical representation of text in bytes.
    :raises ValueError: If text has an invalid value.

    """
    try:
        base, reg_ex = UNIT_SYSTEM_INFO[unit_system]
    except KeyError:
        msg = _('Invalid unit system: "%s"') % unit_system
        raise ValueError(msg)
    match = reg_ex.match(text)
    if match:
        magnitude = float(match.group(1))
        unit_prefix = match.group(2)
        if match.group(3) in ['b', 'bit']:
            magnitude /= 8
    else:
        msg = _('Invalid string format: %s') % text
        raise ValueError(msg)
    if not unit_prefix:
        res = magnitude
    else:
        res = magnitude * pow(base, UNIT_PREFIX_EXPONENT[unit_prefix])
    if return_int:
        return int(math.ceil(res))
    return res
Пример #50
0
def string_to_bytes(text, unit_system='IEC', return_int=False):
    """Converts a string into an float representation of bytes.

    The units supported for IEC ::

        Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it)
        KB, KiB, MB, MiB, GB, GiB, TB, TiB

    The units supported for SI ::

        kb(it), Mb(it), Gb(it), Tb(it)
        kB, MB, GB, TB

    Note that the SI unit system does not support capital letter 'K'

    :param text: String input for bytes size conversion.
    :param unit_system: Unit system for byte size conversion.
    :param return_int: If True, returns integer representation of text
                       in bytes. (default: decimal)
    :returns: Numerical representation of text in bytes.
    :raises ValueError: If text has an invalid value.

    """
    try:
        base, reg_ex = UNIT_SYSTEM_INFO[unit_system]
    except KeyError:
        msg = _('Invalid unit system: "%s"') % unit_system
        raise ValueError(msg)
    match = reg_ex.match(text)
    if match:
        magnitude = float(match.group(1))
        unit_prefix = match.group(2)
        if match.group(3) in ['b', 'bit']:
            magnitude /= 8
    else:
        msg = _('Invalid string format: %s') % text
        raise ValueError(msg)
    if not unit_prefix:
        res = magnitude
    else:
        res = magnitude * pow(base, UNIT_PREFIX_EXPONENT[unit_prefix])
    if return_int:
        return int(math.ceil(res))
    return res
Пример #51
0
    def _from_xml(self, request):
        datastring = request.body
        plurals = set(self.metadata.get('plurals', {}))

        try:
            node = xmlutils.safe_minidom_parse_string(datastring).childNodes[0]
            return {node.nodeName: self._from_xml_node(node, plurals)}
        except expat.ExpatError:
            msg = _("cannot understand XML")
            raise exception.MalformedRequestBody(reason=msg)
Пример #52
0
    def _from_xml(self, request):
        datastring = request.body
        plurals = set(self.metadata.get('plurals', {}))

        try:
            node = xmlutils.safe_minidom_parse_string(datastring).childNodes[0]
            return {node.nodeName: self._from_xml_node(node, plurals)}
        except expat.ExpatError:
            msg = _("cannot understand XML")
            raise exception.MalformedRequestBody(reason=msg)
Пример #53
0
    def create(self, request, body):
        LOG.debug('Environments:Create <Body {0}>'.format(body))
        policy.check('create_environment', request.context)
        LOG.debug('ENV NAME: {0}>'.format(body['name']))
        if VALID_NAME_REGEX.match(str(body['name'])):
            try:
                environment = envs.EnvironmentServices.create(
                    body.copy(), request.context.tenant)
            except db_exc.DBDuplicateEntry:
                msg = _('Environment with specified name already exists')
                LOG.exception(msg)
                raise exc.HTTPConflict(msg)
        else:
            msg = _('Environment name must contain only alphanumeric '
                    'or "_-." characters, must start with alpha')
            LOG.exception(msg)
            raise exc.HTTPClientError(msg)

        return environment.to_dict()
Пример #54
0
def setup_logging():
    """Sets up the logging options for a log with supplied name."""

    if CONF.log_config:
        # Use a logging configuration file for all settings...
        if os.path.exists(CONF.log_config):
            logging.config.fileConfig(CONF.log_config)
            return
        else:
            raise RuntimeError(
                _("Unable to locate specified logging "
                  "config file: %s" % CONF.log_config))

    root_logger = logging.root
    if CONF.debug:
        root_logger.setLevel(logging.DEBUG)
    elif CONF.verbose:
        root_logger.setLevel(logging.INFO)
    else:
        root_logger.setLevel(logging.WARNING)

    formatter = logging.Formatter(CONF.log_format, CONF.log_date_format)

    if CONF.use_syslog:
        try:
            facility = getattr(logging.handlers.SysLogHandler,
                               CONF.syslog_log_facility)
        except AttributeError:
            raise ValueError(_("Invalid syslog facility"))

        handler = logging.handlers.SysLogHandler(address='/dev/log',
                                                 facility=facility)
    elif CONF.log_file:
        logfile = CONF.log_file
        if CONF.log_dir:
            logfile = os.path.join(CONF.log_dir, logfile)
        handler = logging.handlers.WatchedFileHandler(logfile)
    else:
        handler = logging.StreamHandler(sys.stdout)

    handler.setFormatter(formatter)
    root_logger.addHandler(handler)
Пример #55
0
def _get_deployment_config_file():
    """Retrieve the deployment_config_file config item, formatted as an
       absolute pathname.
    """
    path = CONF.paste_deploy.config_file
    if not path:
        path = _get_paste_config_path()
    if not path:
        msg = _("Unable to locate paste config file for %s.") % CONF.prog
        raise RuntimeError(msg)
    return os.path.abspath(path)
Пример #56
0
class LogConfigError(Exception):

    message = _('Error loading logging config %(log_config)s: %(err_msg)s')

    def __init__(self, log_config, err_msg):
        self.log_config = log_config
        self.err_msg = err_msg

    def __str__(self):
        return self.message % dict(log_config=self.log_config,
                                   err_msg=self.err_msg)
Пример #57
0
    def execute(self, request, environment_id, action_id, body):
        policy.check("execute_action", request.context, {})

        LOG.debug('Action:Execute <ActionId: {0}>'.format(action_id))

        unit = db_session.get_session()
        environment = unit.query(models.Environment).get(environment_id)

        if environment is None:
            LOG.info(
                _('Environment <EnvId {0}> '
                  'is not found').format(environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(
                _('User is not authorized to access '
                  'this tenant resources.'))
            raise exc.HTTPUnauthorized

        # no new session can be opened if environment has deploying status
        env_status = envs.EnvironmentServices.get_status(environment_id)
        if env_status in (states.EnvironmentStatus.DEPLOYING,
                          states.EnvironmentStatus.DELETING):
            LOG.info(
                _('Could not open session for environment <EnvId: {0}>,'
                  'environment has deploying '
                  'status.').format(environment_id))
            raise exc.HTTPForbidden()

        user_id = request.context.user
        session = sessions.SessionServices.create(environment_id, user_id)

        if not sessions.SessionServices.validate(session):
            LOG.error(
                _('Session <SessionId {0}> '
                  'is invalid').format(session.id))
            raise exc.HTTPForbidden()

        actions.ActionServices.execute(action_id, session, unit,
                                       request.context.auth_token, body or {})
Пример #58
0
    def _validate_json_pointer(self, pointer):
        """Validate a json pointer.

        Only limited form of json pointers is accepted.
        """
        if not pointer.startswith('/'):
            msg = _('Pointer `%s` does not start with "/".') % pointer
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if re.search('/\s*?/', pointer[1:]):
            msg = _('Pointer `%s` contains adjacent "/".') % pointer
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if len(pointer) > 1 and pointer.endswith('/'):
            msg = _('Pointer `%s` end with "/".') % pointer
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if pointer[1:].strip() == '/':
            msg = _('Pointer `%s` does not contains valid token.') % pointer
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if re.search('~[^01]', pointer) or pointer.endswith('~'):
            msg = _('Pointer `%s` contains "~" not part of'
                    ' a recognized escape sequence.') % pointer
            raise webob.exc.HTTPBadRequest(explanation=msg)