Example #1
0
def main():
    test_runner = MuranoTestRunner()
    try:
        if test_runner.args.config_file:
            default_config_files = [test_runner.args.config_file]
        else:
            default_config_files = cfg.find_config_files('murano')
            if not default_config_files:
                murano_conf = os.path.join(os.path.dirname(__file__),
                                           os.pardir,
                                           os.pardir,
                                           'etc', 'murano',
                                           'murano.conf')
                if os.path.exists(murano_conf):
                    default_config_files = [murano_conf]
        sys.argv = [sys.argv[0]]
        config.parse_args(default_config_files=default_config_files)
        logging.setup(CONF, 'murano')
    except RuntimeError as e:
        LOG.exception(_LE("Failed to initialize murano-test-runner: %s") % e)
        sys.exit("ERROR: %s" % e)

    try:
        exit_code = test_runner.run_tests()
        sys.exit(exit_code)
    except Exception as e:
        tb = traceback.format_exc()
        err_msg = _LE("Command failed: {0}\n{1}").format(e, tb)
        LOG.error(err_msg)
        sys.exit(err_msg)
def main():
    test_runner = MuranoTestRunner()
    try:
        if test_runner.args.config_file:
            default_config_files = [test_runner.args.config_file]
        else:
            default_config_files = cfg.find_config_files('murano')
            if not default_config_files:
                murano_conf = os.path.join(os.path.dirname(__file__),
                                           os.pardir, os.pardir, 'etc',
                                           'murano', 'murano.conf')
                if os.path.exists(murano_conf):
                    default_config_files = [murano_conf]
        sys.argv = [sys.argv[0]]
        config.parse_args(default_config_files=default_config_files)
        logging.setup(CONF, 'murano')
    except RuntimeError as e:
        LOG.exception(_LE("Failed to initialize murano-test-runner: %s") % e)
        sys.exit("ERROR: %s" % e)

    try:
        exit_code = test_runner.run_tests()
        sys.exit(exit_code)
    except Exception as e:
        tb = traceback.format_exc()
        err_msg = _LE("Command failed: {0}\n{1}").format(e, tb)
        LOG.error(err_msg)
        sys.exit(err_msg)
Example #3
0
    def test_get_muranoclient_without_urls(self, mock_glare_client,
                                           mock_muranoclient, mock_log):
        self._override_conf(without_urls=True)

        m_artifacts_client = mock.Mock()
        m_muranoclient = mock.Mock()
        mock_glare_client.Client.return_value = m_artifacts_client
        mock_muranoclient.Client.return_value = m_muranoclient
        mock_request = mock.Mock(endpoints={'murano': None})

        client = api._get_muranoclient(mock.sentinel.token_id, mock_request)

        self.assertEqual(m_muranoclient, client)
        mock_glare_client.Client.assert_called_once_with(
            endpoint=None, token=mock.sentinel.token_id,
            insecure=True, key_file='foo_key_file', ca_file='foo_ca_file',
            cert_file='foo_cert_file', type_name='murano', type_version=1)
        mock_muranoclient.Client.assert_called_once_with(
            1, None, token=mock.sentinel.token_id,
            artifacts_client=m_artifacts_client)
        mock_log.error.assert_has_calls([
            mock.call(_LE('No glare url is specified and no "artifact" '
                          'service is registered in keystone.')),
            mock.call(_LE('No murano url is specified and no '
                          '"application-catalog" service is registered in '
                          'keystone.'))
        ])
def verify_and_get_deployment(db_session, environment_id, deployment_id):
    deployment = db_session.query(models.Task).get(deployment_id)
    if not deployment:
        LOG.error(_LE('Deployment with id {id} not found')
                  .format(id=deployment_id))
        raise exc.HTTPNotFound
    if deployment.environment_id != environment_id:
        LOG.error(_LE('Deployment with id {d_id} not found in environment '
                      '{env_id}').format(d_id=deployment_id,
                                         env_id=environment_id))
        raise exc.HTTPBadRequest

    deployment.description = _patch_description(deployment.description)
    return deployment
Example #5
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.error(_LE('Deployment with id {id} not found')
                  .format(id=deployment_id))
        raise exc.HTTPNotFound
    if deployment.environment_id != environment_id:
        LOG.error(_LE('Deployment with id {d_id} not found in environment '
                      '{env_id}').format(d_id=deployment_id,
                                         env_id=environment_id))
        raise exc.HTTPBadRequest

    deployment.description = _patch_description(deployment.description)
    return deployment
Example #6
0
    def __inner(self, request, env_template_id, *args, **kwargs):
        unit = db_session.get_session()
        template = unit.query(models.EnvironmentTemplate).get(env_template_id)
        if template is None:
            LOG.error(_LE("Environment Template with id '{id}' not found").
                      format(id=env_template_id))
            raise exc.HTTPNotFound()

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

        return func(self, request, env_template_id, *args, **kwargs)
    def _migrate_up(self, engine, version, with_data=False):
        """Migrate up to a new version of the db.

        We allow for data insertion and post checks at every
        migration version with special _pre_upgrade_### and
        _check_### functions in the main test.
        """
        # NOTE(sdague): try block is here because it's impossible to debug
        # where a failed data migration happens otherwise
        check_version = version
        try:
            if with_data:
                data = None
                pre_upgrade = getattr(
                    self, "_pre_upgrade_%s" % check_version, None)
                if pre_upgrade:
                    data = pre_upgrade(engine)
            self._migrate(engine, version, 'upgrade')
            self.assertEqual(version, self._get_version_from_db(engine))
            if with_data:
                check = getattr(self, "_check_%s" % check_version, None)
                if check:
                    check(engine, data)
        except Exception:
            LOG.error(_LE("Failed to migrate to version {ver} on engine {eng}")
                      .format(ver=version, eng=engine))
            raise
Example #8
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 {0} for body {1}>'.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 = _LE('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 = _('Environment with specified name already exists')
            LOG.error(msg)
            raise exc.HTTPConflict(explanation=msg)

        return template.to_dict()
 def _parse_format_string(format_string):
     parts = format_string.rsplit('/', 1)
     if len(parts) != 2:
         LOG.error(
             _LE("Incorrect format name {name}").format(name=format_string))
         raise ValueError(format_string)
     return (parts[0].strip(), semantic_version.Version.coerce(parts[1]))
    def load_extension(self, extension, name_map):
        dist_name = str(extension.entry_point.dist)
        name = extension.entry_point.name
        if not NAME_RE.match(name):
            LOG.warning(
                _LW("Entry-point 'name' {name} is invalid").format(name=name))
            return
        name_map.setdefault(name, []).append(dist_name)
        if dist_name in self.packages:
            package = self.packages[dist_name]
        else:
            package = PackageDefinition(extension.entry_point.dist)
            self.packages[dist_name] = package

        plugin = extension.plugin
        try:
            package.classes[name] = initialize_plugin(plugin)
        except Exception:
            LOG.exception(
                _LE("Unable to initialize plugin for {name}").format(
                    name=name))
            return
        LOG.info(
            _LI("Loaded class {class_name} from {dist}").format(
                class_name=name, dist=dist_name))
Example #11
0
    def _validate_keystone_opts(self, args):
        ks_opts_to_config = {
            'auth_url': 'auth_uri',
            'username': '******',
            'password': '******',
            'project_name': 'admin_tenant_name'
        }

        ks_opts = {
            'auth_url': getattr(args, 'os_auth_url', None),
            'username': getattr(args, 'os_username', None),
            'password': getattr(args, 'os_password', None),
            'project_name': getattr(args, 'os_project_name', None)
        }

        if None in ks_opts.values() and not CONF.default_config_files:
            msg = _LE('Please provide murano config file or credentials for '
                      'authorization: {0}').format(', '.join([
                          '--os-auth-url', '--os-username', '--os-password',
                          '--os-project-name', '--os-tenant-id'
                      ]))
            LOG.error(msg)
            self.error(msg)
        # Load keystone configuration parameters from config
        importutils.import_module('keystonemiddleware.auth_token')

        for param, value in six.iteritems(ks_opts):
            if not value:
                ks_opts[param] = getattr(CONF.keystone_authtoken,
                                         ks_opts_to_config[param])
            if param == 'auth_url':
                ks_opts[param] = ks_opts[param].replace('v2.0', 'v3')
        return ks_opts
Example #12
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)
Example #13
0
    def _validate_keystone_opts(self, args):
        ks_opts_to_config = {
            'auth_url': 'auth_uri',
            'username': '******',
            'password': '******',
            'project_name': 'admin_tenant_name'}

        ks_opts = {'auth_url': getattr(args, 'os_auth_url', None),
                   'username': getattr(args, 'os_username', None),
                   'password': getattr(args, 'os_password', None),
                   'project_name': getattr(args, 'os_project_name', None)}

        if None in ks_opts.values() and not CONF.default_config_files:
            msg = _LE('Please provide murano config file or credentials for '
                      'authorization: {0}').format(
                ', '.join(['--os-auth-url', '--os-username', '--os-password',
                           '--os-project-name', '--os-tenant-id']))
            LOG.error(msg)
            self.error(msg)
        # Load keystone configuration parameters from config
        importutils.import_module('keystonemiddleware.auth_token')

        for param, value in six.iteritems(ks_opts):
            if not value:
                ks_opts[param] = getattr(CONF.keystone_authtoken,
                                         ks_opts_to_config[param])
            if param == 'auth_url':
                ks_opts[param] = ks_opts[param].replace('v2.0', 'v3')
        return ks_opts
Example #14
0
    def test_main_except_general_exception(self, mock_conf):
        mock_conf.command.func.side_effect = Exception

        expected_err_msg = _LE("murano-manage command failed:")

        with self.assertRaisesRegexp(SystemExit, expected_err_msg):
            manage.main()
Example #15
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)
Example #16
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()

        # 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(_LI('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(_LE('Session <SessionId {0}> '
                          'is invalid').format(session.id))
            raise exc.HTTPForbidden()

        task_id = actions.ActionServices.execute(
            action_id, session, unit, request.context.auth_token, body or {})
        return {'task_id': task_id}
Example #17
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 {0} for body {1}>'.
                  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 = _LE('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 = _('Environment with specified name already exists')
            LOG.error(msg)
            raise exc.HTTPConflict(explanation=msg)

        return template.to_dict()
Example #18
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()

        # 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(
                _LI(
                    "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(_LE("Session <SessionId {0}> " "is invalid").format(session.id))
            raise exc.HTTPForbidden()

        task_id = actions.ActionServices.execute(action_id, session, unit, request.context.auth_token, body or {})
        return {"task_id": task_id}
Example #19
0
    def _migrate_up(self, engine, version, with_data=False):
        """migrate up to a new version of the db.

        We allow for data insertion and post checks at every
        migration version with special _pre_upgrade_### and
        _check_### functions in the main test.
        """
        # NOTE(sdague): try block is here because it's impossible to debug
        # where a failed data migration happens otherwise
        check_version = version
        try:
            if with_data:
                data = None
                pre_upgrade = getattr(self, "_pre_upgrade_%s" % check_version,
                                      None)
                if pre_upgrade:
                    data = pre_upgrade(engine)
            self._migrate(engine, version, 'upgrade')
            self.assertEqual(version, self._get_version_from_db(engine))
            if with_data:
                check = getattr(self, "_check_%s" % check_version, None)
                if check:
                    check(engine, data)
        except Exception:
            LOG.error(
                _LE("Failed to migrate to version {ver} on engine {eng}").
                format(ver=version, eng=engine))
            raise
Example #20
0
 def finish(self):
     for delegate in self._tear_down_list:
         try:
             delegate()
         except Exception:
             LOG.exception(_LE("Unhandled exception on invocation of " "post-execution hook"))
     self._tear_down_list = []
Example #21
0
    def _check_enabled(self):
        if CONF.engine.disable_murano_agent:
            LOG.error(_LE("Use of murano-agent is disallowed " "by the server configuration"))

            raise exceptions.PolicyViolationException(
                "Use of murano-agent is disallowed " "by the server configuration"
            )
Example #22
0
 def start(self):
     for delegate in self._set_up_list:
         try:
             delegate()
         except Exception:
             LOG.exception(_LE("Unhandled exception on invocation of " "pre-execution hook"))
     self._set_up_list = []
Example #23
0
    def __inner(self, request, env_template_id, *args, **kwargs):
        unit = db_session.get_session()
        template = unit.query(models.EnvironmentTemplate).get(env_template_id)
        if template is None:
            LOG.error(
                _LE("Environment Template with id '{id}' not found").format(
                    id=env_template_id))
            raise exc.HTTPNotFound()

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

        return func(self, request, env_template_id, *args, **kwargs)
Example #24
0
    def _check_enabled(self):
        if CONF.engine.disable_murano_agent:
            LOG.error(_LE('Use of murano-agent is disallowed '
                          'by the server configuration'))

            raise exceptions.PolicyViolationException(
                'Use of murano-agent is disallowed '
                'by the server configuration')
Example #25
0
 def start(self):
     for delegate in self._set_up_list:
         try:
             delegate()
         except Exception:
             LOG.exception(_LE('Unhandled exception on invocation of '
                           'pre-execution hook'))
     self._set_up_list = []
Example #26
0
 def finish(self):
     for delegate in self._tear_down_list:
         try:
             delegate()
         except Exception:
             LOG.exception(_LE('Unhandled exception on invocation of '
                           'post-execution hook'))
     self._tear_down_list = []
Example #27
0
    def test_update_stats_handle_exception(self, mock_log, _):
        self.service._stats_db.update.side_effect =\
            Exception('test_error_code')

        self.service.update_stats()

        mock_log.exception.assert_called_once_with(
            _LE("Failed to get statistics object from a "
                "database. {error_code}").format(error_code='test_error_code'))
    def execute(self, request, body):
        policy.check("execute_action", request.context, {})

        class_name = body.get('className')
        method_name = body.get('methodName')
        if not class_name or not method_name:
            msg = _('Class name and method name must be specified for '
                    'static action')
            LOG.error(msg)
            raise exc.HTTPBadRequest(msg)

        args = body.get('parameters')
        pkg_name = body.get('packageName')
        class_version = body.get('classVersion', '=0')

        LOG.debug('StaticAction:Execute <MethodName: {0}, '
                  'ClassName: {1}>'.format(method_name, class_name))

        credentials = {
            'token': request.context.auth_token,
            'project_id': request.context.tenant,
            'user_id': request.context.user
        }

        try:
            return static_actions.StaticActionServices.execute(
                method_name, class_name, pkg_name, class_version, args,
                credentials)
        except client.RemoteError as e:
            LOG.error(
                _LE('Exception during call of the method {method_name}: '
                    '{exc}').format(method_name=method_name, exc=str(e)))
            if e.exc_type in ('NoClassFound', 'NoMethodFound',
                              'NoPackageFound', 'NoPackageForClassFound',
                              'MethodNotExposed', 'NoMatchingMethodException'):
                raise exc.HTTPNotFound(e.value)
            elif e.exc_type == 'ContractViolationException':
                raise exc.HTTPBadRequest(e.value)
            raise exc.HTTPServiceUnavailable(e.value)
        except ValueError as e:
            LOG.error(
                _LE('Exception during call of the method {method_name}: '
                    '{exc}').format(method_name=method_name, exc=str(e)))
            raise exc.HTTPBadRequest(e.message)
Example #29
0
def main():
    CONF.register_cli_opt(command_opt)

    try:
        default_config_files = cfg.find_config_files('murano', 'murano')
        CONF(sys.argv[1:], project='murano', prog='murano-manage',
             version=version.version_string,
             default_config_files=default_config_files)
    except RuntimeError as e:
        LOG.error(_LE("failed to initialize murano-manage: %s") % e)
        sys.exit("ERROR: %s" % e)

    try:
        CONF.command.func()
    except Exception as e:
        tb = traceback.format_exc()
        err_msg = _LE("murano-manage command failed: {0}\n{1}").format(e, tb)
        LOG.error(err_msg)
        sys.exit(err_msg)
Example #30
0
 def _validate_request(self, request, env_template_id):
     self._validate_exists(env_template_id)
     get_env_template = env_temps.EnvTemplateServices.get_env_template
     env_template = get_env_template(env_template_id)
     if env_template.is_public or request.context.is_admin:
         return
     if env_template.tenant_id != request.context.tenant:
         msg = _LE('User has no access to these resources.')
         LOG.error(msg)
         raise exc.HTTPForbidden(explanation=msg)
Example #31
0
 def _validate_request(self, request, env_template_id):
     self._validate_exists(env_template_id)
     get_env_template = env_temps.EnvTemplateServices.get_env_template
     env_template = get_env_template(env_template_id)
     if env_template.is_public or request.context.is_admin:
         return
     if env_template.tenant_id != request.context.tenant:
         msg = _LE('User has no access to these resources.')
         LOG.error(msg)
         raise exc.HTTPForbidden(explanation=msg)
 def _parse_format_string(format_string):
     parts = format_string.rsplit('/', 1)
     if len(parts) != 2:
         LOG.error(_LE("Incorrect format name {name}").format(
             name=format_string))
         raise ValueError(format_string)
     return (
         parts[0].strip(),
         semantic_version.Version.coerce(parts[1])
     )
Example #33
0
    def execute(self, request, body):
        policy.check("execute_action", request.context, {})

        class_name = body.get('className')
        method_name = body.get('methodName')
        if not class_name or not method_name:
            msg = _('Class name and method name must be specified for '
                    'static action')
            LOG.error(msg)
            raise exc.HTTPBadRequest(msg)

        args = body.get('parameters')
        pkg_name = body.get('packageName')
        class_version = body.get('classVersion', '=0')

        LOG.debug('StaticAction:Execute <MethodName: {0}, '
                  'ClassName: {1}>'.format(method_name, class_name))

        credentials = {
            'token': request.context.auth_token,
            'tenant_id': request.context.tenant
        }

        try:
            return static_actions.StaticActionServices.execute(
                method_name, class_name, pkg_name, class_version, args,
                credentials)
        except client.RemoteError as e:
            LOG.error(_LE('Exception during call of the method {method_name}: '
                          '{exc}').format(method_name=method_name, exc=str(e)))
            if e.exc_type in (
                    'NoClassFound', 'NoMethodFound', 'NoPackageFound',
                    'NoPackageForClassFound', 'MethodNotExposed',
                    'NoMatchingMethodException'):
                raise exc.HTTPNotFound(e.value)
            elif e.exc_type == 'ContractViolationException':
                raise exc.HTTPBadRequest(e.value)
            raise exc.HTTPServiceUnavailable(e.value)
        except ValueError as e:
            LOG.error(_LE('Exception during call of the method {method_name}: '
                          '{exc}').format(method_name=method_name, exc=str(e)))
            raise exc.HTTPBadRequest(e.message)
Example #34
0
    def _execute(self, pkg_loader):
        class_loader = package_class_loader.PackageClassLoader(pkg_loader)
        system_objects.register(class_loader, pkg_loader)
        get_plugin_loader().register_in_loader(class_loader)

        exc = executor.MuranoDslExecutor(class_loader, self.environment)
        obj = exc.load(self.model)

        self._validate_model(obj, self.action, class_loader)
        action_result = None
        exception = None
        exception_traceback = None
        try:
            LOG.info(_LI('Invoking pre-execution hooks'))
            self.environment.start()
            # Skip execution of action in case no action is provided.
            # Model will be just loaded, cleaned-up and unloaded.
            # Most of the time this is used for deletion of environments.
            if self.action:
                action_result = self._invoke(exc)
        except Exception as e:
            exception = e
            if isinstance(e, dsl_exception.MuranoPlException):
                LOG.error('\n' + e.format(prefix='  '))
            else:
                exception_traceback = traceback.format_exc()
                LOG.exception(
                    _LE("Exception %(exc)s occured"
                        " during invocation of %(method)s"),
                    {'exc': e, 'method': self.action['method']})
            reporter = status_reporter.StatusReporter()
            reporter.initialize(obj)
            reporter.report_error(obj, str(e))
        finally:
            LOG.info(_LI('Invoking post-execution hooks'))
            self.environment.finish()

        model = serializer.serialize_model(obj, exc)
        model['SystemData'] = self._environment.system_attributes
        result = {
            'model': model,
            'action': {
                'result': None,
                'isException': False
            }
        }
        if exception is not None:
            result['action'] = TaskExecutor.exception_result(
                exception, exception_traceback)
        else:
            result['action']['result'] = serializer.serialize_object(
                action_result)

        return result
Example #35
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:
         LOG.exception(_LE('User is not authorized to access this tenant '
                           'resources.'))
         raise exc.HTTPUnauthorized
Example #36
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:
         LOG.exception(
             _LE('User is not authorized to access this tenant '
                 'resources.'))
         raise exc.HTTPUnauthorized
Example #37
0
def _get_muranoclient(token_id, req):

    artifacts_client = None
    if CONF.engine.packages_service in ['glance', 'glare']:
        artifacts_client = _get_glareclient(token_id, req)

    murano_url = CONF.murano.url or req.endpoints.get('murano')
    if not murano_url:
        LOG.error(_LE('No murano url is specified and no '
                      '"application-catalog" '
                      'service is registered in keystone.'))

    return muranoclient.Client(1, murano_url, token=token_id,
                               artifacts_client=artifacts_client)
    def test_get_package_by_definition_except_package_load_error(
            self, mock_load_utils, mock_os, mock_log):
        # Test that the first instance of the exception is caught.
        temp_directory = tempfile.mkdtemp(prefix='test-package-loader-',
                                          dir=tempfile.tempdir)
        mock_os.path.isdir.return_value = True
        mock_os.path.join.return_value = temp_directory
        mock_load_utils.load_from_dir.side_effect = pkg_exc.PackageLoadError

        fqn = 'io.murano.apps.test'
        path, _ = utils.compose_package(
            'test', self.location, archive_dir=self.location)
        with open(path, 'rb') as f:
            package_data = f.read()

        package = mock.MagicMock()
        package.fully_qualified_name = fqn
        package.id = '123'
        package.version = '0.0.1'

        self.murano_client.packages.download = mock.MagicMock(
            return_value=package_data)

        self.loader._get_package_by_definition(package)

        mock_log.exception.assert_called_once_with(
            _LE('Unable to load package from cache. Clean-up.'))
        mock_log.exception.reset_mock()

        # Test that the second instance of the exception is caught.
        mock_os.path.isdir.return_value = [False, True]

        self.loader._get_package_by_definition(package)

        mock_log.exception.assert_called_once_with(
            _LE('Unable to load package from cache. Clean-up.'))
        os.remove(temp_directory)
Example #39
0
    def __exit__(self, ex_type, ex_value, ex_traceback):
        if not ex_value:
            return True

        # TODO(lin.a.yang): current only handle TypeError here, we should
        # process other kind of internal exceptions generated by API and
        # convert to webob exceptions.
        if isinstance(ex_value, TypeError):
            exc_info = (ex_type, ex_value, ex_traceback)
            LOG.error(_LE("Exception handling resource: {0}").format(ex_value),
                      exc_info=exc_info)
            raise webob.exc.HTTPBadRequest()

        # We didn't handle this kind of exception
        return False
Example #40
0
 def _log_exception(e, root, method_name):
     if isinstance(e, dsl_exception.MuranoPlException):
         LOG.error('\n' + e.format(prefix='  '))
         exception_traceback = e.format()
     else:
         exception_traceback = traceback.format_exc()
         LOG.exception(
             _LE("Exception %(exc)s occurred"
                 " during invocation of %(method)s"),
             {'exc': e, 'method': method_name})
     if root is not None:
         reporter = status_reporter.StatusReporter()
         reporter.initialize(root)
         reporter.report_error(root, str(e))
     return exception_traceback
Example #41
0
 def wrap(*args, **kwargs):
     try:
         ts = time.time()
         result = func(*args, **kwargs)
         te = time.time()
         tenant = args[1].context.tenant
         update_count(api, method, te - ts,
                      tenant)
         return result
     except Exception:
         te = time.time()
         tenant = args[1].context.tenant
         LOG.exception(_LE('API {api} method {method} raised an '
                           'exception').format(api=api, method=method))
         update_error_count(api, method, te - te, tenant)
         raise
Example #42
0
 def wrap(*args, **kwargs):
     try:
         ts = time.time()
         result = func(*args, **kwargs)
         te = time.time()
         tenant = args[1].context.tenant
         update_count(api, method, te - ts, tenant)
         return result
     except Exception:
         te = time.time()
         tenant = args[1].context.tenant
         LOG.exception(
             _LE('API {0} method {1} raised an exception').format(
                 api, method))
         update_error_count(api, method, te - te, tenant)
         raise
Example #43
0
    def test_do_import_package_without_update(self, mock_db_catalog_api,
                                              mock_load_utils, mock_log):
        mock_db_catalog_api.package_search.return_value =\
            [self.test_package]
        mock_load_utils.load_from_dir.return_value =\
            mock.MagicMock(full_name='test_full_name')
        manage.CONF = mock.MagicMock()
        manage.CONF.command = mock.MagicMock(directory='test_dir',
                                             categories=[],
                                             update=False)

        manage.do_import_package()

        mock_log.error.assert_called_once_with(
            _LE("Package '{name}' exists ({pkg_id}). Use --update.").format(
                name='test_full_name', pkg_id=self.test_package.id))
Example #44
0
def _get_glareclient(token_id, req):
    glare_settings = CONF.glare

    url = glare_settings.url or req.endpoints.get('glare')
    if not url:
        LOG.error(_LE('No glare url is specified and no "artifact" '
                  'service is registered in keystone.'))

    return glare_client.Client(
        endpoint=url, token=token_id,
        insecure=glare_settings.insecure,
        key_file=glare_settings.key_file or None,
        ca_file=glare_settings.ca_file or None,
        cert_file=glare_settings.cert_file or None,
        type_name='murano',
        type_version=1)
Example #45
0
def _do_import_package(_dir, categories, update=False):
    LOG.debug("Going to import Murano package from {source}".format(
        source=_dir))
    pkg = load_utils.load_from_dir(_dir)

    LOG.debug("Checking for existing packages")
    existing = db_catalog_api.package_search(
        {'fqn': pkg.full_name},
        AdminContext())
    if existing:
        existing_pkg = existing[0]
        if update:
            LOG.debug('Deleting existing package {exst_pkg_id}').format(
                exst_pkg_id=existing_pkg.id)
            db_catalog_api.package_delete(existing_pkg.id, AdminContext())
        else:
            LOG.error(_LE("Package '{name}' exists ({pkg_id}). Use --update.")
                      .format(name=pkg.full_name, pkg_id=existing_pkg.id))
            return

    package = {
        'fully_qualified_name': pkg.full_name,
        'type': pkg.package_type,
        'author': pkg.author,
        'supplier': pkg.supplier,
        'name': pkg.display_name,
        'description': pkg.description,
        # note: we explicitly mark all the imported packages as public,
        # until a parameter added to control visibility scope of a package
        'is_public': True,
        'tags': pkg.tags,
        'logo': pkg.logo,
        'supplier_logo': pkg.supplier_logo,
        'ui_definition': pkg.ui,
        'class_definitions': pkg.classes,
        'archive': pkg.blob,
        'categories': categories or []
    }

    # note(ruhe): the second parameter is tenant_id
    # it is a required field in the DB, that's why we pass an empty string
    result = db_catalog_api.package_upload(package, '')

    LOG.info(_LI("Finished import of package {res_id}").format(
        res_id=result.id))
Example #46
0
def _do_import_package(_dir, categories, update=False):
    LOG.debug(
        "Going to import Murano package from {source}".format(source=_dir))
    pkg = load_utils.load_from_dir(_dir)

    LOG.debug("Checking for existing packages")
    existing = db_catalog_api.package_search({'fqn': pkg.full_name},
                                             AdminContext())
    if existing:
        existing_pkg = existing[0]
        if update:
            LOG.debug('Deleting existing package {exst_pkg_id}').format(
                exst_pkg_id=existing_pkg.id)
            db_catalog_api.package_delete(existing_pkg.id, AdminContext())
        else:
            LOG.error(
                _LE("Package '{name}' exists ({pkg_id}). Use --update.").
                format(name=pkg.full_name, pkg_id=existing_pkg.id))
            return

    package = {
        'fully_qualified_name': pkg.full_name,
        'type': pkg.package_type,
        'author': pkg.author,
        'supplier': pkg.supplier,
        'name': pkg.display_name,
        'description': pkg.description,
        # note: we explicitly mark all the imported packages as public,
        # until a parameter added to control visibility scope of a package
        'is_public': True,
        'tags': pkg.tags,
        'logo': pkg.logo,
        'supplier_logo': pkg.supplier_logo,
        'ui_definition': pkg.ui,
        'class_definitions': pkg.classes,
        'archive': pkg.blob,
        'categories': categories or []
    }

    # note(ruhe): the second parameter is tenant_id
    # it is a required field in the DB, that's why we pass an empty string
    result = db_catalog_api.package_upload(package, '')

    LOG.info(
        _LI("Finished import of package {res_id}").format(res_id=result.id))
Example #47
0
        def f_retry(*args, **kwargs):
            mtries, mdelay = tries, delay
            forever = mtries == -1
            while forever or mtries > 1:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck as e:
                    LOG.exception(_LE("An exception occurred {exc}. Retrying "
                                      "in {time} seconds").format(exc=e,
                                                                  time=mdelay))
                    eventlet.sleep(mdelay)

                    if not forever:
                        mtries -= 1

                    if mdelay < 60:
                        mdelay *= backoff
            return f(*args, **kwargs)
Example #48
0
    def _get_package_by_definition(self, package_def):
        package_id = package_def.id
        package_name = package_def.fully_qualified_name
        package_directory = os.path.join(self._cache_directory, package_name)

        if os.path.exists(package_directory):
            try:
                return load_utils.load_from_dir(
                    package_directory, preload=True,
                    loader=yaql_yaml_loader.YaqlYamlLoader)
            except pkg_exc.PackageLoadError:
                LOG.exception(_LE(
                    'Unable to load package from cache. Clean-up...'))
                shutil.rmtree(package_directory, ignore_errors=True)
        try:
            package_data = self._murano_client_factory().packages.download(
                package_id)
        except muranoclient_exc.HTTPException as e:
            msg = 'Error loading package id {0}: {1}'.format(
                package_id, str(e)
            )
            exc_info = sys.exc_info()
            raise pkg_exc.PackageLoadError(msg), None, exc_info[2]
        package_file = None
        try:
            with tempfile.NamedTemporaryFile(delete=False) as package_file:
                package_file.write(package_data)

            return load_utils.load_from_file(
                package_file.name,
                target_dir=package_directory,
                drop_dir=False,
                loader=yaql_yaml_loader.YaqlYamlLoader
            )
        except IOError:
            msg = 'Unable to extract package data for %s' % package_id
            exc_info = sys.exc_info()
            raise pkg_exc.PackageLoadError(msg), None, exc_info[2]
        finally:
            try:
                if package_file:
                    os.remove(package_file.name)
            except OSError:
                pass
Example #49
0
    def _get_package_by_definition(self, package_def):
        package_id = package_def.id
        package_name = package_def.fully_qualified_name
        package_directory = os.path.join(self._cache_directory, package_name)

        if os.path.exists(package_directory):
            try:
                return load_utils.load_from_dir(
                    package_directory,
                    preload=True,
                    loader=yaql_yaml_loader.YaqlYamlLoader)
            except pkg_exc.PackageLoadError:
                LOG.exception(
                    _LE('Unable to load package from cache. Clean-up...'))
                shutil.rmtree(package_directory, ignore_errors=True)
        try:
            package_data = self._murano_client_factory().packages.download(
                package_id)
        except muranoclient_exc.HTTPException as e:
            msg = 'Error loading package id {0}: {1}'.format(
                package_id, str(e))
            exc_info = sys.exc_info()
            raise pkg_exc.PackageLoadError(msg), None, exc_info[2]
        package_file = None
        try:
            with tempfile.NamedTemporaryFile(delete=False) as package_file:
                package_file.write(package_data)

            return load_utils.load_from_file(
                package_file.name,
                target_dir=package_directory,
                drop_dir=False,
                loader=yaql_yaml_loader.YaqlYamlLoader)
        except IOError:
            msg = 'Unable to extract package data for %s' % package_id
            exc_info = sys.exc_info()
            raise pkg_exc.PackageLoadError(msg), None, exc_info[2]
        finally:
            try:
                if package_file:
                    os.remove(package_file.name)
            except OSError:
                pass
Example #50
0
    def handle_task(context, task):
        s_task = token_sanitizer.TokenSanitizer().sanitize(task)
        LOG.info(_LI('Starting processing task: {task_desc}').format(
            task_desc=jsonutils.dumps(s_task)))

        result = {'model': task['model']}
        try:
            task_executor = TaskExecutor(task)
            result = task_executor.execute()
        except Exception as e:
            LOG.exception(_LE('Error during task execution for tenant %s'),
                          task['tenant_id'])
            result['action'] = TaskExecutor.exception_result(e)
            msg_env = Environment(task['id'])
            reporter = status_reporter.StatusReporter()
            reporter.initialize(msg_env)
            reporter.report_error(msg_env, str(e))
        finally:
            rpc.api().process_result(result, task['id'])
Example #51
0
 def wrap(*args, **kwargs):
     try:
         ts = time.time()
         result = None
         if (api == 'Environments' and method == 'Show'):
             environment_id = kwargs.get('environment_id')
             if environment_id in specs:
                 request = args[1]
                 unit = db_session.get_session()
                 environment = unit.query(models.Environment).get(environment_id)
                 result = environment.to_dict()
                 result['status'] = states.EnvironmentStatus.READY
                 result['acquired_by'] = None
                 schedules = unit.query(models.Session).filter_by(environment_id=environment_id, user_id=request.context.user)
                 result['services'] = []
                 for session in schedules:
                     if session is not None and session.description['Objects'].has_key('services'):
                         services = session.description['Objects']['services']
                         for service in services:
                             service['?']['status'] = session.state
                             service['?']['id'] = session.id
                         result['services'].extend(services)
         elif (api == 'Sessions' and method == 'Create'):
             environment_id = kwargs.get('environment_id')
             if environment_id in specs:
                 result = my_session_create(environment_id, args[1]).to_dict()
         elif (api == 'Services' and method == 'Create'):
             environment_id = kwargs.get('environment_id')
             if environment_id in specs:
                 request = args[1]
                 result = my_post_data(environment_id, request.context.session, kwargs.get('body'), kwargs.get('path'), request)
         if result is None:
             result = func(*args, **kwargs)
         te = time.time()
         tenant = args[1].context.tenant
         request_statistics.update_count(api, method, te - ts, tenant)
         return result
     except Exception:
         te = time.time()
         tenant = args[1].context.tenant
         LOG.exception(_LE('API {api} method {method} raised an exception').format(api=api, method=method))
         request_statistics.update_error_count(api, method, te - te, tenant)
         raise
Example #52
0
    def _build_index(self):
        for entry in os.listdir(self._base_path):
            folder = os.path.join(self._base_path, entry)
            if not os.path.isdir(folder) or entry in self._processed_entries:
                continue

            try:
                package = load_utils.load_from_dir(
                    folder, preload=True,
                    loader=yaql_yaml_loader.YaqlYamlLoader)
            except pkg_exc.PackageLoadError:
                LOG.exception(_LE('Unable to load package from path: '
                                  '{0}').format(entry))
                continue

            for c in package.classes:
                self._packages_by_class[c] = package
            self._packages_by_name[package.full_name] = package

            self._processed_entries.add(entry)
Example #53
0
    def exception_result(self, exception, root, method_name):
        if isinstance(exception, dsl_exception.MuranoPlException):
            LOG.error('\n' + exception.format(prefix='  '))
            exception_traceback = exception.format()
        else:
            exception_traceback = traceback.format_exc()
            LOG.exception(
                _LE("Exception %(exc)s occurred"
                    " during invocation of %(method)s"),
                {'exc': exception, 'method': method_name})
        self._reporter.report_error(root, str(exception))

        return {
            'action': {
                'isException': True,
                'result': {
                    'message': str(exception),
                    'details': exception_traceback
                }
            }
        }
Example #54
0
    def update_stats(self):
        LOG.debug("Updating statistic information.")
        LOG.debug("Stats object: {stats}".format(stats=v1.stats))
        LOG.debug("Stats: Requests:{amount}  Errors: {error}"
                  "Ave.Res.Time {time:2.4f}\n Per tenant: {req_count}".format(
                      amount=v1.stats.request_count,
                      error=v1.stats.error_count,
                      time=v1.stats.average_time,
                      req_count=v1.stats.requests_per_tenant))
        try:
            stats = self._stats_db.get_stats_by_host(self._hostname)
            if stats is None:
                self._stats_db.create(self._hostname,
                                      v1.stats.request_count,
                                      v1.stats.error_count,
                                      v1.stats.average_time,
                                      v1.stats.requests_per_tenant,
                                      psutil.NUM_CPUS,
                                      psutil.cpu_percent())
                return

            now = time.time()
            t_delta = now - self._prev_time
            requests_per_second = (v1.stats.request_count -
                                   stats.request_count) / t_delta
            errors_per_second = (v1.stats.error_count -
                                 stats.error_count) / t_delta
            self._prev_time = now
            stats.request_count = v1.stats.request_count
            stats.error_count = v1.stats.error_count
            stats.average_response_time = v1.stats.average_time
            stats.requests_per_tenant = json.dumps(v1.stats.
                                                   requests_per_tenant)
            stats.requests_per_second = requests_per_second
            stats.errors_per_second = errors_per_second
            stats.cpu_percent = psutil.cpu_percent()
            self._stats_db.update(self._hostname, stats)
        except Exception as e:
            LOG.exception(_LE("Failed to get statistics object from a "
                              "database. {error_code}").format(error_code=e))
Example #55
0
    def update_stats(self):
        LOG.debug("Updating statistic information.")
        LOG.debug("Stats object: %s" % v1.stats)
        LOG.debug("Stats: Requests:%s  Errors: %s Ave.Res.Time %2.4f\n"
                  "Per tenant: %s" %
                  (v1.stats.request_count,
                   v1.stats.error_count,
                   v1.stats.average_time,
                   v1.stats.requests_per_tenant))
        try:
            stats = self._stats_db.get_stats_by_host(self._hostname)
            if stats is None:
                self._stats_db.create(self._hostname,
                                      v1.stats.request_count,
                                      v1.stats.error_count,
                                      v1.stats.average_time,
                                      v1.stats.requests_per_tenant,
                                      psutil.NUM_CPUS,
                                      psutil.cpu_percent())
                return

            now = time.time()
            t_delta = now - self._prev_time
            requests_per_second = (v1.stats.request_count -
                                   stats.request_count) / t_delta
            errors_per_second = (v1.stats.error_count -
                                 stats.error_count) / t_delta
            self._prev_time = now
            stats.request_count = v1.stats.request_count
            stats.error_count = v1.stats.error_count
            stats.average_response_time = v1.stats.average_time
            stats.requests_per_tenant = json.dumps(v1.stats.
                                                   requests_per_tenant)
            stats.requests_per_second = requests_per_second
            stats.errors_per_second = errors_per_second
            stats.cpu_percent = psutil.cpu_percent()
            self._stats_db.update(self._hostname, stats)
        except Exception as e:
            LOG.exception(_LE("Failed to get statistics object "
                          "form a database. %s"), e)
Example #56
0
    def load_extension(self, extension, name_map):
        dist_name = str(extension.entry_point.dist)
        name = extension.entry_point.name
        if not NAME_RE.match(name):
            LOG.warning(_LW("Entry-point 'name' %s is invalid") % name)
            return
        name = "%s.%s" % (self.namespace, name)
        name_map.setdefault(name, []).append(dist_name)
        if dist_name in self.packages:
            package = self.packages[dist_name]
        else:
            package = PackageDefinition(extension.entry_point.dist)
            self.packages[dist_name] = package

        plugin = extension.plugin
        try:
            package.classes[name] = initialize_plugin(plugin)
        except Exception:
            LOG.exception(_LE("Unable to initialize plugin for %s") % name)
            return
        LOG.info(_LI("Loaded class '%(class_name)s' from '%(dist)s'")
                 % dict(class_name=name, dist=dist_name))
Example #57
0
    def deserialize_body(self, request, action):
        if not len(request.body) > 0:
            LOG.debug("Empty body provided in request")
            return {}

        try:
            content_type = request.get_content_type()
        except exceptions.UnsupportedContentType as e:
            LOG.error(_LE("Unrecognized Content-Type provided in request: " "{error}").format(error=str(e)))
            raise

        if content_type is None:
            LOG.debug("No Content-Type provided in request")
            return {}

        try:
            deserializer = self.get_body_deserializer(content_type)
        except exceptions.UnsupportedContentType:
            LOG.debug("Unable to deserialize body as provided Content-Type")
            raise

        return deserializer.deserialize(request, action)