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)
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
def validate(self, 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")) if 'recipe' in body.keys(): recipe = body['recipe'] else: recipe = "default" LOG.info( _LI('Processing Request for cookbook {cookbook}, recipe {recipe}, ' 'image {image}').format(cookbook=cookbook, recipe=recipe, image=image)) res = self.ve.validate_cookbook( cookbook, recipe, image, request ) return res
def _validate_auth_url(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
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
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)
def test_all_remote_exceptions(self): for name, obj in inspect.getmembers( chef_validator_exc, lambda x: inspect.isclass(x) and issubclass(x, chef_validator_exc.OpenstackException)): if '__init__' in obj.__dict__: if obj == chef_validator_exc.OpenstackException: # # manually ignore baseclass continue elif obj == chef_validator_exc.Error: error = obj('Error') elif obj == chef_validator_exc.NotFound: error = obj() elif obj == chef_validator_exc.ResourceFailure: exc = chef_validator_exc.Error(_('Error')) error = obj(exc, None, 'CREATE') elif obj == chef_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)
def run_deploy(self, cookbook, recipe): """Run cookbook deployment :param cookbook: cookbook to deploy :param recipe: recipe 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
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_name=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: LOG.error(_LW("Chef install exception: %s") % e) self.remove_container(self.container) raise CookbookInstallException(cookbook=cookbook) return msg
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_name=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
def default(request): try: return {'body': jsonutils.loads(request.body)} except ValueError: raise exception.MalformedRequestBody( reason=_("cannot understand JSON"))
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')