コード例 #1
0
def openstack_cloud(
        config=None, strict=False, app_name=None, app_version=None, **kwargs):
    if not config:
        config = _get_openstack_config(app_name, app_version)
    try:
        cloud_region = config.get_one(**kwargs)
    except keystoneauth1.exceptions.auth_plugins.NoMatchingPlugin as e:
        raise OpenStackCloudException(
            "Invalid cloud configuration: {exc}".format(exc=str(e)))
    return OpenStackCloud(cloud_config=cloud_region, strict=strict)
コード例 #2
0
    def __init__(self,
                 config_files=None,
                 refresh=False,
                 private=False,
                 config_key=None,
                 config_defaults=None,
                 cloud=None,
                 use_direct_get=False):
        if config_files is None:
            config_files = []
        config = openstack.config.loader.OpenStackConfig(
            config_files=openstack.config.loader.CONFIG_FILES + config_files)
        self.extra_config = config.get_extra_config(config_key,
                                                    config_defaults)

        if cloud is None:
            self.clouds = [
                openstack.cloud.OpenStackCloud(cloud_config=cloud_region)
                for cloud_region in config.get_all()
            ]
        else:
            try:
                self.clouds = [
                    openstack.cloud.OpenStackCloud(
                        cloud_config=config.get_one(cloud))
                ]
            except openstack.config.exceptions.OpenStackConfigException as e:
                raise openstack.cloud.OpenStackCloudException(e)

        if private:
            for cloud in self.clouds:
                cloud.private = True

        # Handle manual invalidation of entire persistent cache
        if refresh:
            for cloud in self.clouds:
                cloud._cache.invalidate()
コード例 #3
0
    def connect_as(self, **kwargs):
        """Make a new OpenStackCloud object with new auth context.

        Take the existing settings from the current cloud and construct a new
        OpenStackCloud object with some of the auth settings overridden. This
        is useful for getting an object to perform tasks with as another user,
        or in the context of a different project.

        .. code-block:: python

          conn = openstack.connect(cloud='example')
          # Work normally
          servers = conn.list_servers()
          conn2 = conn.connect_as(username='******', password='')
          # Work as different-user
          servers = conn2.list_servers()

        :param kwargs: keyword arguments can contain anything that would
                       normally go in an auth dict. They will override the same
                       settings from the parent cloud as appropriate. Entries
                       that do not want to be overridden can be ommitted.
        """

        if self.config._openstack_config:
            config = self.config._openstack_config
        else:
            # TODO(mordred) Replace this with from_session
            config = openstack.config.OpenStackConfig(
                app_name=self.config._app_name,
                app_version=self.config._app_version,
                load_yaml_config=False)
        params = copy.deepcopy(self.config.config)
        # Remove profile from current cloud so that overridding works
        params.pop('profile', None)

        # Utility function to help with the stripping below.
        def pop_keys(params, auth, name_key, id_key):
            if name_key in auth or id_key in auth:
                params['auth'].pop(name_key, None)
                params['auth'].pop(id_key, None)

        # If there are user, project or domain settings in the incoming auth
        # dict, strip out both id and name so that a user can say:
        #     cloud.connect_as(project_name='foo')
        # and have that work with clouds that have a project_id set in their
        # config.
        for prefix in ('user', 'project'):
            if prefix == 'user':
                name_key = 'username'
            else:
                name_key = 'project_name'
            id_key = '{prefix}_id'.format(prefix=prefix)
            pop_keys(params, kwargs, name_key, id_key)
            id_key = '{prefix}_domain_id'.format(prefix=prefix)
            name_key = '{prefix}_domain_name'.format(prefix=prefix)
            pop_keys(params, kwargs, name_key, id_key)

        for key, value in kwargs.items():
            params['auth'][key] = value

        # TODO(mordred) Replace this chunk with the next patch that allows
        # passing a Session to CloudRegion.
        # Closure to pass to OpenStackConfig to ensure the new cloud shares
        # the Session with the current cloud. This will ensure that version
        # discovery cache will be re-used.
        def session_constructor(*args, **kwargs):
            # We need to pass our current keystone session to the Session
            # Constructor, otherwise the new auth plugin doesn't get used.
            return keystoneauth1.session.Session(
                session=self.session,
                discovery_cache=self.config._discovery_cache)

        cloud_config = config.get_one(
            session_constructor=session_constructor,
            **params)
        # Override the cloud name so that logging/location work right
        cloud_config._name = self.name
        cloud_config.config['profile'] = self.name
        # Use self.__class__ so that we return whatever this if, like if it's
        # a subclass in the case of shade wrapping sdk.
        return self.__class__(config=cloud_config)
コード例 #4
0
    def connect_as(self, **kwargs):
        """Make a new OpenStackCloud object with new auth context.

        Take the existing settings from the current cloud and construct a new
        OpenStackCloud object with some of the auth settings overridden. This
        is useful for getting an object to perform tasks with as another user,
        or in the context of a different project.

        .. code-block:: python

          conn = openstack.connect(cloud='example')
          # Work normally
          servers = conn.list_servers()
          conn2 = conn.connect_as(username='******', password='')
          # Work as different-user
          servers = conn2.list_servers()

        :param kwargs: keyword arguments can contain anything that would
                       normally go in an auth dict. They will override the same
                       settings from the parent cloud as appropriate. Entries
                       that do not want to be overridden can be ommitted.
        """

        if self.config._openstack_config:
            config = self.config._openstack_config
        else:
            # TODO(mordred) Replace this with from_session
            config = openstack.config.OpenStackConfig(
                app_name=self.config._app_name,
                app_version=self.config._app_version,
                load_yaml_config=False)
        params = copy.deepcopy(self.config.config)
        # Remove profile from current cloud so that overridding works
        params.pop('profile', None)

        # Utility function to help with the stripping below.
        def pop_keys(params, auth, name_key, id_key):
            if name_key in auth or id_key in auth:
                params['auth'].pop(name_key, None)
                params['auth'].pop(id_key, None)

        # If there are user, project or domain settings in the incoming auth
        # dict, strip out both id and name so that a user can say:
        #     cloud.connect_as(project_name='foo')
        # and have that work with clouds that have a project_id set in their
        # config.
        for prefix in ('user', 'project'):
            if prefix == 'user':
                name_key = 'username'
            else:
                name_key = 'project_name'
            id_key = '{prefix}_id'.format(prefix=prefix)
            pop_keys(params, kwargs, name_key, id_key)
            id_key = '{prefix}_domain_id'.format(prefix=prefix)
            name_key = '{prefix}_domain_name'.format(prefix=prefix)
            pop_keys(params, kwargs, name_key, id_key)

        for key, value in kwargs.items():
            params['auth'][key] = value

        # TODO(mordred) Replace this chunk with the next patch that allows
        # passing a Session to CloudRegion.
        # Closure to pass to OpenStackConfig to ensure the new cloud shares
        # the Session with the current cloud. This will ensure that version
        # discovery cache will be re-used.
        def session_constructor(*args, **kwargs):
            # We need to pass our current keystone session to the Session
            # Constructor, otherwise the new auth plugin doesn't get used.
            return keystoneauth1.session.Session(
                session=self.session,
                discovery_cache=self.config._discovery_cache)

        cloud_config = config.get_one(session_constructor=session_constructor,
                                      **params)
        # Override the cloud name so that logging/location work right
        cloud_config._name = self.name
        cloud_config.config['profile'] = self.name
        # Use self.__class__ so that we return whatever this if, like if it's
        # a subclass in the case of shade wrapping sdk.
        return self.__class__(config=cloud_config)