def mode(self, v): """Pass in the mode to set on the file. EG 0644. Must be between 0 and 0777, the sticky bit is not supported. """ if type(v) is not int: raise exc.ConfigException("mode '%s' is not numeric" % v) if not 0 <= v <= 0o777: raise exc.ConfigException("mode '%#o' out of range" % v) self._mode = v
def render_template(template, config): if is_executable(template): return render_executable(template, config) else: try: return render_moustache(open(template).read(), config) except context.KeyNotFoundError as e: raise exc.ConfigException( "key '%s' from template '%s' does not exist in metadata file." % (e.key, template)) except Exception as e: logger.error("%s", e) raise exc.ConfigException( "could not render moustache template %s" % template)
def group(self, v): """Pass in the GID to set on the file. EG 'rabbitmq' or 501. """ try: if type(v) is int: group = grp.getgrgid(v) elif type(v) is str: group = grp.getgrnam(v) else: raise exc.ConfigException( "group '%s' must be a string or int" % v) except KeyError: raise exc.ConfigException( "group '%s' not found in group database" % v) self._group = group[2]
def owner(self, v): """Pass in the UID to set on the file. EG 'rabbitmq' or 501. """ try: if type(v) is int: user = pwd.getpwuid(v) elif type(v) is str: user = pwd.getpwnam(v) else: raise exc.ConfigException( "owner '%s' must be a string or int" % v) except KeyError: raise exc.ConfigException( "owner '%s' not found in passwd database" % v) self._owner = user[2]
def parse_configs(config_data): '''Generator yields parsed json for each item passed in config_data.''' for input_data, input_path in config_data: try: yield (json.loads(input_data)) except ValueError: raise exc.ConfigException('Could not parse metadata file: %s' % input_path)
def read_configs(config_files): '''Generator yields data from any existing file in list config_files.''' for input_path in [x for x in config_files if x]: if os.path.exists(input_path): try: with open(input_path) as input_file: yield ((input_file.read(), input_path)) except IOError as e: raise exc.ConfigException('Could not open %s for reading. %s' % (input_path, e))
def strip_hash(h, keys): if not keys: return h for k in keys.split('.'): if k in h and isinstance(h[k], dict): h = h[k] else: raise exc.ConfigException( "key '%s' does not correspond to a hash in the metadata file" % keys) return h
def __init__(self, body, **kwargs): super(OacFile, self).__init__() self.body = body for k, v in six.iteritems(self.DEFAULTS): setattr(self, '_' + k, v) for k, v in six.iteritems(kwargs): if not hasattr(self, k): raise exc.ConfigException( "unrecognised file control key '%s'" % (k)) setattr(self, k, v)
def render_executable(path, config): p = subprocess.Popen([path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate(json.dumps(config).encode('utf-8')) p.wait() if p.returncode != 0: raise exc.ConfigException( "config script failed: %s\n\nwith output:\n\n%s" % (path, stdout + stderr)) return stdout.decode('utf-8')
def print_key( config_path, key, type_name, default=None, fallback_metadata=None): config = collect_config.collect_config(config_path, fallback_metadata) config = _extract_key(config_path, key, fallback_metadata) if config is None: if default is not None: print(str(default)) return else: raise exc.ConfigException( 'key %s does not exist in %s' % (key, config_path)) value_types.ensure_type(str(config), type_name) if isinstance(config, (dict, list, bool)): print(json.dumps(config)) else: print(str(config))
def main(argv=sys.argv): opts = parse_opts(argv) if opts.print_templates: print(opts.templates) return 0 if not opts.metadata: if 'OS_CONFIG_FILES' in os.environ: opts.metadata = os.environ['OS_CONFIG_FILES'].split(':') else: opts.metadata = load_list_from_json(opts.os_config_files) if ((not opts.metadata and opts.os_config_files == OS_CONFIG_FILES_PATH)): logger.warning('DEPRECATED: falling back to %s' % OS_CONFIG_FILES_PATH_OLD) opts.metadata = load_list_from_json(OS_CONFIG_FILES_PATH_OLD) if opts.key and opts.boolean_key: logger.warning('--key is not compatible with --boolean-key.' ' --boolean-key ignored.') try: if opts.templates is None: raise exc.ConfigException('missing option --templates') if opts.key: print_key(opts.metadata, opts.key, opts.type, opts.key_default, opts.fallback_metadata) elif opts.boolean_key: return boolean_key(opts.metadata, opts.boolean_key, opts.fallback_metadata) else: install_config(opts.metadata, opts.templates, opts.output, opts.validate, opts.subhash, opts.fallback_metadata) logger.info("success") except exc.ConfigException as e: logger.error(e) return 1 return 0
def build_tree(templates, config): """Return a map of filenames to OacFiles.""" res = {} for in_file, out_file in templates: try: body = render_template(in_file, config) ctrl_file = in_file + CONTROL_FILE_SUFFIX ctrl_dict = {} if os.path.isfile(ctrl_file): with open(ctrl_file) as cf: ctrl_body = cf.read() ctrl_dict = yaml.safe_load(ctrl_body) or {} if not isinstance(ctrl_dict, dict): raise exc.ConfigException("header is not a dict: %s" % in_file) res[out_file] = oac_file.OacFile(body, **ctrl_dict) except exc.ConfigException as e: e.args += in_file, raise return res
def allow_empty(self, value): if type(value) is not bool: raise exc.ConfigException( "allow_empty requires Boolean, got: '%s'" % value) self._allow_empty = value return self