Exemple #1
0
 def _from_json(self, datastring):
     try:
         return jsonutils.loads(datastring)
     except ValueError:
         msg = _("Cannot understand JSON")
         LOG.exception(_("InvalidJSON: %s"), msg)
         raise exceptions.MalformedRequestBody(reason=msg)
Exemple #2
0
 def run(self, parsed_args):
     self.log.debug('run(%s)', parsed_args)
     hypernet_client = self.get_client()
     hypernet_client.format = parsed_args.request_format
     _extra_values = parse_args_to_dict(self.values_specs)
     _merge_args(self, parsed_args, _extra_values, self.values_specs)
     body = self.args2body(parsed_args)
     if self.resource in body:
         body[self.resource].update(_extra_values)
     else:
         body[self.resource] = _extra_values
     if not body[self.resource]:
         raise exceptions.CommandError(
             _("Must specify new values to update %s") % self.resource)
     if self.allow_names:
         _id = find_resourceid_by_name_or_id(hypernet_client, self.resource,
                                             parsed_args.id)
     else:
         _id = find_resourceid_by_id(hypernet_client, self.resource,
                                     parsed_args.id)
     obj_updator = getattr(hypernet_client, "update_%s" % self.resource)
     obj_updator(_id, body)
     print((_('Updated %(resource)s: %(id)s') % {
         'id': parsed_args.id,
         'resource': self.resource
     }),
           file=self.app.stdout)
     return
Exemple #3
0
 def _load_all_extensions_from_path(self, path):
     # Sorting the extension list makes the order in which they
     # are loaded predictable across a cluster of load-balanced
     # Hypernet Servers
     for f in sorted(os.listdir(path)):
         try:
             LOG.debug(_('Loading extension file: %s'), f)
             mod_name, file_ext = os.path.splitext(os.path.split(f)[-1])
             ext_path = os.path.join(path, f)
             if file_ext.lower() == '.py' and not mod_name.startswith('_'):
                 mod = imp.load_source(mod_name, ext_path)
                 ext_name = mod_name[0].upper() + mod_name[1:]
                 new_ext_class = getattr(mod, ext_name, None)
                 if not new_ext_class:
                     LOG.warning(_('Did not find expected name '
                                   '"%(ext_name)s" in %(file)s'),
                                 {'ext_name': ext_name,
                                  'file': ext_path})
                     continue
                 new_ext = new_ext_class()
                 self.add_extension(new_ext)
         except Exception as exception:
             LOG.warning(_("Extension file %(f)s wasn't loaded due to "
                           "%(exception)s"),
                         {'f': f, 'exception': exception})
Exemple #4
0
    def retry_request(self,
                      method,
                      action,
                      body=None,
                      headers=None,
                      params=None):
        """Call do_request with the default retry configuration.
        Only idempotent requests should retry failed connection attempts.
        :raises: ConnectionFailed if the maximum # of retries is exceeded
        """
        max_attempts = self.retries + 1
        for i in range(max_attempts):
            try:
                return self.do_request(method,
                                       action,
                                       body=body,
                                       headers=headers,
                                       params=params)
            except exceptions.ConnectionFailed:
                # Exception has already been logged by do_request()
                if i < self.retries:
                    _logger.debug('Retrying connection to Tacker service')
                    time.sleep(self.retry_interval)
                elif self.raise_errors:
                    raise

        if self.retries:
            msg = (_("Failed to connect to Tacker server after %d attempts") %
                   max_attempts)
        else:
            msg = _("Failed to connect Tacker server")

        raise exceptions.ConnectionFailed(reason=msg)
def check_non_negative_int(value):
    try:
        value = int(value)
    except ValueError:
        raise argparse.ArgumentTypeError(_("invalid int value: %r") % value)
    if value < 0:
        raise argparse.ArgumentTypeError(
            _("input value %d is negative") % value)
    return value
Exemple #6
0
 def get_parser(self, prog_name):
     parser = super(DeleteCommand, self).get_parser(prog_name)
     if self.allow_names:
         help_str = _('IDs or names of %s to delete')
     else:
         help_str = _('IDs of %s to delete')
     parser.add_argument('ids',
                         nargs='+',
                         metavar=self.resource.upper(),
                         help=help_str % self.resource)
     return parser
Exemple #7
0
 def get_parser(self, prog_name):
     parser = super(ShowCommand, self).get_parser(prog_name)
     add_show_list_common_argument(parser)
     if self.allow_names:
         help_str = _('ID or name of %s to look up')
     else:
         help_str = _('ID of %s to look up')
     parser.add_argument('id',
                         metavar=self.get_id(),
                         help=help_str % self.resource)
     return parser
Exemple #8
0
def validate_head_file(config):
    script = alembic_script.ScriptDirectory.from_config(config)
    if len(script.get_heads()) > 1:
        alembic_util.err(_('Timeline branches unable to generate timeline'))

    head_path = os.path.join(script.versions, HEAD_FILENAME)
    if (os.path.isfile(head_path)
            and open(head_path).read().strip() == script.get_current_head()):
        return
    else:
        alembic_util.err(_('HEAD file does not match migration timeline head'))
    def build_option_parser(self, description, version):
        """Return an argparse option parser for this application.
        Subclasses may override this method to extend
        the parser with more global options.
        :param description: full description of the application
        :paramtype description: str
        :param version: version number for the application
        :paramtype version: str
        """
        parser = argparse.ArgumentParser(
            description=description,
            add_help=False,
        )
        parser.add_argument(
            '--version',
            action='version',
            version=__version__,
        )
        parser.add_argument(
            '-v',
            '--verbose',
            '--debug',
            action='count',
            dest='verbose_level',
            default=self.DEFAULT_VERBOSE_LEVEL,
            help=_('Increase verbosity of output and show tracebacks on'
                   ' errors. You can repeat this option.'))
        parser.add_argument(
            '-q',
            '--quiet',
            action='store_const',
            dest='verbose_level',
            const=0,
            help=_('Suppress output except warnings and errors.'))
        parser.add_argument(
            '-h',
            '--help',
            action=HelpAction,
            nargs=0,
            default=self,  # tricky
            help=_("Show this help message and exit."))
        parser.add_argument(
            '-r',
            '--retries',
            metavar="NUM",
            type=check_non_negative_int,
            default=0,
            help=_("How many times the request to the Hypernet server should "
                   "be retried if it fails."))
        # FIXME(bklei): this method should come from python-keystoneclient
        self._append_global_identity_args(parser)

        return parser
Exemple #10
0
    def __init__(self, application,
                 ext_mgr=None):
        self.ext_mgr = (ext_mgr
                        or ExtensionManager(get_extensions_path()))
        mapper = routes.Mapper()

        # extended resources
        for resource in self.ext_mgr.get_resources():
            path_prefix = resource.path_prefix
            if resource.parent:
                path_prefix = (resource.path_prefix +
                               "/%s/{%s_id}" %
                               (resource.parent["collection_name"],
                                resource.parent["member_name"]))

            LOG.debug(_('Extended resource: %s'),
                      resource.collection)
            for action, method in six.iteritems(resource.collection_actions):
                conditions = dict(method=[method])
                path = "/%s/%s" % (resource.collection, action)
                with mapper.submapper(controller=resource.controller,
                                      action=action,
                                      path_prefix=path_prefix,
                                      conditions=conditions) as submap:
                    submap.connect(path)
                    submap.connect("%s.:(format)" % path)

            mapper.resource(resource.collection, resource.collection,
                            controller=resource.controller,
                            member=resource.member_actions,
                            parent_resource=resource.parent,
                            path_prefix=path_prefix)

        # extended actions
        action_controllers = self._action_ext_controllers(application,
                                                          self.ext_mgr, mapper)
        for action in self.ext_mgr.get_actions():
            LOG.debug(_('Extended action: %s'), action.action_name)
            controller = action_controllers[action.collection]
            controller.add_action(action.action_name, action.handler)

        # extended requests
        req_controllers = self._request_ext_controllers(application,
                                                        self.ext_mgr, mapper)
        for request_ext in self.ext_mgr.get_request_extensions():
            LOG.debug(_('Extended request: %s'), request_ext.key)
            controller = req_controllers[request_ext.key]
            controller.add_handler(request_ext.handler)

        self._router = routes.middleware.RoutesMiddleware(self._dispatch,
                                                          mapper)
        super(ExtensionMiddleware, self).__init__(application)
Exemple #11
0
    def extend_resources(self, version, attr_map):
        """Extend resources with additional resources or attributes.
        :param: attr_map, the existing mapping from resource name to
        attrs definition.
        After this function, we will extend the attr_map if an extension
        wants to extend this map.
        """
        update_exts = []
        processed_exts = set()
        exts_to_process = self.extensions.copy()
        # Iterate until there are unprocessed extensions or if no progress
        # is made in a whole iteration
        while exts_to_process:
            processed_ext_count = len(processed_exts)
            for ext_name, ext in exts_to_process.items():
                if not hasattr(ext, 'get_extended_resources'):
                    del exts_to_process[ext_name]
                    continue
                if hasattr(ext, 'update_attributes_map'):
                    update_exts.append(ext)
                if hasattr(ext, 'get_required_extensions'):
                    # Process extension only if all required extensions
                    # have been processed already
                    required_exts_set = set(ext.get_required_extensions())
                    if required_exts_set - processed_exts:
                        continue
                try:
                    extended_attrs = ext.get_extended_resources(version)
                    for resource, resource_attrs in six.iteritems(
                            extended_attrs):
                        if attr_map.get(resource):
                            attr_map[resource].update(resource_attrs)
                        else:
                            attr_map[resource] = resource_attrs
                except AttributeError:
                    LOG.exception(_("Error fetching extended attributes for "
                                    "extension '%s'"), ext.get_name())
                processed_exts.add(ext_name)
                del exts_to_process[ext_name]
            if len(processed_exts) == processed_ext_count:
                # Exit loop as no progress was made
                break
        if exts_to_process:
            # NOTE(salv-orlando): Consider whether this error should be fatal
            LOG.error(_("It was impossible to process the following "
                        "extensions: %s because of missing requirements."),
                      ','.join(exts_to_process.keys()))

        # Extending extensions' attributes map.
        for ext in update_exts:
            ext.update_attributes_map(attr_map)
Exemple #12
0
 def show(self, request, id):
     # NOTE(dprince): the extensions alias is used as the 'id' for show
     ext = self.extension_manager.extensions.get(id)
     if not ext:
         raise webob.exc.HTTPNotFound(
             _("Extension with alias %s does not exist") % id)
     return dict(extension=self._translate(ext))
Exemple #13
0
    def __call__(self, req):
        """Call the method specified in req.environ by RoutesMiddleware."""
        arg_dict = req.environ['wsgiorg.routing_args'][1]
        action = arg_dict['action']
        method = getattr(self, action)
        del arg_dict['controller']
        del arg_dict['action']
        if 'format' in arg_dict:
            del arg_dict['format']
        arg_dict['request'] = req
        result = method(**arg_dict)

        if isinstance(result, dict) or result is None:
            if result is None:
                status = 204
                content_type = ''
                body = None
            else:
                status = 200
                content_type = req.best_match_content_type()
                body = self._serialize(result, content_type)

            response = webob.Response(status=status,
                                      content_type=content_type,
                                      body=body)
            msg_dict = dict(url=req.url, status=response.status_int)
            msg = _("%(url)s returned with HTTP %(status)d") % msg_dict
            LOG.debug(msg)
            return response
        else:
            return result
Exemple #14
0
 def __call__(self, environ, start_response):
     r"""Subclasses will probably want to implement __call__ like this:
     @webob.dec.wsgify(RequestClass=Request)
     def __call__(self, req):
       # Any of the following objects work as responses:
       # Option 1: simple string
       res = 'message\n'
       # Option 2: a nicely formatted HTTP exception page
       res = exc.HTTPForbidden(explanation='Nice try')
       # Option 3: a webob Response object (in case you need to play with
       # headers, or you want to be treated like an iterable, or or or)
       res = Response();
       res.app_iter = open('somefile')
       # Option 4: any wsgi app to be run next
       res = self.application
       # Option 5: you can get a Response object for a wsgi app, too, to
       # play with headers etc
       res = req.get_response(self.application)
       # You can then just return your response...
       return res
       # ... or set req.response and return None.
       req.response = res
     See the end of http://pythonpaste.org/webob/modules/dec.html
     for more info.
     """
     raise NotImplementedError(_('You must implement __call__'))
Exemple #15
0
def make_client(instance):
    """Returns an hypernet client."""

    hypernet_client = utils.get_client_class(
        API_NAME,
        instance._api_version[API_NAME],
        API_VERSIONS,
    )
    instance.initialize()
    url = instance._url
    url = url.rstrip("/")
    if '1.0' == instance._api_version[API_NAME]:
        client = hypernet_client(username=instance._username,
                                 tenant_name=instance._tenant_name,
                                 password=instance._password,
                                 region_name=instance._region_name,
                                 auth_url=instance._auth_url,
                                 endpoint_url=url,
                                 endpoint_type=instance._endpoint_type,
                                 token=instance._token,
                                 auth_strategy=instance._auth_strategy,
                                 insecure=instance._insecure,
                                 ca_cert=instance._ca_cert,
                                 retries=instance._retries,
                                 raise_errors=instance._raise_errors,
                                 session=instance._session,
                                 auth=instance._auth)
        return client
    else:
        raise exceptions.UnsupportedVersion(_("API version %s is not "
                                              "supported") %
                                            instance._api_version[API_NAME])
Exemple #16
0
class InvalidInput(BadRequest):
    """A bad request due to invalid input.
    A specialization of the BadRequest error indicating bad input was
    specified.
    :param error_message: Details on the operation that failed due to bad
    input.
    """
    message = _("Invalid input for operation: %(error_message)s.")
Exemple #17
0
 def get_parser(self, prog_name):
     parser = super(UpdateCommand, self).get_parser(prog_name)
     parser.add_argument('id',
                         metavar=self.resource.upper(),
                         help=_('ID or name of %s to update') %
                         self.resource)
     self.add_known_arguments(parser)
     return parser
Exemple #18
0
def update_head_file(config):
    script = alembic_script.ScriptDirectory.from_config(config)
    if len(script.get_heads()) > 1:
        alembic_util.err(_('Timeline branches unable to generate timeline'))

    head_path = os.path.join(script.versions, HEAD_FILENAME)
    with open(head_path, 'w+') as f:
        f.write(script.get_current_head())
Exemple #19
0
 def authenticate(self):
     if self.auth_strategy == 'keystone':
         self._authenticate_keystone()
     elif self.auth_strategy == 'noauth':
         self._authenticate_noauth()
     else:
         err_msg = _('Unknown auth strategy: %s') % self.auth_strategy
         raise exceptions.Unauthorized(message=err_msg)
Exemple #20
0
 def deserialize(self, datastring, content_type):
     """Deserialize a string to a dictionary.
     The string must be in the format of a supported MIME type.
     """
     try:
         return self.get_deserialize_handler(content_type).deserialize(
             datastring)
     except Exception:
         raise webob.exc.HTTPBadRequest(_("Could not deserialize data"))
Exemple #21
0
 def get_content_type(self):
     allowed_types = ("application/json")
     if "Content-Type" not in self.headers:
         LOG.debug(_("Missing Content-Type"))
         return None
     _type = self.content_type
     if _type in allowed_types:
         return _type
     return None
Exemple #22
0
 def run(self, parsed_args):
     failure = False
     deleted_ids = []
     failed_items = {}
     hypernet_client = self.get_client()
     hypernet_client.format = parsed_args.request_format
     obj_deleter = getattr(hypernet_client, "delete_%s" % self.resource)
     for resource_id in parsed_args.ids:
         try:
             if self.allow_names:
                 _id = find_resourceid_by_name_or_id(
                     hypernet_client, self.resource, resource_id)
             else:
                 _id = resource_id
             obj_deleter(_id)
             deleted_ids.append(resource_id)
         except Exception as e:
             failure = True
             failed_items[resource_id] = e
     if failure:
         msg = ''
         if deleted_ids:
             status_msg = self.deleted_msg.get(self.resource, 'deleted')
             msg = (_('Successfully %(status_msg)s %(resource)s(s):'
                      ' %(deleted_list)s') % {
                          'status_msg': status_msg,
                          'deleted_list': ', '.join(deleted_ids),
                          'resource': self.resource
                      })
         err_msg = _("\n\nUnable to delete the below"
                     " %s(s):") % self.resource
         for failed_id, error in failed_items.iteritems():
             err_msg += (_('\n Cannot delete %(failed_id)s: %(error)s') % {
                 'failed_id': failed_id,
                 'error': error
             })
         msg += err_msg
         raise exceptions.CommandError(msg)
     else:
         print((_('All %(resource)s(s) %(msg)s successfully') % {
             'msg': self.deleted_msg.get(self.resource, 'deleted'),
             'resource': self.resource
         }))
     return
def _run_wsgi(app_name):
    app = config.load_paste_app(app_name)
    if not app:
        LOG.error(_('No known API applications configured.'))
        return
    server = wsgi.Server(cfg.CONF,
                         app_name,
                         app,
                         host=cfg.CONF.bind_host,
                         port=cfg.CONF.bind_port,
                         use_ssl=sslutils.is_enabled(cfg.CONF))
    server.start()
    # Dump all option values here after all options are parsed
    cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)
    LOG.info(_("Hypernet service started, listening on %(host)s:%(port)s"), {
        'host': cfg.CONF.bind_host,
        'port': cfg.CONF.bind_port
    })
    return server
Exemple #24
0
def add_pagination_argument(parser):
    parser.add_argument(
        '-P',
        '--page-size',
        dest='page_size',
        metavar='SIZE',
        type=int,
        help=_("Specify retrieve unit of each request, then split one request "
               "to several requests"),
        default=None)
Exemple #25
0
 def get_parser(self, prog_name):
     parser = super(CreateCommand, self).get_parser(prog_name)
     parser.add_argument(
         '--tenant-id',
         metavar='TENANT_ID',
         help=_('The owner tenant ID'),
     )
     parser.add_argument('--tenant_id', help=argparse.SUPPRESS)
     self.add_known_arguments(parser)
     return parser
def serve_wsgi(cls):

    try:
        service = cls.create()
    except Exception:
        with excutils.save_and_reraise_exception():
            LOG.exception(
                _('Unrecoverable error: please check log '
                  'for details.'))

    return service
Exemple #27
0
    def add_extension(self, ext):
        # Do nothing if the extension doesn't check out
        if not self._check_extension(ext):
            return

        alias = ext.get_alias()
        LOG.info(_('Loaded extension: %s'), alias)

        if alias in self.extensions:
            raise exceptions.DuplicatedExtension(alias=alias)
        self.extensions[alias] = ext
Exemple #28
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        LOG.info(_("%(method)s %(url)s"), {"method": request.method,
                                           "url": request.url})

        try:
            action, args, accept = self.deserializer.deserialize(request)
        except exceptions.InvalidContentType:
            msg = _("Unsupported Content-Type")
            LOG.exception(_("InvalidContentType: %s"), msg)
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))
        except exceptions.MalformedRequestBody:
            msg = _("Malformed request body")
            LOG.exception(_("MalformedRequestBody: %s"), msg)
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))

        try:
            action_result = self.dispatch(request, action, args)
        except webob.exc.HTTPException as ex:
            LOG.info(_("HTTP exception thrown: %s"), six.text_type(ex))
            action_result = Fault(ex,
                                  self._fault_body_function)
        except Exception:
            LOG.exception(_("Internal error"))
            # Do not include the traceback to avoid returning it to clients.
            action_result = Fault(webob.exc.HTTPServerError(),
                                  self._fault_body_function)

        if isinstance(action_result, dict) or action_result is None:
            response = self.serializer.serialize(action_result,
                                                 accept,
                                                 action=action)
        else:
            response = action_result

        try:
            msg_dict = dict(url=request.url, status=response.status_int)
            msg = _("%(url)s returned with HTTP %(status)d") % msg_dict
        except AttributeError as e:
            msg_dict = dict(url=request.url, exception=e)
            msg = _("%(url)s returned a fault: %(exception)s") % msg_dict

        LOG.info(msg)

        return response
Exemple #29
0
def add_sorting_argument(parser):
    parser.add_argument(
        '--sort-key',
        dest='sort_key',
        metavar='FIELD',
        action='append',
        help=_("Sorts the list by the specified fields in the specified "
               "directions. You can repeat this option, but you must "
               "specify an equal number of sort_dir and sort_key values. "
               "Extra sort_dir options are ignored. Missing sort_dir options "
               "use the default asc value."),
        default=[])
    parser.add_argument(
        '--sort-dir',
        dest='sort_dir',
        metavar='{asc,desc}',
        help=_("Sorts the list in the specified direction. You can repeat "
               "this option."),
        action='append',
        default=[],
        choices=['asc', 'desc'])
Exemple #30
0
def do_upgrade_downgrade(config, cmd):
    if not CONF.command.revision and not CONF.command.delta:
        raise SystemExit(_('You must provide a revision or relative delta'))

    revision = CONF.command.revision

    if CONF.command.delta:
        sign = '+' if CONF.command.name == 'upgrade' else '-'
        revision = sign + str(CONF.command.delta)
    else:
        revision = CONF.command.revision

    do_alembic_command(config, cmd, revision, sql=CONF.command.sql)