def load(self): """Load mrack configuration, first config file wins, rest is ignored.""" cfg_paths = self.get_config_paths() chosen = None for cfg_path in cfg_paths: if os.path.exists(cfg_path): chosen = cfg_path break if not chosen: logger.debug("No config file found.") self._parser.read_dict({"mrack": {}}) # empty mrack section return try: logger.debug(f"Loading config file: {chosen}.") self._parser.read(chosen) except ParsingError as parse_err: raise ConfigError(f"Invalid syntax in configuration file {chosen}." ) from parse_err if not self._parser.has_section(self.section): raise ConfigError(f"Configuration file {chosen} doesn't have " f"required section [{self.section}].") return
def init_metadata(ctx, user_defined_path): """Load and initialize job metadata.""" config = ctx.obj[CONFIG] meta_path = user_defined_path or config.metadata_path() if not meta_path: raise ConfigError("Job metadata file path not provided.") if not os.path.exists(meta_path): raise ConfigError(f"Job metadata file not found: {meta_path}") metadata_data = load_yaml(meta_path) ctx.obj[METADATA] = metadata_data return metadata_data
def _locate_mrack_section(self): """Locate mrack managed section.""" start = -1 end = -1 mrack_lines = [] errors = [] for index, line in enumerate(self.lines): if MRACK_START in line: if start != -1: errors.append("Multiple start marks.") start = index if MRACK_END in line: if end != -1: errors.append("Multiple end marks.") end = index if start != -1 and end == -1 and index > start: mrack_lines.append([index, line]) # Check errors: if start == -1 and end != -1: errors.append("Doesn't have start mark.") if start != -1 and end == -1: errors.append("Doesn't have end mark.") if end < start: errors.append("End mark before start mark.") if errors: error = "/etc/hosts has broken mrack managed section and needs fixing:\n" for err in errors: error += f" {err}\n" raise ConfigError(error) return (start, end, mrack_lines)
def create_inventory(self): """Create the Ansible inventory in dict form.""" provisioned = self._db.hosts inventory = deepcopy( self._config.get("inventory_layout", DEFAULT_INVENTORY_LAYOUT)) if not isinstance(inventory, dict): raise ConfigError("Inventory layout should be a dictionary") all_group = ensure_all_group(inventory) for host in provisioned.values(): meta_host, _meta_domain = get_host_from_metadata( self._metadata, host.name) # Groups can be defined in both "groups" and "group" variable. groups = meta_host.get("groups", []) group = meta_host.get("group") if group and group not in groups: groups.append(group) # Add only a reference custom groups for group in groups: added = add_to_group(inventory, group, host.name) if not added: # group doesn't exist add_group(inventory, group, host.name) # Main record belongs in "all" group all_group["hosts"][host.name] = self.create_ansible_host(host.name) return inventory
def config(self): """Get transformer/provider configuration from provisioning configuration.""" key = self._config_key try: return self._config[key] except KeyError as key_err: error = f"No '{key}' entry in provisioning configuration" raise ConfigError(error) from key_err
def validate_dict_attrs(dct, attr_list, dct_name): """Validate that dictionary contains all attributes. Based on provided attribute list. """ missing = [a for a in attr_list if a not in dct] if missing: error = f""" '{dct_name} definition:' {dct} 'Is missing required attributes: {missing}' """ raise ConfigError(error)
def wrapped_f(*args, **kwargs): try: return func(*args, **kwargs) except FileNotFoundError as file_error: raise ConfigError(self.error.format( path=file_error.filename)) from file_error