Beispiel #1
0
    def update(self, req, body, package_id):
        """List of allowed changes:
            { "op": "add", "path": "/tags", "value": [ "foo", "bar" ] }
            { "op": "add", "path": "/categories", "value": [ "foo", "bar" ] }
            { "op": "remove", "path": "/tags" }
            { "op": "remove", "path": "/categories" }
            { "op": "replace", "path": "/tags", "value": ["foo", "bar"] }
            { "op": "replace", "path": "/is_public", "value": true }
            { "op": "replace", "path": "/description",
                                "value":"New description" }
            { "op": "replace", "path": "/name", "value": "New name" }
        """
        policy.check("modify_package", req.context, {'package_id': package_id})

        pkg_to_update = db_api.package_get(package_id, req.context)
        if pkg_to_update.is_public:
            policy.check("manage_public_package", req.context)

        _check_content_type(req, 'application/murano-packages-json-patch')
        if not isinstance(body, list):
            msg = _('Request body must be a JSON array of operation objects.')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        for change in body:
            if 'is_public' in change['path']:
                if change['value'] is True and not pkg_to_update.is_public:
                    policy.check('publicize_package', req.context)
            if 'name' in change['path']:
                if len(change['value']) > 80:
                    msg = _('Package name should be 80 characters maximum')
                    LOG.error(msg)
                    raise exc.HTTPBadRequest(explanation=msg)
        package = db_api.package_update(package_id, body, req.context)
        return package.to_dict()
Beispiel #2
0
def validate_quotes(value):
    """Validate filter values

    Validation opening/closing quotes in the expression.
    """
    open_quotes = True
    count_backslash_in_row = 0
    for i in range(len(value)):
        if value[i] == '"':
            if count_backslash_in_row % 2:
                continue
            if open_quotes:
                if i and value[i - 1] != ',':
                    msg = _("Invalid filter value %s. There is no comma "
                            "before opening quotation mark.") % value
                    raise ValueError(msg)
            else:
                if i + 1 != len(value) and value[i + 1] != ",":
                    msg = _("Invalid filter value %s. There is no comma "
                            "after opening quotation mark.") % value
                    raise ValueError(msg)
            open_quotes = not open_quotes
        elif value[i] == '\\':
            count_backslash_in_row += 1
        else:
            count_backslash_in_row = 0
    if not open_quotes:
        msg = _("Invalid filter value %s. The quote is not closed.") % value
        raise ValueError(msg)
    return True
Beispiel #3
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(_LI('Environment <EnvId {0}> not '
                         'found').format(environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(_LI('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'])):
            try:
                environment.update(body)
                environment.save(session)
            except db_exc.DBDuplicateEntry:
                msg = _('Environment with specified name already exists')
                LOG.exception(msg)
                raise exc.HTTPConflict(explanation=msg)
        else:
            msg = _('Environment name must contain only alphanumeric '
                    'or "_-." characters, must start with alpha')
            LOG.error(msg)
            raise exc.HTTPClientError(explanation=msg)

        return environment.to_dict()
Beispiel #4
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:
                msg = _("Package schema is not valid: {reason}").format(
                    reason=e)
                LOG.exception(msg)
                raise exc.HTTPBadRequest(explanation=msg)
        else:
            package_meta = {}

        if package_meta.get('is_public'):
            policy.check('publicize_package', req.context)

        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(explanation=msg)
            tempf.write(content)
            package_meta['archive'] = content
        try:
            with load_utils.load_from_file(tempf.name,
                                           target_dir=None,
                                           drop_dir=True) as pkg_to_upload:
                # extend dictionary for update db
                for k, v in six.iteritems(PKG_PARAMS_MAP):
                    if hasattr(pkg_to_upload, k):
                        package_meta[v] = getattr(pkg_to_upload, k)
                if len(package_meta['name']) > 80:
                    msg = _('Package name should be 80 characters maximum')
                    LOG.error(msg)
                    raise exc.HTTPBadRequest(explanation=msg)
                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.HTTPConflict(msg)
                return package.to_dict()
        except pkg_exc.PackageLoadError as e:
            msg = _("Couldn't load package from file: {reason}").format(
                reason=e)
            LOG.exception(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        finally:
            LOG.debug("Deleting package archive temporary file")
            os.remove(tempf.name)
Beispiel #5
0
 def _get_category_filters(req):
     query_params = {}
     valid_query_params = ['sort_keys', 'sort_dir', 'limit', 'marker']
     for key, value in req.GET.items():
         if key not in valid_query_params:
             raise exc.HTTPBadRequest(
                 _('Bad value passed to filter. '
                   'Got {key}, exected:{valid}').format(
                       key=key, valid=', '.join(valid_query_params)))
         if key == 'sort_keys':
             available_sort_keys = [
                 'name', 'created', 'updated', 'package_count', 'id'
             ]
             value = [v.strip() for v in value.split(',')]
             for sort_key in value:
                 if sort_key not in available_sort_keys:
                     raise exc.HTTPBadRequest(explanation=_(
                         'Invalid sort key: {sort_key}. '
                         'Must be one of the following: '
                         '{available}').format(
                             sort_key=sort_key,
                             available=', '.join(available_sort_keys)))
         if key == 'sort_dir':
             if value not in ['asc', 'desc']:
                 msg = _('Invalid sort direction: {0}').format(value)
                 raise exc.HTTPBadRequest(explanation=msg)
         query_params[key] = value
     return query_params
Beispiel #6
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(_LI('Environment <EnvId {0}> not '
                         'found').format(environment_id))
            raise exc.HTTPNotFound

        if environment.tenant_id != request.context.tenant:
            LOG.info(_LI('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'])):
            try:
                environment.update(body)
                environment.save(session)
            except db_exc.DBDuplicateEntry:
                msg = _('Environment with specified name already exists')
                LOG.exception(msg)
                raise exc.HTTPConflict(explanation=msg)
        else:
            msg = _('Environment name must contain only alphanumeric '
                    'or "_-." characters, must start with alpha')
            LOG.error(msg)
            raise exc.HTTPClientError(explanation=msg)

        return environment.to_dict()
Beispiel #7
0
    def update(self, req, body, package_id):
        """List of allowed changes:
            { "op": "add", "path": "/tags", "value": [ "foo", "bar" ] }
            { "op": "add", "path": "/categories", "value": [ "foo", "bar" ] }
            { "op": "remove", "path": "/tags" }
            { "op": "remove", "path": "/categories" }
            { "op": "replace", "path": "/tags", "value": ["foo", "bar"] }
            { "op": "replace", "path": "/is_public", "value": true }
            { "op": "replace", "path": "/description",
                                "value":"New description" }
            { "op": "replace", "path": "/name", "value": "New name" }
        """
        policy.check("modify_package", req.context, {'package_id': package_id})

        pkg_to_update = db_api.package_get(package_id, req.context)
        if pkg_to_update.is_public:
            policy.check("manage_public_package", req.context)

        _check_content_type(req, 'application/murano-packages-json-patch')
        if not isinstance(body, list):
            msg = _('Request body must be a JSON array of operation objects.')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        for change in body:
            if 'is_public' in change['path']:
                if change['value'] is True and not pkg_to_update.is_public:
                    policy.check('publicize_package', req.context)
            if 'name' in change['path']:
                if len(change['value']) > 80:
                    msg = _('Package name should be 80 characters maximum')
                    LOG.error(msg)
                    raise exc.HTTPBadRequest(explanation=msg)
        package = db_api.package_update(package_id, body, req.context)
        return package.to_dict()
Beispiel #8
0
 def create(self, request, body):
     """It creates the env template from the payload obtaining.
     This payload can contain just the template name, or include
     also service information.
     :param request: the operation request.
     :param body: the env template description
     :return: the description of the created template.
     """
     LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body))
     policy.check('create_env_template', request.context)
     try:
         LOG.debug(
             'ENV TEMP NAME: {templ_name}>'.format(templ_name=body['name']))
         if not envs_api.VALID_NAME_REGEX.match(str(body['name'])):
             msg = _('Environment Template must contain only alphanumeric '
                     'or "_-." characters, must start with alpha')
             LOG.error(msg)
             raise exc.HTTPBadRequest(msg)
     except Exception:
         msg = _('Env template body is incorrect')
         LOG.exception(msg)
         raise exc.HTTPClientError(msg)
     if len(body['name']) > 255:
         msg = _('Environment Template name should be 255 characters '
                 'maximum')
         LOG.exception(msg)
         raise exc.HTTPBadRequest(explanation=msg)
     try:
         template = env_temps.EnvTemplateServices.create(
             body.copy(), request.context.tenant)
         return template.to_dict()
     except db_exc.DBDuplicateEntry:
         msg = _('Env Template with specified name already exists')
         LOG.exception(msg)
         raise exc.HTTPConflict(msg)
Beispiel #9
0
def validate_quotes(value):
    """Validate filter values

    Validation opening/closing quotes in the expression.
    """
    open_quotes = True
    count_backslash_in_row = 0
    for i in range(len(value)):
        if value[i] == '"':
            if count_backslash_in_row % 2:
                continue
            if open_quotes:
                if i and value[i - 1] != ',':
                    msg = _("Invalid filter value %s. There is no comma "
                            "before opening quotation mark.") % value
                    raise ValueError(msg)
            else:
                if i + 1 != len(value) and value[i + 1] != ",":
                    msg = _("Invalid filter value %s. There is no comma "
                            "after opening quotation mark.") % value
                    raise ValueError(msg)
            open_quotes = not open_quotes
        elif value[i] == '\\':
            count_backslash_in_row += 1
        else:
            count_backslash_in_row = 0
    if not open_quotes:
        msg = _("Invalid filter value %s. The quote is not closed.") % value
        raise ValueError(msg)
    return True
Beispiel #10
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=six.text_type(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=six.text_type(msg))

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

        try:
            jsonschema.validate(property_to_update, schemas.PKG_UPDATE_SCHEMA)
        except jsonschema.ValidationError as e:
            LOG.error(_LE("Schema validation error occured: {error}")
                      .format(error=e))
            raise webob.exc.HTTPBadRequest(explanation=e.message)
Beispiel #11
0
    def create(self, request, body):
        LOG.debug('Environments:Create <Body {body}>'.format(body=body))
        policy.check('create_environment', request.context)

        if not body.get('name'):
            msg = _('Please, specify a name of the environment to create')
            LOG.exception(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        name = unicode(body['name'])
        if len(name) > 255:
            msg = _('Environment name should be 255 characters maximum')
            LOG.exception(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        if VALID_NAME_REGEX.match(name):
            try:
                environment = envs.EnvironmentServices.create(
                    body.copy(), request.context)
            except db_exc.DBDuplicateEntry:
                msg = _('Environment with specified name already exists')
                LOG.exception(msg)
                raise exc.HTTPConflict(explanation=msg)
        else:
            msg = _('Environment name must contain only alphanumericor "_-." '
                    'characters, must start with alpha')
            LOG.exception(msg)
            raise exc.HTTPClientError(explanation=msg)

        return environment.to_dict()
Beispiel #12
0
    def __inner(self, request, *args, **kwargs):
        if hasattr(request, 'context') and not request.context.session:
            msg = _('X-Configuration-Session header which indicates'
                    ' to the session is missed')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        session_id = request.context.session

        unit = db_session.get_session()
        session = unit.query(models.Session).get(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 not sessions.SessionServices.validate(session):
            msg = _('Session <SessionId {0}> '
                    'is invalid: environment has been updated or '
                    'updating right now with other session').format(session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        if session.state == states.SessionState.DEPLOYING:
            msg = _('Session <SessionId {0}> is already in deployment state'
                    ).format(session_id)
            raise exc.HTTPForbidden(explanation=msg)
        return func(self, request, *args, **kwargs)
Beispiel #13
0
def check(rule, ctxt, target={}, do_raise=True, exc=exceptions.HTTPForbidden):
    creds = ctxt.to_dict()

    try:
        result = _ENFORCER.enforce(rule, target, creds, do_raise, exc)
    except Exception:
        result = False
        raise
    else:
        return result
    finally:
        extra = {'policy': {'rule': rule, 'target': target}}

        if result:
            LOG.info(_("Policy check succeeded for rule "
                       "'%(rule)s' on target %(target)s"), {
                           'rule': rule,
                           'target': repr(target)
                       },
                     extra=extra)
        else:
            LOG.info(_("Policy check failed for rule "
                       "'%(rule)s' on target: %(target)s"), {
                           'rule': rule,
                           'target': repr(target)
                       },
                     extra=extra)
Beispiel #14
0
    def update(self, request, env_template_id, body):
        """It updates the description template

        :param request: the operation request.
        :param env_template_id: the env template ID.
        :param body: the description to be updated
        :return: the updated template description.
        """
        LOG.debug('Templates:Update <Id: {templ_id}, '
                  'Body: {body}>'.format(templ_id=env_template_id, body=body))
        target = {"env_template_id": env_template_id}
        policy.check('update_env_template', request.context, target)

        self._validate_request(request, env_template_id)
        try:
            LOG.debug('ENV TEMP NAME: {temp_name}>'.format(
                temp_name=body['name']))
            if not str(body['name']).strip():
                msg = _('Environment Template must contain at least one '
                        'non-white space symbol')
                LOG.exception(msg)
                raise exc.HTTPBadRequest(msg)
        except Exception:
                msg = _('EnvTemplate body is incorrect')
                LOG.exception(msg)
                raise exc.HTTPBadRequest(msg)

        template = env_temps.EnvTemplateServices.update(env_template_id, body)
        return template.to_dict()
Beispiel #15
0
    def show(self, request, environment_id, session_id):
        LOG.debug('Session:Show <SessionId: {id}>'.format(id=session_id))

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

        check_session(request, environment_id, session, session_id)

        user_id = request.context.user

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

        if not sessions.SessionServices.validate(session):
            msg = _('Session <SessionId {0}> is invalid: environment has been'
                    ' updated or updating right now with other session'
                    ).format(session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        return session.to_dict()
Beispiel #16
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        LOG.debug("{method} {url}\nHEADERS: {headers}".format(
                  method=request.method,
                  url=request.url,
                  headers=self._format_request_headers(request.headers)))

        try:
            action, action_args, accept = self.deserialize_request(request)
        except exceptions.UnsupportedContentType:
            msg = _("Unsupported Content-Type")
            return webob.exc.HTTPUnsupportedMediaType(detail=msg)
        except exceptions.NotAcceptableContentType:
            msg = _("Acceptable response can not be provided")
            return webob.exc.HTTPNotAcceptable(detail=msg)
        except exceptions.MalformedRequestBody:
            msg = _("Malformed request body")
            return webob.exc.HTTPBadRequest(explanation=msg)

        with ResourceExceptionHandler():
            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
Beispiel #17
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(request, 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
Beispiel #18
0
    def __inner(self, request, *args, **kwargs):
        if hasattr(request, 'context') and not request.context.session:
            msg = _('X-Configuration-Session header which indicates'
                    ' to the session is missed')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        session_id = request.context.session

        unit = db_session.get_session()
        session = unit.query(models.Session).get(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 not sessions.SessionServices.validate(session):
            msg = _('Session <SessionId {0}> '
                    'is invalid: environment has been updated or '
                    'updating right now with other session').format(session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        if session.state == states.SessionState.DEPLOYING:
            msg = _('Session <SessionId {0}> is already in deployment state'
                    ).format(session_id)
            raise exc.HTTPForbidden(explanation=msg)
        return func(self, request, *args, **kwargs)
Beispiel #19
0
    def update(self, request, env_template_id, body):
        """It updates the description template.
        :param request: the operation request.
        :param env_template_id: the env template ID.
        :param body: the description to be updated
        :return: the updated template description.
        """
        LOG.debug('Templates:Update <Id: {templ_id}, '
                  'Body: {body}>'.format(templ_id=env_template_id, body=body))
        target = {"env_template_id": env_template_id}
        policy.check('update_env_template', request.context, target)

        self._validate_request(request, env_template_id)
        try:
            LOG.debug('ENV TEMP NAME: {temp_name}>'.format(
                temp_name=body['name']))
            if not envs_api.VALID_NAME_REGEX.match(str(body['name'])):
                msg = _('Env Template must contain only alphanumeric '
                        'or "_-." characters, must start with alpha')
                LOG.exception(msg)
                raise exc.HTTPBadRequest(msg)
        except Exception:
                msg = _('EnvTemplate body is incorrect')
                LOG.exception(msg)
                raise exc.HTTPBadRequest(msg)

        template = env_temps.EnvTemplateServices.update(env_template_id, body)
        return template.to_dict()
Beispiel #20
0
    def update(self, request, env_template_id, body):
        """It updates the description template

        :param request: the operation request.
        :param env_template_id: the env template ID.
        :param body: the description to be updated
        :return: the updated template description.
        """
        LOG.debug('Templates:Update <Id: {templ_id}, '
                  'Body: {body}>'.format(templ_id=env_template_id, body=body))
        target = {"env_template_id": env_template_id}
        policy.check('update_env_template', request.context, target)

        self._validate_request(request, env_template_id)
        try:
            LOG.debug(
                'ENV TEMP NAME: {temp_name}>'.format(temp_name=body['name']))
            if not str(body['name']).strip():
                msg = _('Environment Template must contain at least one '
                        'non-white space symbol')
                LOG.exception(msg)
                raise exc.HTTPBadRequest(msg)
        except Exception:
            msg = _('EnvTemplate body is incorrect')
            LOG.exception(msg)
            raise exc.HTTPBadRequest(msg)

        template = env_temps.EnvTemplateServices.update(env_template_id, body)
        return template.to_dict()
Beispiel #21
0
    def update(self, request, env_template_id, body):
        """It updates the description template.
        :param request: the operation request.
        :param env_template_id: the env template ID.
        :param body: the description to be updated
        :return: the updated template description.
        """
        LOG.debug('Templates:Update <Id: {templ_id}, '
                  'Body: {body}>'.format(templ_id=env_template_id, body=body))
        target = {"env_template_id": env_template_id}
        policy.check('update_env_template', request.context, target)

        self._validate_request(request, env_template_id)
        try:
            LOG.debug(
                'ENV TEMP NAME: {temp_name}>'.format(temp_name=body['name']))
            if not envs_api.VALID_NAME_REGEX.match(str(body['name'])):
                msg = _('Env Template must contain only alphanumeric '
                        'or "_-." characters, must start with alpha')
                LOG.exception(msg)
                raise exc.HTTPBadRequest(msg)
        except Exception:
            msg = _('EnvTemplate body is incorrect')
            LOG.exception(msg)
            raise exc.HTTPBadRequest(msg)

        template = env_temps.EnvTemplateServices.update(env_template_id, body)
        return template.to_dict()
Beispiel #22
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:
                msg = _("Package schema is not valid: {reason}").format(
                    reason=e)
                LOG.exception(msg)
                raise exc.HTTPBadRequest(explanation=msg)
        else:
            package_meta = {}

        if package_meta.get('is_public'):
            policy.check('publicize_package', req.context)

        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(explanation=msg)
            tempf.write(content)
            package_meta['archive'] = content
        try:
            with load_utils.load_from_file(
                    tempf.name, target_dir=None,
                    drop_dir=True) as pkg_to_upload:
                # extend dictionary for update db
                for k, v in six.iteritems(PKG_PARAMS_MAP):
                    if hasattr(pkg_to_upload, k):
                        package_meta[v] = getattr(pkg_to_upload, k)
                if len(package_meta['name']) > 80:
                    msg = _('Package name should be 80 characters maximum')
                    LOG.error(msg)
                    raise exc.HTTPBadRequest(explanation=msg)
                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.HTTPConflict(msg)
                return package.to_dict()
        except pkg_exc.PackageLoadError as e:
            msg = _("Couldn't load package from file: {reason}").format(
                reason=e)
            LOG.exception(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        finally:
            LOG.debug("Deleting package archive temporary file")
            os.remove(tempf.name)
    def update(self, request, environment_id, body):
        """"Rename an environment."""
        LOG.debug('Environments:Update <Id: {id}, '
                  'Body: {body}>'.format(id=environment_id, body=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)
        new_name = six.text_type(body['name'])
        if new_name.strip():
            if len(new_name) > 255:
                msg = _('Environment name should be 255 characters maximum')
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)
            try:
                environment.update({'name': new_name})
                environment.save(session)
            except db_exc.DBDuplicateEntry:
                msg = _('Environment with specified name already exists')
                LOG.error(msg)
                raise exc.HTTPConflict(explanation=msg)
        else:
            msg = _('Environment name must contain at least one '
                    'non-white space symbol')
            LOG.error(msg)
            raise exc.HTTPClientError(explanation=msg)

        return environment.to_dict()
Beispiel #24
0
 def _load_package(self, pkg_loader, name):
     try:
         parts = name.rsplit('/')
         if len(parts) == 2:
             name, pkg_version = parts
             version_spec = helpers.parse_version_spec(pkg_version)
         else:
             version_spec = helpers.parse_version_spec('*')
         package = pkg_loader.load_package(name, version_spec)
     except exceptions.NoPackageFound:
         if not CONF.engine.load_packages_from:
             msg = _('Local package is not found since "load-packages-from"'
                     ' engine parameter is not provided and specified '
                     'packages is not loaded to murano-api')
         else:
             msg = _('Specified package is not found: {0} were scanned '
                     'together with murano database').format(','.join(
                         CONF.engine.load_packages_from))
         LOG.error(msg)
         self.error(msg, show_help=False)
     except exc.CommunicationError:
         msg = ('Murano API is not running. '
                'Check configuration parameters.')
         LOG.error(msg)
         self.error(msg, show_help=False)
     return package
Beispiel #25
0
    def update(self, request, environment_id, body):
        LOG.debug('Environments:Update <Id: {id}, '
                  'Body: {body}>'.format(id=environment_id, body=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)
        new_name = six.text_type(body['name'])
        if new_name.strip():
            if len(new_name) > 255:
                msg = _('Environment name should be 255 characters maximum')
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)
            try:
                environment.update(body)
                environment.save(session)
            except db_exc.DBDuplicateEntry:
                msg = _('Environment with specified name already exists')
                LOG.error(msg)
                raise exc.HTTPConflict(explanation=msg)
        else:
            msg = _('Environment name must contain at least one '
                    'non-white space symbol')
            LOG.error(msg)
            raise exc.HTTPClientError(explanation=msg)

        return environment.to_dict()
Beispiel #26
0
    def _load_image(self, file_name, default_name, what_image):
        full_path = path.secure_join(self._source_directory, file_name
                                     or default_name)
        if not os.path.isfile(full_path) and not file_name:
            return

        allowed_ftype = ('png', 'jpeg', 'gif')
        allowed_size = 500 * 1024
        try:

            if imghdr.what(full_path) not in allowed_ftype:
                msg = _('{0}: Unsupported Format. Only {1} allowed').format(
                    what_image, ', '.join(allowed_ftype))

                raise exceptions.PackageLoadError(msg)

            fsize = os.stat(full_path).st_size
            if fsize > allowed_size:
                msg = _('{0}: Uploaded image size {1} is too large. '
                        'Max allowed size is {2}').format(
                            what_image, fsize, allowed_size)
                raise exceptions.PackageLoadError(msg)

            with open(full_path, 'rb') as stream:
                return stream.read()

        except Exception as ex:
            trace = sys.exc_info()[2]
            utils.reraise(
                exceptions.PackageLoadError,
                exceptions.PackageLoadError('Unable to load {0}: {1}'.format(
                    what_image, ex)), trace)
    def create(self, request, body):
        LOG.debug("Environments:Create <Body {body}>".format(body=body))
        policy.check("create_environment", request.context)

        if not body.get("name"):
            msg = _("Please, specify a name of the environment to create")
            LOG.exception(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        name = unicode(body["name"])
        if len(name) > 255:
            msg = _("Environment name should be 255 characters maximum")
            LOG.exception(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        if VALID_NAME_REGEX.match(name):
            try:
                environment = envs.EnvironmentServices.create(body.copy(), request.context)
            except db_exc.DBDuplicateEntry:
                msg = _("Environment with specified name already exists")
                LOG.exception(msg)
                raise exc.HTTPConflict(explanation=msg)
        else:
            msg = _('Environment name must contain only alphanumeric or "_-." ' "characters, must start with alpha")
            LOG.exception(msg)
            raise exc.HTTPClientError(explanation=msg)

        return environment.to_dict()
Beispiel #28
0
    def show(self, request, environment_id, session_id):
        LOG.debug('Session:Show <SessionId: {id}>'.format(id=session_id))

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

        check_session(request, environment_id, session, session_id)

        user_id = request.context.user

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

        if not sessions.SessionServices.validate(session):
            msg = _('Session <SessionId {0}> is invalid: environment has been '
                    'updated or updating right now with other session').format(
                        session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        return session.to_dict()
Beispiel #29
0
 def create(self, request, body):
     """It creates the env template from the payload obtaining.
     This payload can contain just the template name, or include
     also service information.
     :param request: the operation request.
     :param body: the env template description
     :return: the description of the created template.
     """
     LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body))
     policy.check('create_env_template', request.context)
     try:
         LOG.debug('ENV TEMP NAME: {templ_name}>'.format(
             templ_name=body['name']))
         if not envs_api.VALID_NAME_REGEX.match(str(body['name'])):
             msg = _('Environment Template must contain only alphanumeric '
                     'or "_-." characters, must start with alpha')
             LOG.error(msg)
             raise exc.HTTPBadRequest(msg)
     except Exception:
             msg = _('Env template body is incorrect')
             LOG.exception(msg)
             raise exc.HTTPClientError(msg)
     if len(body['name']) > 255:
         msg = _('Environment Template name should be 255 characters '
                 'maximum')
         LOG.exception(msg)
         raise exc.HTTPBadRequest(explanation=msg)
     try:
         template = env_temps.EnvTemplateServices.create(
             body.copy(), request.context.tenant)
         return template.to_dict()
     except db_exc.DBDuplicateEntry:
         msg = _('Env Template with specified name already exists')
         LOG.exception(msg)
         raise exc.HTTPConflict(msg)
Beispiel #30
0
    def _load_image(self, file_name, default_name, what_image):
        full_path = os.path.join(
            self._source_directory, file_name or default_name)
        if not os.path.isfile(full_path) and not file_name:
            return

        allowed_ftype = ('png', 'jpeg', 'gif')
        allowed_size = 500 * 1024
        try:

            if imghdr.what(full_path) not in allowed_ftype:
                msg = _('{0}: Unsupported Format. Only {1} allowed').format(
                    what_image, ', '.join(allowed_ftype))

                raise exceptions.PackageLoadError(msg)

            fsize = os.stat(full_path).st_size
            if fsize > allowed_size:
                msg = _('{0}: Uploaded image size {1} is too large. '
                        'Max allowed size is {2}').format(
                    what_image, fsize, allowed_size)
                raise exceptions.PackageLoadError(msg)

            with open(full_path, 'rb') as stream:
                return stream.read()

        except Exception as ex:
            trace = sys.exc_info()[2]
            six.reraise(exceptions.PackageLoadError,
                        exceptions.PackageLoadError(
                            'Unable to load {0}: {1}'.format(what_image, ex)),
                        trace)
Beispiel #31
0
    def delete(self, request, environment_id, session_id):
        LOG.debug('Session:Delete <SessionId: {s_id}>'.format(s_id=session_id))

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

        check_session(request, environment_id, session, session_id)

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

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

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

        return None
Beispiel #32
0
    def _from_json_patch(self, datastring):
        try:
            operations = jsonutils.loads(datastring)
        except ValueError:
            msg = _("cannot understand JSON")
            raise exceptions.MalformedRequestBody(reason=msg)

        if not isinstance(operations, list):
            msg = _('JSON-patch must be a list.')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        changes = []
        for raw_change in operations:
            if not isinstance(raw_change, dict):
                msg = _('Operations must be JSON objects.')
                raise webob.exc.HTTPBadRequest(explanation=msg)

            (op, path) = self._parse_json_schema_change(raw_change)

            self._validate_path(path)
            change = {'op': op, 'path': path}

            change['value'] = self._get_change_value(raw_change, op)
            self._validate_change(change)

            changes.append(change)
        return changes
Beispiel #33
0
 def _load_package(self, pkg_loader, name):
     try:
         parts = name.rsplit('/')
         if len(parts) == 2:
             name, pkg_version = parts
             version_spec = helpers.parse_version_spec(pkg_version)
         else:
             version_spec = helpers.parse_version_spec('*')
         package = pkg_loader.load_package(name, version_spec)
     except exceptions.NoPackageFound:
         if not CONF.packages_opts.load_packages_from:
             msg = _('Local package is not found since "load-packages-from"'
                     ' engine parameter is not provided and specified '
                     'packages is not loaded to murano-api')
         else:
             msg = _('Specified package is not found: {0} were scanned '
                     'together with murano database'
                     ).format(','.join(
                         CONF.packages_opts.load_packages_from))
         LOG.error(msg)
         self.error(msg, show_help=False)
     except exc.CommunicationError:
         msg = ('Murano API is not running. '
                'Check configuration parameters.')
         LOG.error(msg)
         self.error(msg, show_help=False)
     return package
Beispiel #34
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        LOG.debug("{method} {url}\nHEADERS: {headers}".format(
            method=request.method,
            url=request.url,
            headers=self._format_request_headers(request.headers)))

        try:
            action, action_args, accept = self.deserialize_request(request)
        except exceptions.UnsupportedContentType:
            msg = _("Unsupported Content-Type")
            return webob.exc.HTTPUnsupportedMediaType(detail=msg)
        except exceptions.NotAcceptableContentType:
            msg = _("Acceptable response can not be provided")
            return webob.exc.HTTPNotAcceptable(detail=msg)
        except exceptions.MalformedRequestBody:
            msg = _("Malformed request body")
            return webob.exc.HTTPBadRequest(explanation=msg)

        with ResourceExceptionHandler():
            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
Beispiel #35
0
 def _get_category_filters(req):
     query_params = {}
     valid_query_params = ['sort_keys', 'sort_dir', 'limit', 'marker']
     for key, value in req.GET.items():
         if key not in valid_query_params:
             raise exc.HTTPBadRequest(
                 _('Bad value passed to filter. '
                   'Got {key}, exected:{valid}').format(
                     key=key, valid=', '.join(valid_query_params)))
         if key == 'sort_keys':
             available_sort_keys = ['name', 'created',
                                    'updated', 'package_count', 'id']
             value = [v.strip() for v in value.split(',')]
             for sort_key in value:
                 if sort_key not in available_sort_keys:
                     raise exc.HTTPBadRequest(
                         explanation=_('Invalid sort key: {sort_key}. '
                                       'Must be one of the following: '
                                       '{available}').format(
                             sort_key=sort_key,
                             available=', '.join(available_sort_keys)))
         if key == 'sort_dir':
             if value not in ['asc', 'desc']:
                 msg = _('Invalid sort direction: {0}').format(value)
                 raise exc.HTTPBadRequest(explanation=msg)
         query_params[key] = value
     return query_params
Beispiel #36
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=six.text_type(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=six.text_type(msg))

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

        try:
            jsonschema.validate(property_to_update, schemas.PKG_UPDATE_SCHEMA)
        except jsonschema.ValidationError as e:
            LOG.error(
                _LE("Schema validation error occured: {error}").format(
                    error=e))
            raise webob.exc.HTTPBadRequest(explanation=e.message)
Beispiel #37
0
    def clone(self, request, env_template_id, body):
        """Clones env template from another tenant

        It clones the env template from another env template
        from other tenant.
        :param request: the operation request.
        :param env_template_id: the env template ID.
        :param body: the request body.
        :return: the description of the created template.
        """

        LOG.debug('EnvTemplates:Clone <Env Template {1} for body {0}>'.
                  format(body, env_template_id))
        policy.check('clone_env_template', request.context)

        old_env_template = self._validate_exists(env_template_id)

        if not old_env_template.get('is_public'):
            msg = _('User has no access to these resources.')
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)
        self._validate_body_name(body)
        LOG.debug('ENV TEMP NAME: {0}'.format(body['name']))

        try:
            is_public = body.get('is_public', False)
            template = env_temps.EnvTemplateServices.clone(
                env_template_id, request.context.tenant, body['name'],
                is_public)
        except db_exc.DBDuplicateEntry:
            msg = _('Env template with specified name already exists')
            LOG.error(msg)
            raise exc.HTTPConflict(explanation=msg)

        return template.to_dict()
Beispiel #38
0
def run_tests(args):
    provided_pkg_name = args.package
    load_packages_from = args.load_packages_from
    tests_to_run = args.tests

    if not provided_pkg_name:
        msg = _('Package name is required parameter.')
        sys.stderr.write("ERROR: {msg}".format(msg=msg))
        sys.exit(1)

    ks_opts = _validate_keystone_opts(args)

    client = ks_client.Client(**ks_opts)
    test_env = environment.Environment()
    test_env.token = client.auth_token
    test_env.tenant_id = client.auth_tenant_id
    test_env.clients = client_manager.ClientManager(test_env)

    murano_client_factory = lambda: \
        test_env.clients.get_murano_client(test_env)

    # Replace location of loading packages with provided from command line.
    if load_packages_from:
        cfg.CONF.engine.load_packages_from = load_packages_from
    with package_loader.CombinedPackageLoader(
            murano_client_factory, client.tenant_id) as pkg_loader:
        engine.get_plugin_loader().register_in_loader(pkg_loader)
        exc = executor.MuranoDslExecutor(
            pkg_loader, engine.ContextManager(), test_env)

        package = _load_package(pkg_loader, provided_pkg_name)
        class_to_methods, class_to_obj = _get_all_test_methods(exc, package)

        run_set = _get_methods_to_run(package, tests_to_run, class_to_methods)
        if run_set:
            LOG.debug('Starting test execution.')
        else:
            msg = _('No tests found for execution.')
            LOG.error(msg)
            sys.stderr.write("ERROR: {msg}".format(msg=msg))
            sys.exit(1)

        for pkg_class, methods in run_set.iteritems():
            obj = class_to_obj[pkg_class]
            for m in methods:
                _call_service_method('setUp', exc, obj)
                obj.type.methods[m].usage = 'Action'

                test_env.start()
                try:
                    obj.type.invoke(m, exc, obj, (), {})
                    LOG.debug('\n.....{0}.{1}.....OK'.format(obj.type.name, m))
                    _call_service_method('tearDown', exc, obj)
                except Exception:
                    LOG.exception('\n.....{0}.{1}.....FAILURE\n'
                                  ''.format(obj.type.name, m))
                finally:
                    test_env.finish()
Beispiel #39
0
def run_tests(args):
    provided_pkg_name = args.package
    load_packages_from = args.load_packages_from
    tests_to_run = args.tests

    if not provided_pkg_name:
        msg = _('Package name is required parameter.')
        sys.stderr.write("ERROR: {msg}".format(msg=msg))
        sys.exit(1)

    ks_opts = _validate_keystone_opts(args)

    client = ks_client.Client(**ks_opts)
    test_env = environment.Environment()
    test_env.token = client.auth_token
    test_env.tenant_id = client.auth_tenant_id
    test_env.clients = client_manager.ClientManager(test_env)

    murano_client_factory = lambda: \
        test_env.clients.get_murano_client(test_env)

    # Replace location of loading packages with provided from command line.
    if load_packages_from:
        cfg.CONF.engine.load_packages_from = load_packages_from
    with package_loader.CombinedPackageLoader(murano_client_factory,
                                              client.tenant_id) as pkg_loader:
        engine.get_plugin_loader().register_in_loader(pkg_loader)
        exc = executor.MuranoDslExecutor(pkg_loader, engine.ContextManager(),
                                         test_env)

        package = _load_package(pkg_loader, provided_pkg_name)
        class_to_methods, class_to_obj = _get_all_test_methods(exc, package)

        run_set = _get_methods_to_run(package, tests_to_run, class_to_methods)
        if run_set:
            LOG.debug('Starting test execution.')
        else:
            msg = _('No tests found for execution.')
            LOG.error(msg)
            sys.stderr.write("ERROR: {msg}".format(msg=msg))
            sys.exit(1)

        for pkg_class, methods in run_set.iteritems():
            obj = class_to_obj[pkg_class]
            for m in methods:
                _call_service_method('setUp', exc, obj)
                obj.type.methods[m].usage = 'Action'

                test_env.start()
                try:
                    obj.type.invoke(m, exc, obj, (), {})
                    LOG.debug('\n.....{0}.{1}.....OK'.format(obj.type.name, m))
                    _call_service_method('tearDown', exc, obj)
                except Exception:
                    LOG.exception('\n.....{0}.{1}.....FAILURE\n'
                                  ''.format(obj.type.name, m))
                finally:
                    test_env.finish()
Beispiel #40
0
    def validate(self, model, class_loader=None):
        """Validate model using Congress rule engine.

        @type model: dict
        @param model: Dictionary representation of model starting on
                      environment level (['Objects'])
        @type class_loader: murano.dsl.class_loader.MuranoClassLoader
        @param class_loader: Optional. Used for evaluating parent class types
        @raises ValidationError in case validation was not successful
        """

        if model is None:
            return

        client = self._client_manager.get_congress_client(self._environment)
        if not client:
            raise ValueError(_('Congress client is not configured!'))

        LOG.info(_LI('Validating model'))
        LOG.debug(model)

        rules = congress_rules.CongressRulesManager().convert(
            model, class_loader, self._environment.tenant_id)

        rules_str = map(str, rules)
        env_id = model['?']['id']
        # cleanup of data populated by murano driver
        rules_str.insert(0, 'deleteEnv("{0}")'.format(env_id))

        rules_line = " ".join(rules_str)
        LOG.debug('Congress rules: \n  ' +
                  '\n  '.join(rules_str))

        validation_result = client.execute_policy_action(
            "murano_system",
            "simulate",
            False,
            False,
            {'query': 'predeploy_errors(eid, oid, msg)',
             'action_policy': 'murano_action',
             'sequence': rules_line})

        if validation_result["result"]:

            messages = self._parse_messages(env_id,
                                            validation_result["result"])

            if messages:
                result_str = "\n  ".join(map(str, messages))
                msg = _("Murano object model validation failed: {0}").format(
                    "\n  " + result_str)
                LOG.error(msg)
                raise ValidationError(msg)
        else:
            LOG.info(_LI('Model valid'))
Beispiel #41
0
def _authorize_package(package, context, allow_public=False):

    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(explanation=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(explanation=msg)
Beispiel #42
0
 def _validate_request(self, request, env_template_id):
     env_template_exists = env_temps.EnvTemplateServices.env_template_exist
     if not env_template_exists(env_template_id):
         mng = _("EnvTemplate <TempId {0}> is not found").format(env_template_id)
         LOG.exception(mng)
         raise exc.HTTPNotFound(explanation=mng)
     get_env_template = env_temps.EnvTemplateServices.get_env_template
     env_template = get_env_template(env_template_id)
     if env_template.tenant_id != request.context.tenant:
         LOG.exception(_("User is not authorized to access " "this tenant resources."))
         raise exc.HTTPUnauthorized
Beispiel #43
0
    def validate(self, model, class_loader=None):
        """Validate model using Congress rule engine.

        @type model: dict
        @param model: Dictionary representation of model starting on
                      environment level (['Objects'])
        @type class_loader: murano.dsl.class_loader.MuranoClassLoader
        @param class_loader: Optional. Used for evaluating parent class types
        @raises ValidationError in case validation was not successful
        """

        if model is None:
            return

        client = self._client_manager.get_congress_client(self._environment)
        if not client:
            raise ValueError(_('Congress client is not configured!'))

        LOG.info(_LI('Validating model'))
        LOG.debug(model)

        rules = congress_rules.CongressRulesManager().convert(
            model, class_loader, self._environment.tenant_id)

        rules_str = map(str, rules)
        env_id = model['?']['id']
        # cleanup of data populated by murano driver
        rules_str.insert(0, 'deleteEnv("{0}")'.format(env_id))

        rules_line = " ".join(rules_str)
        LOG.debug('Congress rules: \n  ' + '\n  '.join(rules_str))

        validation_result = client.execute_policy_action(
            "murano_system", "simulate", False, False, {
                'query': 'predeploy_errors(eid, oid, msg)',
                'action_policy': 'murano_action',
                'sequence': rules_line
            })

        if validation_result["result"]:

            messages = self._parse_messages(env_id,
                                            validation_result["result"])

            if messages:
                result_str = "\n  ".join(map(str, messages))
                msg = _("Murano object model validation failed: {0}").format(
                    "\n  " + result_str)
                LOG.error(msg)
                raise ValidationError(msg)
        else:
            LOG.info(_LI('Model valid'))
Beispiel #44
0
def _authorize_package(package, context, allow_public=False):

    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(explanation=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(explanation=msg)
Beispiel #45
0
 def _validate_request(self, request, env_template_id):
     env_template_exists = env_temps.EnvTemplateServices.env_template_exist
     if not env_template_exists(env_template_id):
         msg = _('EnvTemplate <TempId {temp_id}> is not found').format(
             temp_id=env_template_id)
         LOG.exception(msg)
         raise exc.HTTPNotFound(explanation=msg)
     get_env_template = env_temps.EnvTemplateServices.get_env_template
     env_template = get_env_template(env_template_id)
     if env_template.tenant_id != request.context.tenant:
         msg = _('User is not authorized to access this tenant resources')
         LOG.error(msg)
         raise exc.HTTPForbidden(explanation=msg)
Beispiel #46
0
    def _validate_body_name(self, body):

        if not('name' in body and body['name'].strip()):
            msg = _('Please, specify a name of the environment template.')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        name = six.text_type(body['name'])
        if len(name) > 255:
            msg = _('Environment template name should be 255 characters '
                    'maximum')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)
Beispiel #47
0
    def _validate_body_name(self, body):

        if not ('name' in body and body['name'].strip()):
            msg = _('Please, specify a name of the environment template.')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        name = str(body['name'])
        if len(name) > 255:
            msg = _('Environment template name should be 255 characters '
                    'maximum')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)
Beispiel #48
0
 def _validate_request(self, request, env_template_id):
     env_template_exists = env_temps.EnvTemplateServices.env_template_exist
     if not env_template_exists(env_template_id):
         msg = _('EnvTemplate <TempId {temp_id}> is not found').format(
             temp_id=env_template_id)
         LOG.exception(msg)
         raise exc.HTTPNotFound(explanation=msg)
     get_env_template = env_temps.EnvTemplateServices.get_env_template
     env_template = get_env_template(env_template_id)
     if env_template.tenant_id != request.context.tenant:
         msg = _('User is not authorized to access this tenant resources')
         LOG.error(msg)
         raise exc.HTTPForbidden(explanation=msg)
Beispiel #49
0
    def _check_session(self, request, 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)

        self._check_environment(request, environment_id)
Beispiel #50
0
 def _validate_request(self, request, env_template_id):
     env_template_exists = env_temps.EnvTemplateServices.env_template_exist
     if not env_template_exists(env_template_id):
         mng = _('EnvTemplate <TempId {0}> is not found').format(
             env_template_id)
         LOG.exception(mng)
         raise exc.HTTPNotFound(explanation=mng)
     get_env_template = env_temps.EnvTemplateServices.get_env_template
     env_template = get_env_template(env_template_id)
     if env_template.tenant_id != request.context.tenant:
         LOG.exception(_('User is not authorized to access '
                         'this tenant resources.'))
         raise exc.HTTPUnauthorized
Beispiel #51
0
    def _check_environment(self, request, 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)
Beispiel #52
0
    def _check_session(self, request, 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)

        self._check_environment(request, environment_id)
Beispiel #53
0
def check_env(request, environment_id):
    unit = db_session.get_session()
    environment = unit.query(models.Environment).get(environment_id)
    if environment is None:
        msg = _('Environment with id {0}' ' not found').format(environment_id)
        LOG.warning(msg)
        raise exc.HTTPNotFound(explanation=msg)

    if hasattr(request, 'context'):
        if environment.tenant_id != request.context.tenant:
            msg = _('User is not authorized to access'
                    ' these tenant resources')
            LOG.warning(msg)
            raise exc.HTTPForbidden(explanation=msg)
Beispiel #54
0
    def create_environment(self, request, env_template_id, body):
        """Creates environment and session from template.
        :param request: operation request
        :param env_template_id: environment template ID
        :param body: the environment name
        :return: session_id and environment_id
        """
        LOG.debug('Templates:Create environment <Id: {templ_id}>'.
                  format(templ_id=env_template_id))
        target = {"env_template_id": env_template_id}
        policy.check('create_environment', request.context, target)

        self._validate_request(request, env_template_id)
        template = env_temps.EnvTemplateServices.\
            get_env_template(env_template_id)

        if ('name' not in body or
                not envs_api.VALID_NAME_REGEX.match(str(body['name']))):
            msg = _('Environment must contain only alphanumeric '
                    'or "_-." characters, must start with alpha')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)
        LOG.debug('ENVIRONMENT NAME: {env_name}>'.format(
            env_name=body['name']))

        try:
            environment = envs.EnvironmentServices.create(
                body.copy(), request.context)
        except db_exc.DBDuplicateEntry:
            msg = _('Environment with specified name already exists')
            LOG.exception(msg)
            raise exc.HTTPConflict(explanation=msg)

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

        if self.has_services(template):
            services_node = utils.TraverseHelper.get("services",
                                                     template.description)
            utils.TraverseHelper.update("/Objects/services",
                                        services_node,
                                        environment.description)

        envs.EnvironmentServices.save_environment_description(
            session.id,
            environment.description,
            inner=False
        )
        return {"session_id": session.id, "environment_id": environment.id}
Beispiel #55
0
    def _check_environment(self, request, 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)
Beispiel #56
0
def check_env(request, environment_id):
    unit = db_session.get_session()
    environment = unit.query(models.Environment).get(environment_id)
    if environment is None:
        msg = _('Environment with id {0}'
                ' not found').format(environment_id)
        LOG.warning(msg)
        raise exc.HTTPNotFound(explanation=msg)

    if hasattr(request, 'context'):
        if environment.tenant_id != request.context.tenant:
            msg = _('User is not authorized to access'
                    ' these tenant resources')
            LOG.warning(msg)
            raise exc.HTTPForbidden(explanation=msg)
Beispiel #57
0
def check_session(request, environment_id, session, session_id):
    """Validate, that a session is ok."""
    if session is None:
        msg = _('Session <SessionId {id}> is not found').format(id=session_id)
        LOG.error(msg)
        raise exc.HTTPNotFound(explanation=msg)

    if session.environment_id != environment_id:
        msg = _('Session <SessionId {session_id}> is not tied '
                'with Environment <EnvId {environment_id}>').format(
                    session_id=session_id, environment_id=environment_id)
        LOG.error(msg)
        raise exc.HTTPBadRequest(explanation=msg)

    check_env(request, environment_id)
Beispiel #58
0
    def post_env_template_data(env_template_id, data, path):
        """It stores the template data inside the template
        description.
        :param env_template_id: The env_template_id to obtain the data
        :param data: the template description
        :param path: Id of service for which we checking status.
        :return: The template description
        """
        get_description = env_temp.EnvTemplateServices.get_description
        save_description = env_temp.EnvTemplateServices.save_description

        temp_description = get_description(env_template_id)
        if temp_description is None:
            msg = _('Environment Template <EnvId {id}> is not found').format(
                id=env_template_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if 'services' not in temp_description:
            temp_description['services'] = []

        if path == '/services':
            if isinstance(data, list):
                utils.TraverseHelper.extend(path, data, temp_description)
            else:
                utils.TraverseHelper.insert(path, data, temp_description)
        save_description(temp_description)
        return data
Beispiel #59
0
    def get_template_data(env_template_id, path):
        """It obtains the data for the template. It includes
        all the services. In case the path includes information
        such as the env_template_id, the information provided will
        be related to the entity specified in the path

        :param env_template_id: The env_template_id to obtain the data
        :param path: Id of service for which we checking status.
        :return: The template description
        """
        temp_description = env_temp.EnvTemplateServices.\
            get_description(env_template_id)

        if temp_description is None:
            return None

        if 'services' not in temp_description:
            return []

        result = utils.TraverseHelper.get(path, temp_description)
        if result is None:
            msg = _('Environment Template <EnvId {id}> is not found').format(
                id=env_template_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)
        return result
Beispiel #60
0
    def put(self, request, env_template_id, path, body):

        """It updates a service into a template.
        :param request: The operation request.
        :param env_template_id: the env template ID where the service
        belongs to.
        :param path: The path
        :param body: the information about the service
        :return: the service description updated.
        """
        LOG.debug('Applications:Put <EnvTempId: {templ_id}, Path: {path}, '
                  'Body: {body}>'.format(templ_id=env_template_id,
                                         body=body,
                                         path=path))

        put_data = core_services.CoreServices.put_data
        session_id = request.context.session

        try:
            result = put_data(env_template_id, session_id, body, path)
        except (KeyError, ValueError):
            msg = _('The template does not exist {templ_id}').format(
                templ_id=env_template_id)
            LOG.exception(msg)
            raise exc.HTTPNotFound(msg)
        return result