def _generate_override(self, index, value): # If they provided a tuple, they may have named their tuple # or given us a differing file_type. So we unpack it before # we look at the unpacked value. if isinstance(value, tuple): if len(value) < 2: raise YapconfLoadError('Invalid override tuple provided. The ' 'tuple must have a name and value. ' 'Optionally, it can provide a third ' 'argument specifying the file type if ' 'it is different than the default ' 'file_type passed during ' 'initialization.') label = value[0] unpacked_value = value[1] file_type = self._file_type if len(value) > 2: file_type = value[2] else: label = None unpacked_value = value file_type = self._file_type if isinstance(unpacked_value, six.string_types): label = label or unpacked_value # Special String called "ENVIRONMENT" tells us to load # the override as the current environment. Otherwise # a string is a file name. if unpacked_value == 'ENVIRONMENT': override_dict = os.environ.copy() else: override_dict = self._load_file_to_dict( unpacked_value, file_type, YapconfLoadError) elif isinstance(unpacked_value, dict): label = label or "dict-{0}".format(index) override_dict = unpacked_value else: raise YapconfLoadError( "Invalid override given: {0} Overrides " "must be either a dictionary or a filename.".format( unpacked_value)) return label, override_dict
def _write_dict_to_file(self, dictionary, filename, file_type): self._logger.debug("Writing config: {0}".format(dictionary)) self._logger.debug("To ({0}) file: {1}".format(file_type, filename)) if file_type == 'yaml' and not yapconf.yaml_support: raise YapconfLoadError('Cannot output a YAML file because the ' 'yaml module was not loaded. Please ' 'install either PyYaml or ruamel.yaml') elif file_type not in yapconf.FILE_TYPES: raise YapconfLoadError( 'Unsupported file type: {0}'.format(file_type)) with open(filename, 'w', encoding=self._encoding) as conf_file: if file_type == 'json': dumped = json.dumps(dictionary, sort_keys=True, indent=4) conf_file.write(six.u(dumped)) elif file_type == 'yaml': yapconf.yaml.dump(dictionary, conf_file)
def _get_config_if_exists(self, config_file_path, create, file_type): if not os.path.isfile(config_file_path) and create: return {} elif not os.path.isfile(config_file_path): raise YapconfLoadError("Error migrating config file {0}. " "File does not exist. If you would like " "to create the file, you need to pass " "the create flag.".format(config_file_path)) else: return self._load_file_to_dict(config_file_path, file_type, YapconfLoadError)
def get_data(self): result = self.client.read(key=self.key, recursive=True) if not result.dir: raise YapconfLoadError( "Loaded key %s, but it was not a directory according to etcd." % self.key) data = {} for child in result.children: keys = self._extract_keys(child.key) self._add_value(data, keys, child.value) return data
def _extract_source(self, index, override): label, unpacked_value, file_type = self._explode_override(override) if isinstance(unpacked_value, six.string_types): return self._extract_string_source(label, unpacked_value, file_type) elif isinstance(unpacked_value, dict): label = label or "dict-%d" % index return get_source(label, "dict", data=unpacked_value) raise YapconfLoadError( "Invalid override given: %s overrides must be one of the " "following: a dictionary, a filename, a label for a source, or " '"ENVIRONMENT". Got: %s' % (label, unpacked_value) )
def _extract_string_source(self, label, value, file_type): if value in self._sources: return self._sources[value] elif value == "ENVIRONMENT": return get_source(value, "environment") elif value == "CLI": return get_source(value, "cli", spec=self) elif file_type in ["json", "yaml"]: return get_source(value, file_type, filename=value, encoding=self._encoding) raise YapconfLoadError( "Invalid override given: %s. A string type was detected " "but no valid source could be generated. This should be " "a string which points to a label from the sources you added, " 'the string "ENVIRONMENT" or have a file_type of "json" or "yaml"' "got a (value, file_type) of: (%s %s)" % (label, value, file_type) )
def get_data(self): result = self.client.read_namespaced_config_map( self.name, self.namespace) if self.key is None: return result.data if self.key not in result.data: raise YapconfLoadError( "Loaded configmap %s, but could not find key %s in the data " "portion of the configmap." % self.key) nested_config = result.data[self.key] if self.config_type == "json": return json.loads(nested_config, ) elif self.config_type == "yaml": return yapconf.yaml.load(nested_config) else: raise NotImplementedError("Cannot load config with type %s" % self.config_type)
def generate_override(self, separator="."): """Generate an override. Uses ``get_data`` which is expected to be implemented by each child class. Returns: A tuple of label, dict Raises: YapconfLoadError: If a known error occurs. """ data = self.get_data() if not isinstance(data, dict): raise YapconfLoadError( "Invalid source (%s). The data was loaded successfully, but " "the result was not a dictionary. Got %s" % (self.label, type(data))) return self.label, yapconf.flatten(data, separator=separator)
def _extract_string_source(self, label, value, file_type): if value in self._sources: return self._sources[value] elif value == 'ENVIRONMENT': return get_source(value, 'environment') elif file_type in ['json', 'yaml']: return get_source( value, file_type, filename=value, encoding=self._encoding ) raise YapconfLoadError( 'Invalid override given: %s. A string type was detected ' 'but no valid source could be generated. This should be ' 'a string which points to a label from the sources you added, ' 'the string "ENVIRONMENT" or have a file_type of "json" or "yaml"' 'got a (value, file_type) of: (%s %s)' % (label, value, file_type) )
def _explode_override(self, override): label = None unpacked_value = override file_type = self._file_type # If they provided a tuple, they may have named their tuple # or given us a differing file_type. So we unpack it before # we look at the unpacked value. if isinstance(override, tuple): if len(override) < 2: raise YapconfLoadError( "Invalid override tuple provided. The tuple must have a " "name and value. Optionally, it can provide a third " "argument specifying the file type if it is different " "than the default file_type passed during initialization." ) label = override[0] unpacked_value = override[1] if len(override) > 2: file_type = override[2] return label, unpacked_value, file_type