Ejemplo n.º 1
0
    def load_extension(self, ext_factory):
        """Execute an extension factory.

        Loads an extension.  The 'ext_factory' is the name of a
        callable that will be imported and called with one
        argument--the extension manager.  The factory callable is
        expected to call the register() method at least once.
        """

        LOG.debug("Loading extension %s", ext_factory)

        if isinstance(ext_factory, six.string_types):
            if ext_factory.startswith('fastrunner.api.openstack.compute.contrib'):
                LOG.warn(_LW("The legacy v2 API module already moved into"
                             "'fastrunner.api.openstack.compute.legacy_v2.contrib'. "
                             "Use new path instead of old path %s"),
                         ext_factory)
                ext_factory = ext_factory.replace('contrib',
                                                  'legacy_v2.contrib')
            # Load the factory
            factory = importutils.import_class(ext_factory)
        else:
            factory = ext_factory

        # Call it
        LOG.debug("Calling extension factory %s", ext_factory)
        factory(self)
Ejemplo n.º 2
0
    def _register_controllers(self, ext):
        """Register controllers defined by the extensions

        Extensions define what resources they want to add through
        a get_controller_extensions function
        """

        handler = ext.obj
        LOG.debug("Running _register_controllers on %s", ext.obj)

        for extension in handler.get_controller_extensions():
            ext_name = extension.extension.name
            collection = extension.collection
            controller = extension.controller

            if collection not in self.resources:
                LOG.warning(
                    _LW('Extension %(ext_name)s: Cannot extend '
                        'resource %(collection)s: No such resource'), {
                            'ext_name': ext_name,
                            'collection': collection
                        })
                continue

            LOG.debug(
                'Extension %(ext_name)s extending resource: '
                '%(collection)s', {
                    'ext_name': ext_name,
                    'collection': collection
                })

            resource = self.resources[collection]
            resource.register_actions(controller)
            resource.register_extensions(controller)
Ejemplo n.º 3
0
    def _load_extensions(self):
        """Load extensions specified on the command line."""

        extensions = list(self.cls_list)

        for ext_factory in extensions:
            try:
                self.load_extension(ext_factory)
            except Exception as exc:
                LOG.warning(_LW('Failed to load extension %(ext_factory)s: '
                                '%(exc)s'),
                            {'ext_factory': ext_factory, 'exc': exc})
Ejemplo n.º 4
0
    def _setup_extensions(self, ext_mgr):
        for extension in ext_mgr.get_controller_extensions():
            collection = extension.collection
            controller = extension.controller

            msg_format_dict = {
                'collection': collection,
                'ext_name': extension.extension.name
            }
            if collection not in self.resources:
                LOG.warning(
                    _LW('Extension %(ext_name)s: Cannot extend '
                        'resource %(collection)s: No such resource'),
                    msg_format_dict)
                continue

            LOG.debug(
                'Extension %(ext_name)s extended resource: '
                '%(collection)s', msg_format_dict)

            resource = self.resources[collection]
            resource.register_actions(controller)
            resource.register_extensions(controller)
Ejemplo n.º 5
0
def load_standard_extensions(ext_mgr, logger, path, package, ext_list=None):
    """Registers all standard API extensions."""

    # Walk through all the modules in our directory...
    our_dir = path[0]
    for dirpath, dirnames, filenames in os.walk(our_dir):
        # Compute the relative package name from the dirpath
        relpath = os.path.relpath(dirpath, our_dir)
        if relpath == '.':
            relpkg = ''
        else:
            relpkg = '.%s' % '.'.join(relpath.split(os.sep))

        # Now, consider each file in turn, only considering .py files
        for fname in filenames:
            root, ext = os.path.splitext(fname)

            # Skip __init__ and anything that's not .py
            if ext != '.py' or root == '__init__':
                continue

            # Try loading it
            classname = "%s%s" % (root[0].upper(), root[1:])
            classpath = ("%s%s.%s.%s" %
                         (package, relpkg, root, classname))

            if ext_list is not None and classname not in ext_list:
                logger.debug("Skipping extension: %s" % classpath)
                continue

            try:
                ext_mgr.load_extension(classpath)
            except Exception as exc:
                logger.warn(_LW('Failed to load extension %(classpath)s: '
                                '%(exc)s'),
                            {'classpath': classpath, 'exc': exc})

        # Now, let's consider any subdirectories we may have...
        subdirs = []
        for dname in dirnames:
            # Skip it if it does not have __init__.py
            if not os.path.exists(os.path.join(dirpath, dname, '__init__.py')):
                continue

            # If it has extension(), delegate...
            ext_name = "%s%s.%s.extension" % (package, relpkg, dname)
            try:
                ext = importutils.import_class(ext_name)
            except ImportError:
                # extension() doesn't exist on it, so we'll explore
                # the directory for ourselves
                subdirs.append(dname)
            else:
                try:
                    ext(ext_mgr)
                except Exception as exc:
                    logger.warn(_LW('Failed to load extension %(ext_name)s:'
                                    '%(exc)s'),
                                {'ext_name': ext_name, 'exc': exc})

        # Update the list of directories we'll explore...
        # using os.walk 'the caller can modify the dirnames list in-place,
        # and walk() will only recurse into the subdirectories whose names
        # remain in dirnames'
        # https://docs.python.org/2/library/os.html#os.walk
        dirnames[:] = subdirs
Ejemplo n.º 6
0
    def __init__(self, init_only=None, v3mode=False):
        # TODO(cyeoh): bp v3-api-extension-framework. Currently load
        # all extensions but eventually should be able to exclude
        # based on a config file
        # TODO(oomichi): We can remove v3mode argument after moving all v3 APIs
        # to v2.1.
        def _check_load_extension(ext):
            if (self.init_only is None
                    or ext.obj.alias in self.init_only) and isinstance(
                        ext.obj, extensions.V21APIExtensionBase):

                return self._register_extension(ext)
            return False

        if not CONF.osapi_v21.enabled:
            LOG.info(_LI("V2.1 API has been disabled by configuration"))
            LOG.warning(_LW("In the M release you must run the v2.1 API."))
            return

        if (CONF.osapi_v21.extensions_blacklist
                or CONF.osapi_v21.extensions_whitelist):
            LOG.warning(
                _LW('In the M release you must run all of the API. '
                    'The concept of API extensions will be removed from '
                    'the codebase to ensure there is a single Compute API.'))

        self.init_only = init_only
        LOG.debug("v21 API Extension Blacklist: %s",
                  CONF.osapi_v21.extensions_blacklist)
        LOG.debug("v21 API Extension Whitelist: %s",
                  CONF.osapi_v21.extensions_whitelist)

        in_blacklist_and_whitelist = set(
            CONF.osapi_v21.extensions_whitelist).intersection(
                CONF.osapi_v21.extensions_blacklist)
        if len(in_blacklist_and_whitelist) != 0:
            LOG.warning(_LW("Extensions in both blacklist and whitelist: %s"),
                        list(in_blacklist_and_whitelist))

        self.api_extension_manager = stevedore.enabled.EnabledExtensionManager(
            namespace=self.api_extension_namespace(),
            check_func=_check_load_extension,
            invoke_on_load=True,
            invoke_kwds={"extension_info": self.loaded_extension_info})

        if v3mode:
            mapper = PlainMapper()
        else:
            mapper = ProjectMapper()

        self.resources = {}

        # NOTE(cyeoh) Core API support is rewritten as extensions
        # but conceptually still have core
        if list(self.api_extension_manager):
            # NOTE(cyeoh): Stevedore raises an exception if there are
            # no plugins detected. I wonder if this is a bug.
            self._register_resources_check_inherits(mapper)
            self.api_extension_manager.map(self._register_controllers)

        missing_core_extensions = self.get_missing_core_extensions(
            self.loaded_extension_info.get_extensions().keys())
        #if not self.init_only and missing_core_extensions:
        #    LOG.critical(_LC("Missing core API extensions: %s"),
        #                 missing_core_extensions)
        #    raise exception.CoreAPIMissing(
        #        missing_apis=missing_core_extensions)

        LOG.info(_LI("Loaded extensions: %s"),
                 sorted(self.loaded_extension_info.get_extensions().keys()))
        super(APIRouterV21, self).__init__(mapper)
Ejemplo n.º 7
0
    def __init__(self,
                 user_id=None,
                 project_id=None,
                 is_admin=None,
                 read_deleted="no",
                 roles=None,
                 remote_address=None,
                 timestamp=None,
                 request_id=None,
                 auth_token=None,
                 overwrite=True,
                 quota_class=None,
                 user_name=None,
                 project_name=None,
                 service_catalog=None,
                 instance_lock_checked=False,
                 user_auth_plugin=None,
                 **kwargs):
        """:param read_deleted: 'no' indicates deleted records are hidden,
                'yes' indicates deleted records are visible,
                'only' indicates that *only* deleted records are visible.

           :param overwrite: Set to False to ensure that the greenthread local
                copy of the index is not overwritten.

           :param user_auth_plugin: The auth plugin for the current request's
                authentication data.

           :param kwargs: Extra arguments that might be present, but we ignore
                because they possibly came in from older rpc messages.
        """
        user = kwargs.pop('user', None)
        tenant = kwargs.pop('tenant', None)
        super(RequestContext,
              self).__init__(auth_token=auth_token,
                             user=user_id or user,
                             tenant=project_id or tenant,
                             domain=kwargs.pop('domain', None),
                             user_domain=kwargs.pop('user_domain', None),
                             project_domain=kwargs.pop('project_domain', None),
                             is_admin=is_admin,
                             read_only=kwargs.pop('read_only', False),
                             show_deleted=kwargs.pop('show_deleted', False),
                             request_id=request_id,
                             resource_uuid=kwargs.pop('resource_uuid', None),
                             overwrite=overwrite)
        # oslo_context's RequestContext.to_dict() generates this field, we can
        # safely ignore this as we don't use it.
        kwargs.pop('user_identity', None)
        if kwargs:
            LOG.warning(_LW('Arguments dropped when creating context: %s'),
                        str(kwargs))

        # FIXME(dims): user_id and project_id duplicate information that is
        # already present in the oslo_context's RequestContext. We need to
        # get rid of them.
        self.user_id = user_id
        self.project_id = project_id
        self.roles = roles or []
        self.read_deleted = read_deleted
        self.remote_address = remote_address
        if not timestamp:
            timestamp = timeutils.utcnow()
        if isinstance(timestamp, six.string_types):
            timestamp = timeutils.parse_strtime(timestamp)
        self.timestamp = timestamp

        if service_catalog:
            # Only include required parts of service_catalog
            self.service_catalog = [
                s for s in service_catalog
                if s.get('type') in ('volume', 'volumev2', 'key-manager')
            ]
        else:
            # if list is empty or none
            self.service_catalog = []

        self.instance_lock_checked = instance_lock_checked

        # NOTE(markmc): this attribute is currently only used by the
        # rs_limits turnstile pre-processor.
        # See https://lists.launchpad.net/openstack/msg12200.html
        self.quota_class = quota_class
        self.user_name = user_name
        self.project_name = project_name
        self.is_admin = is_admin

        # NOTE(dheeraj): The following attribute is used by cellsv2 to store
        # connection information for connecting to the target cell.
        # It is only manipulated using the target_cell contextmanager
        # provided by this module
        self.db_connection = None
        self.user_auth_plugin = user_auth_plugin
        if self.is_admin is None:
            self.is_admin = policy.check_is_admin(self)