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

        try:
            action_args = self.get_action_args(request.environ)
            action = action_args.pop('action', None)
            deserialized_request = self.deserialize_request(request)
            action_args.update(deserialized_request)
        except exception.InvalidContentType:
            msg = _("Unsupported Content-Type")
            return webob.exc.HTTPUnsupportedMediaType(explanation=msg)
        except exception.MalformedRequestBody:
            msg = _("Malformed request body")
            return webob.exc.HTTPBadRequest(explanation=msg)

        action_result = self.execute_action(action, request, **action_args)

        try:
            response = webob.Response(request=request)
            self.dispatch(self.serializer, action, response, action_result)
            return response
        # return unserializable result (typically a webob exc)
        except Exception:
            try:
                err_body = action_result.get_unserialized_body()
                self.serializer.default(action_result, err_body)
            except Exception:
                LOG.warning(_LW("Unable to serialize exception response"))
            return action_result
Beispiel #2
0
def load_paste_app(app_name=None):
    """Builds and returns a WSGI app from a paste config file.

    We assume the last config file specified in the supplied ConfigOpts
    object is the paste config file.

    :param app_name: name of the application to load

    :raises RuntimeError when config file cannot be located or application
            cannot be loaded from config file
    """
    if app_name is None:
        app_name = CONF.prog

    app_name += _get_deployment_flavor()
    conf_file = _get_deployment_config_file()
    if conf_file is None:
        raise RuntimeError(_("Unable to locate config file"))

    try:
        LOG.debug("Loading %(app_name)s from %(conf_file)s" %
                  {'conf_file': conf_file, 'app_name': app_name})
        app = wsgi.paste_deploy_app(conf_file, app_name, cfg.CONF)
        return app
    except (LookupError, ImportError) as e:
        msg = _("Unable to load %(app_name)s from configuration file "
                "%(conf_file)s. \nGot: %(e)r") % \
              {'conf_file': conf_file, 'app_name': app_name, 'e': e}
        LOG.error(msg)
        raise RuntimeError(msg)
Beispiel #3
0
 def _validate_auth_url(self, auth_url):
     """Validate auth_url to ensure it can be used."""
     if not auth_url:
         raise exc.HTTPBadRequest(_("Request missing required header " "X-Auth-Url"))
     allowed = cfg.CONF.auth_password.allowed_auth_uris
     if auth_url not in allowed:
         raise exc.HTTPUnauthorized(_('Header X-Auth-Url "%s" not ' "an allowed endpoint") % auth_url)
     return True
Beispiel #4
0
    def _get_socket(host, port, backlog):
        info = socket.getaddrinfo(
            host, port, socket.AF_UNSPEC, socket.SOCK_STREAM
        )[0]
        family = info[0]
        bind_addr = info[-1]

        sock = None
        retry_until = time.time() + 30
        while not sock and time.time() < retry_until:
            try:
                sock = eventlet.listen(bind_addr, backlog=backlog,
                                       family=family)
                if sslutils.is_enabled(CONF):
                    sock = sslutils.wrap(CONF, sock)

            except socket.error as err:
                if err.args[0] != errno.EADDRINUSE:
                    raise
        if not sock:
            raise RuntimeError(_(
                "Could not bind to %(host)s:%(port)s "
                "after trying for 30 seconds") %
                               {'host': host, 'port': port})
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # sockets can hang around forever without keepalive
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

        # This option isn't available in the OS X version of eventlet
        if hasattr(socket, 'TCP_KEEPIDLE'):
            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE,
                            CONF.tcp_keepidle)

        return sock
Beispiel #5
0
    def deprecated(self, msg, *args, **kwargs):
        """Call this method when a deprecated feature is used.

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

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

        :param kwargs:
        :param args:
        :param msg:
        :raises: :class:`DeprecatedConfig` if the system is configured for
                 fatal deprecations.

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

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

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

        sent_args.append(args)
        self.warn(stdmsg, *args, **kwargs)
Beispiel #6
0
    def validate(request, body):
        """ Validate the given cookbook
        :param request: request context
        :param body: a json with deployment parameters
        :return : a json file with process results
        """
        body = body or {}
        if len(body) < 1:
            raise exc.HTTPBadRequest(_("No action specified"))
        try:
            cookbook = body['cookbook']
            image = body['image']
        except KeyError:
            raise exc.HTTPBadRequest(_("Insufficient payload"))

        LOG.info(_LI('Processing Request for cookbook %s, image %s' % (cookbook, image)))
        res = ValidateEngine().validate_chef_cookbook(cookbook, image, request)
        return res
Beispiel #7
0
def _get_deployment_config_file():
    """Retrieve the deployment_config_file config item, formatted as an
       absolute pathname.
    """
    path = CONF.paste_deploy.config_file
    if CONF.debug:
        return os.path.abspath(os.path.join(CONF.config_dir, path))
    if not path:
        path = _get_paste_config_path()
    if not path:
        msg = _("Unable to locate paste config file for %s.") % CONF.prog
        raise RuntimeError(msg)
    return os.path.abspath(path)
Beispiel #8
0
 def run_deploy(self, cookbook):
     """ Run cookbook deployment
     :param cookbook: cookbook to deploy
     :return msg: dictionary with results and state
     """
     try:
         # launch execution
         cmd_launch = CONF.clients_chef.cmd_launch
         resp_launch = self.execute_command(cmd_launch)
         msg = {
             'success': True,
             'response': resp_launch
         }
         LOG.debug(_("Launch result: %s") % resp_launch)
         if resp_launch is None or "FATAL" in resp_launch:
             msg['success'] = False
     except Exception as e:
         self.remove_container(self.container)
         LOG.error(_LW("Cookbook deployment exception %s" % e))
         raise CookbookDeploymentException(cookbook=cookbook)
     return msg
Beispiel #9
0
 def run_install(self, cookbook):
     """Run download and install command
     :param cookbook: cookbook to process
     :return msg: operation result
     """
     try:
         cmd_install = CONF.clients_chef.cmd_install.format(cookbook)
         resp_install = self.execute_command(cmd_install)
         msg = {
             'success': True,
             'response': resp_install
         }
         for line in resp_install.splitlines():
             if "ERROR" in line:
                 msg['success'] = False
         LOG.debug(_("Install result: %s") % resp_install)
     except Exception as e:
         self.remove_container(self.container)
         LOG.error(_LW("Chef install exception: %s" % e))
         raise CookbookInstallException(cookbook=cookbook)
     return msg
Beispiel #10
0
 def run_test(self, cookbook):
     """ Test cookbook syntax
     :param cookbook: cookbook to test
     :return msg: dictionary with results and state
     """
     try:
         cmd_test = CONF.clients_chef.cmd_test.format(cookbook)
         resp_test = self.execute_command(cmd_test)
         msg = {
             'success': True,
             'response': resp_test
         }
         for line in resp_test.splitlines():
             if "ERROR" in line:
                 msg['success'] = False
         LOG.debug(_("Test result: %s") % resp_test)
     except Exception as e:
         self.remove_container(self.container)
         LOG.error(_LW("Cookbook syntax exception %s" % e))
         raise CookbookSyntaxException(cookbook=cookbook)
     return msg
Beispiel #11
0
    def test_all_remote_exceptions(self):
        for name, obj in inspect.getmembers(
                validator_exc, lambda x: inspect.isclass(x) and
                issubclass(x, validator_exc.OpenstackException)):
            if '__init__' in obj.__dict__:
                if obj == validator_exc.OpenstackException:  #
                    # manually ignore baseclass
                    continue
                elif obj == validator_exc.Error:
                    error = obj('Error')
                elif obj == validator_exc.NotFound:
                    error = obj()
                elif obj == validator_exc.ResourceFailure:
                    exc = validator_exc.Error(_('Error'))
                    error = obj(exc, None, 'CREATE')
                elif obj == validator_exc.ResourcePropertyConflict:
                    error = obj('%s' % 'a test prop')
                else:
                    continue
                self.remote_exception_helper(name, error)
                continue

            if hasattr(obj, 'msg_fmt'):
                kwargs = {}
                spec_names = re.findall('%\((\w+)\)([cdeEfFgGinorsxX])',
                                        obj.msg_fmt)

                for key, convtype in spec_names:
                    if convtype == 'r' or convtype == 's':
                        kwargs[key] = '"' + key + '"'
                    else:
                        # this is highly unlikely
                        raise Exception("test needs additional conversion"
                                        " type added due to %s exception"
                                        " using '%c' specifier" % (obj,
                                                                   convtype))

                error = obj(**kwargs)
                self.remote_exception_helper(name, error)
Beispiel #12
0
def _find_facility_from_conf():
    facility_names = logging.handlers.SysLogHandler.facility_names
    facility = getattr(logging.handlers.SysLogHandler,
                       CONF.syslog_log_facility,
                       None)

    if facility is None and CONF.syslog_log_facility in facility_names:
        facility = facility_names.get(CONF.syslog_log_facility)

    if facility is None:
        valid_facilities = facility_names.keys()
        consts = ['LOG_AUTH', 'LOG_AUTHPRIV', 'LOG_CRON', 'LOG_DAEMON',
                  'LOG_FTP', 'LOG_KERN', 'LOG_LPR', 'LOG_MAIL', 'LOG_NEWS',
                  'LOG_AUTH', 'LOG_SYSLOG', 'LOG_USER', 'LOG_UUCP',
                  'LOG_LOCAL0', 'LOG_LOCAL1', 'LOG_LOCAL2', 'LOG_LOCAL3',
                  'LOG_LOCAL4', 'LOG_LOCAL5', 'LOG_LOCAL6', 'LOG_LOCAL7']
        valid_facilities.extend(consts)
        raise TypeError(_('syslog facility must be one of: %s') %
                        ', '.join("'%s'" % fac
                                  for fac in valid_facilities))

    return facility
Beispiel #13
0
socket_opts = [
    cfg.IntOpt('tcp_keepidle',
               default=600,
               help="Sets the value of TCP_KEEPIDLE in seconds for each "
                    "server socket. Not supported on OS X."),
]

CONF = cfg.CONF
CONF.register_opts(socket_opts)
LOG = logging.getLogger(__name__)

# Local ip/port binding options
bind_opts = [
    cfg.StrOpt('bind_host', default=socket.gethostname(),
               help=_('Name of the engine node.')),
    cfg.StrOpt('bind_port', default=4041,
               help=_('Listening port of the engine node.')),
]
CONF.register_cli_opts(bind_opts)

# Paste/Deploy server options
paste_deploy_group = cfg.OptGroup('paste_deploy')
paste_deploy_opts = [
    cfg.StrOpt('config_file', default="api-paste.ini",
               help=_("The API config file to use.")),
    cfg.StrOpt('flavor', help=_("The flavor to use."))
]
CONF.register_group(paste_deploy_group)
CONF.register_opts(paste_deploy_opts, group='paste_deploy')
Beispiel #14
0
 def default(request):
     try:
         return {'body': jsonutils.loads(request.body)}
     except ValueError:
         raise exception.MalformedRequestBody(
             reason=_("cannot understand JSON"))