def _get_extra_config(self, key, defaults=None):
        """Fetch an arbitrary extra chunk of config, laying in defaults.

        :param string key: name of the config section to fetch
        :param dict defaults: (optional) default values to merge under the
                                         found config
        """
        defaults = _util.normalize_keys(defaults or {})
        if not key:
            return defaults
        return _util.merge_clouds(
            defaults, _util.normalize_keys(self._extra_config.get(key, {})))
예제 #2
0
 def __init__(self, name=None, region_name=None, config=None,
              force_ipv4=False, auth_plugin=None,
              openstack_config=None, session_constructor=None,
              app_name=None, app_version=None, session=None,
              discovery_cache=None, extra_config=None,
              cache_expiration_time=0, cache_expirations=None,
              cache_path=None, cache_class='dogpile.cache.null',
              cache_arguments=None, password_callback=None):
     self._name = name
     self.region_name = region_name
     self.config = _util.normalize_keys(config)
     self._extra_config = extra_config or {}
     self.log = _log.setup_logging('openstack.config')
     self._force_ipv4 = force_ipv4
     self._auth = auth_plugin
     self._openstack_config = openstack_config
     self._keystone_session = session
     self._session_constructor = session_constructor or ks_session.Session
     self._app_name = app_name
     self._app_version = app_version
     self._discovery_cache = discovery_cache or None
     self._cache_expiration_time = cache_expiration_time
     self._cache_expirations = cache_expirations or {}
     self._cache_path = cache_path
     self._cache_class = cache_class
     self._cache_arguments = cache_arguments
     self._password_callback = password_callback
예제 #3
0
    def __init__(self,
                 name=None,
                 region_name=None,
                 config=None,
                 force_ipv4=False,
                 auth_plugin=None,
                 openstack_config=None,
                 session_constructor=None,
                 app_name=None,
                 app_version=None,
                 session=None,
                 discovery_cache=None,
                 extra_config=None,
                 cache_expiration_time=0,
                 cache_expirations=None,
                 cache_path=None,
                 cache_class='dogpile.cache.null',
                 cache_arguments=None,
                 password_callback=None,
                 statsd_host=None,
                 statsd_port=None,
                 statsd_prefix=None,
                 influxdb_config=None,
                 collector_registry=None):
        self._name = name
        self.config = _util.normalize_keys(config)
        # NOTE(efried): For backward compatibility: a) continue to accept the
        # region_name kwarg; b) make it take precedence over (non-service_type-
        # specific) region_name set in the config dict.
        if region_name is not None:
            self.config['region_name'] = region_name
        self._extra_config = extra_config or {}
        self.log = _log.setup_logging('openstack.config')
        self._force_ipv4 = force_ipv4
        self._auth = auth_plugin
        self._openstack_config = openstack_config
        self._keystone_session = session
        self._session_constructor = session_constructor or ks_session.Session
        self._app_name = app_name
        self._app_version = app_version
        self._discovery_cache = discovery_cache or None
        self._cache_expiration_time = cache_expiration_time
        self._cache_expirations = cache_expirations or {}
        self._cache_path = cache_path
        self._cache_class = cache_class
        self._cache_arguments = cache_arguments
        self._password_callback = password_callback
        self._statsd_host = statsd_host
        self._statsd_port = statsd_port
        self._statsd_prefix = statsd_prefix
        self._statsd_client = None
        self._influxdb_config = influxdb_config
        self._influxdb_client = None
        self._collector_registry = collector_registry

        self._service_type_manager = os_service_types.ServiceTypes()
예제 #4
0
 def _get_known_regions(self, cloud):
     config = _util.normalize_keys(self.cloud_config['clouds'][cloud])
     if 'regions' in config:
         return self._expand_regions(config['regions'])
     elif 'region_name' in config:
         if isinstance(config['region_name'], list):
             regions = config['region_name']
         else:
             regions = config['region_name'].split(',')
         if len(regions) > 1:
             warnings.warn(
                 "Comma separated lists in region_name are deprecated."
                 " Please use a yaml list in the regions"
                 " parameter in {0} instead.".format(self.config_filename))
         return self._expand_regions(regions)
     else:
         # crappit. we don't have a region defined.
         new_cloud = dict()
         our_cloud = self.cloud_config['clouds'].get(cloud, dict())
         self._expand_vendor_profile(cloud, new_cloud, our_cloud)
         if 'regions' in new_cloud and new_cloud['regions']:
             return self._expand_regions(new_cloud['regions'])
         elif 'region_name' in new_cloud and new_cloud['region_name']:
             return [self._expand_region_name(new_cloud['region_name'])]
예제 #5
0
 def __init__(self,
              name=None,
              region_name=None,
              config=None,
              force_ipv4=False,
              auth_plugin=None,
              openstack_config=None,
              session_constructor=None,
              app_name=None,
              app_version=None,
              session=None,
              discovery_cache=None):
     self._name = name
     self.region_name = region_name
     self.config = _util.normalize_keys(config)
     self.log = _log.setup_logging('openstack.config')
     self._force_ipv4 = force_ipv4
     self._auth = auth_plugin
     self._openstack_config = openstack_config
     self._keystone_session = session
     self._session_constructor = session_constructor or ks_session.Session
     self._app_name = app_name
     self._app_version = app_version
     self._discovery_cache = discovery_cache or None
예제 #6
0
    def __init__(self,
                 config_files=None,
                 vendor_files=None,
                 override_defaults=None,
                 force_ipv4=None,
                 envvar_prefix=None,
                 secure_files=None,
                 pw_func=None,
                 session_constructor=None,
                 app_name=None,
                 app_version=None,
                 load_yaml_config=True,
                 load_envvars=True):
        self.log = _log.setup_logging('openstack.config')
        self._session_constructor = session_constructor
        self._app_name = app_name
        self._app_version = app_version
        self._load_envvars = load_envvars

        if load_yaml_config:
            self._config_files = config_files or CONFIG_FILES
            self._secure_files = secure_files or SECURE_FILES
            self._vendor_files = vendor_files or VENDOR_FILES
        else:
            self._config_files = []
            self._secure_files = []
            self._vendor_files = []

        config_file_override = self._get_envvar('OS_CLIENT_CONFIG_FILE')
        if config_file_override:
            self._config_files.insert(0, config_file_override)

        secure_file_override = self._get_envvar('OS_CLIENT_SECURE_FILE')
        if secure_file_override:
            self._secure_files.insert(0, secure_file_override)

        self.defaults = self._defaults_module.get_defaults()
        if override_defaults:
            self.defaults.update(override_defaults)

        # First, use a config file if it exists where expected
        self.config_filename, self.cloud_config = self._load_config_file()
        _, secure_config = self._load_secure_file()
        if secure_config:
            self.cloud_config = _merge_clouds(self.cloud_config, secure_config)

        if not self.cloud_config:
            self.cloud_config = {'clouds': {}}
        if 'clouds' not in self.cloud_config:
            self.cloud_config['clouds'] = {}

        # Grab ipv6 preference settings from env
        client_config = self.cloud_config.get('client', {})

        if force_ipv4 is not None:
            # If it's passed in to the constructor, honor it.
            self.force_ipv4 = force_ipv4
        else:
            # Get the backwards compat value
            prefer_ipv6 = get_boolean(
                self._get_envvar(
                    'OS_PREFER_IPV6',
                    client_config.get('prefer_ipv6',
                                      client_config.get('prefer-ipv6', True))))
            force_ipv4 = get_boolean(
                self._get_envvar(
                    'OS_FORCE_IPV4',
                    client_config.get('force_ipv4',
                                      client_config.get('broken-ipv6',
                                                        False))))

            self.force_ipv4 = force_ipv4
            if not prefer_ipv6:
                # this will only be false if someone set it explicitly
                # honor their wishes
                self.force_ipv4 = True

        # Next, process environment variables and add them to the mix
        self.envvar_key = self._get_envvar('OS_CLOUD_NAME', 'envvars')
        if self.envvar_key in self.cloud_config['clouds']:
            raise exceptions.ConfigException(
                '"{0}" defines a cloud named "{1}", but'
                ' OS_CLOUD_NAME is also set to "{1}". Please rename'
                ' either your environment based cloud, or one of your'
                ' file-based clouds.'.format(self.config_filename,
                                             self.envvar_key))

        self.default_cloud = self._get_envvar('OS_CLOUD')

        if load_envvars:
            envvars = self._get_os_environ(envvar_prefix=envvar_prefix)
            if envvars:
                self.cloud_config['clouds'][self.envvar_key] = envvars
                if not self.default_cloud:
                    self.default_cloud = self.envvar_key

        if not self.default_cloud and self.cloud_config['clouds']:
            if len(self.cloud_config['clouds'].keys()) == 1:
                # If there is only one cloud just use it. This matches envvars
                # behavior and allows for much less typing.
                # TODO(mordred) allow someone to mark a cloud as "default" in
                # clouds.yaml.
                # The next/iter thing is for python3 compat where dict.keys
                # returns an iterator but in python2 it's a list.
                self.default_cloud = next(
                    iter(self.cloud_config['clouds'].keys()))

        # Finally, fall through and make a cloud that starts with defaults
        # because we need somewhere to put arguments, and there are neither
        # config files or env vars
        if not self.cloud_config['clouds']:
            self.cloud_config = dict(clouds=dict(defaults=dict(self.defaults)))
            self.default_cloud = 'defaults'

        self._cache_expiration_time = 0
        self._cache_path = CACHE_PATH
        self._cache_class = 'dogpile.cache.null'
        self._cache_arguments = {}
        self._cache_expiration = {}
        if 'cache' in self.cloud_config:
            cache_settings = _util.normalize_keys(self.cloud_config['cache'])

            # expiration_time used to be 'max_age' but the dogpile setting
            # is expiration_time. Support max_age for backwards compat.
            self._cache_expiration_time = cache_settings.get(
                'expiration_time',
                cache_settings.get('max_age', self._cache_expiration_time))

            # If cache class is given, use that. If not, but if cache time
            # is given, default to memory. Otherwise, default to nothing.
            # to memory.
            if self._cache_expiration_time:
                self._cache_class = 'dogpile.cache.memory'
            self._cache_class = self.cloud_config['cache'].get(
                'class', self._cache_class)

            self._cache_path = os.path.expanduser(
                cache_settings.get('path', self._cache_path))
            self._cache_arguments = cache_settings.get('arguments',
                                                       self._cache_arguments)
            self._cache_expiration = cache_settings.get(
                'expiration', self._cache_expiration)

        # Flag location to hold the peeked value of an argparse timeout value
        self._argv_timeout = False

        # Save the password callback
        # password = self._pw_callback(prompt="Password: ")
        self._pw_callback = pw_func
예제 #7
0
    def get_one(self, cloud=None, validate=True, argparse=None, **kwargs):
        """Retrieve a single CloudRegion and merge additional options

        :param string cloud:
            The name of the configuration to load from clouds.yaml
        :param boolean validate:
            Validate the config. Setting this to False causes no auth plugin
            to be created. It's really only useful for testing.
        :param Namespace argparse:
            An argparse Namespace object; allows direct passing in of
            argparse options to be added to the cloud config.  Values
            of None and '' will be removed.
        :param region_name: Name of the region of the cloud.
        :param kwargs: Additional configuration options

        :returns: openstack.config.cloud_region.CloudRegion
        :raises: keystoneauth1.exceptions.MissingRequiredOptions
            on missing required auth parameters
        """

        args = self._fix_args(kwargs, argparse=argparse)

        if cloud is None:
            if 'cloud' in args:
                cloud = args['cloud']
            else:
                cloud = self.default_cloud

        config = self._get_base_cloud_config(cloud)

        # Get region specific settings
        if 'region_name' not in args:
            args['region_name'] = ''
        region = self._get_region(cloud=cloud, region_name=args['region_name'])
        args['region_name'] = region['name']
        region_args = copy.deepcopy(region['values'])

        # Regions is a list that we can use to create a list of cloud/region
        # objects. It does not belong in the single-cloud dict
        config.pop('regions', None)

        # Can't just do update, because None values take over
        for arg_list in region_args, args:
            for (key, val) in iter(arg_list.items()):
                if val is not None:
                    if key == 'auth' and config[key] is not None:
                        config[key] = _auth_update(config[key], val)
                    else:
                        config[key] = val

        config = self.magic_fixes(config)
        config = _util.normalize_keys(config)

        # NOTE(dtroyer): OSC needs a hook into the auth args before the
        #                plugin is loaded in order to maintain backward-
        #                compatible behaviour
        config = self.auth_config_hook(config)

        if validate:
            loader = self._get_auth_loader(config)
            config = self._validate_auth(config, loader)
            auth_plugin = loader.load_from_options(**config['auth'])
        else:
            auth_plugin = None

        # If any of the defaults reference other values, we need to expand
        for (key, value) in config.items():
            if hasattr(value, 'format') and key not in FORMAT_EXCLUSIONS:
                config[key] = value.format(**config)

        force_ipv4 = config.pop('force_ipv4', self.force_ipv4)
        prefer_ipv6 = config.pop('prefer_ipv6', True)
        if not prefer_ipv6:
            force_ipv4 = True

        if cloud is None:
            cloud_name = ''
        else:
            cloud_name = str(cloud)
        return self._cloud_region_class(
            name=cloud_name,
            region_name=config['region_name'],
            config=config,
            force_ipv4=force_ipv4,
            auth_plugin=auth_plugin,
            openstack_config=self,
            session_constructor=self._session_constructor,
            app_name=self._app_name,
            app_version=self._app_version,
        )