def _upload_config_to_database(self, file_name, domain_name): """Upload a single config file to the database. :param file_name: the file containing the config options :param domain_name: the domain name :returns: a boolean indicating if the upload succeeded """ try: domain_ref = ( self.resource_manager.get_domain_by_name(domain_name)) except exception.DomainNotFound: print(_('Invalid domain name: %(domain)s found in config file ' 'name: %(file)s - ignoring this file.') % { 'domain': domain_name, 'file': file_name}) return False if self.domain_config_manager.get_config_with_sensitive_info( domain_ref['id']): print(_('Domain: %(domain)s already has a configuration ' 'defined - ignoring file: %(file)s.') % { 'domain': domain_name, 'file': file_name}) return False sections = {} try: parser = cfg.ConfigParser(file_name, sections) parser.parse() except Exception: # We explicitly don't try and differentiate the error cases, in # order to keep the code in this tool more robust as oslo.config # changes. print(_('Error parsing configuration file for domain: %(domain)s, ' 'file: %(file)s.') % { 'domain': domain_name, 'file': file_name}) return False try: for group in sections: for option in sections[group]: sections[group][option] = sections[group][option][0] self.domain_config_manager.create_config(domain_ref['id'], sections) return True except Exception as e: msg = ('Error processing config file for domain: ' '%(domain_name)s, file: %(filename)s, error: %(error)s') LOG.error(msg, {'domain_name': domain_name, 'filename': file_name, 'error': e}, exc_info=True) return False
def upload_config_to_database(self, file_name, domain_name): """Upload a single config file to the database. :param file_name: the file containing the config options :param domain_name: the domain name :raises: ValueError: the domain does not exist or already has domain specific configurations defined :raises: Exceptions from oslo config: there is an issue with options defined in the config file or its format The caller of this method should catch the errors raised and handle appropriately in order that the best UX experience can be provided for both the case of when a user has asked for a specific config file to be uploaded, as well as all config files in a directory. """ try: domain_ref = ( self.resource_manager.get_domain_by_name(domain_name)) except exception.DomainNotFound: print(_('Invalid domain name: %(domain)s found in config file ' 'name: %(file)s - ignoring this file.') % { 'domain': domain_name, 'file': file_name}) raise ValueError if self.domain_config_manager.get_config_with_sensitive_info( domain_ref['id']): print(_('Domain: %(domain)s already has a configuration ' 'defined - ignoring file: %(file)s.') % { 'domain': domain_name, 'file': file_name}) raise ValueError sections = {} try: parser = cfg.ConfigParser(file_name, sections) parser.parse() except Exception: # We explicitly don't try and differentiate the error cases, in # order to keep the code in this tool more robust as oslo.config # changes. print(_('Error parsing configuration file for domain: %(domain)s, ' 'file: %(file)s.') % { 'domain': domain_name, 'file': file_name}) raise for group in sections: for option in sections[group]: sections[group][option] = sections[group][option][0] self.domain_config_manager.create_config(domain_ref['id'], sections)
def f(x): # Writing out the file that was just read is suboptimal with tempfile.NamedTemporaryFile(mode='w', delete=True) as fp: fp.write(x) fp.seek(0) sections = {} parser = cfg.ConfigParser(fp.name, sections) parser.parse() for section, entries in expected_contents.items(): for key, value in entries.items(): if sections.get(section, {}).get(key) != value: return False return True
def get_neutron_db_connection_string(): """Retrieve db connection string from Neutron's configuration file. Since we are a subordinate of the neutron-api charm and have no direct relationship with the database ourselves we rely on gleaning Neutron's credentials from its config file. :returns: SQLAlchemy consumable DB connection string. :rtype: str """ sections = {} parser = cfg.ConfigParser(NEUTRON_CONF, sections) parser.parse() return sections['database']['connection'][0]
def _parse_files(conf_files): sections = {} for filename in conf_files: parser = cfg.ConfigParser(filename, sections) try: parser.parse() except IOError: LOG.warning('IOError failure on %(file)s: %(exc)s', { 'file': filename, 'exc': '(file missing or permission issue?)' }) continue except Exception as e: LOG.warning('Failed to parse file %(file)s: %(exc)s', { 'file': filename, 'exc': e }) return [sections]
def get_devices(): """Parse supplied config files and fetch defined supported devices.""" device_tag = 'genericswitch:' devices = {} for filename in CONF.config_file: sections = {} parser = cfg.ConfigParser(filename, sections) try: parser.parse() except IOError: continue for parsed_item, parsed_value in sections.items(): if parsed_item.startswith(device_tag): dev_id = parsed_item.partition(device_tag)[2] device_cfg = {k: v[0] for k, v in parsed_value.items()} devices[dev_id] = device_cfg return devices
def _parse_files(conf_files): try: multi_parser = cfg.MultiConfigParser() multi_parser.read(conf_files) return multi_parser.parsed except AttributeError: # Oslo 6.0.0+ sections = {} for filename in conf_files: parser = cfg.ConfigParser(filename, sections) try: parser.parse() except IOError: LOG.warning('IOError failure on %(file)s: %(exc)s', {'file': filename, 'exc': '(file missing or permission issue?)'}) continue except Exception as e: LOG.warning('Failed to parse file %(file)s: %(exc)s', {'file': filename, 'exc': e}) return [sections]
def get_host_racks_config(): """Read the rack config file to get physical rack configurations.""" # Example section in the file: # [ml2_mech_cisco_nexus:1.1.1.1] # compute1=1/1 # compute2=1/2 # ... host_racks_map = {} sections = {} filepath = CONF.rack_config if not filepath: return host_racks_map if not os.path.exists(filepath): LOG.error(_LE("The rack config file is not found: %s"), filepath) return host_racks_map prefix = CONF.rack_config_prefix if not prefix: LOG.error(_LE("Rack config prefix is not set.")) return host_racks_map try: rack_config_parser = cfg.ConfigParser(filepath, sections) rack_config_parser.parse() for section_name in sections.keys(): if section_name.startswith(prefix): # section_name: rack id for key, value in sections[section_name].items(): # key: host name, value: port id host_racks_map.setdefault(key, set([])) host_racks_map[key].add(section_name) except Exception as e: LOG.error(_LE("The rack config file is not parsed properly: %s"), str(e)) return host_racks_map
def _validate(conf): conf.register_opts(_validator_opts) if conf.namespace: groups = generator._get_groups(generator._list_opts(conf.namespace)) opt_data = generator._generate_machine_readable_data(groups, conf) elif conf.opt_data: opt_data = load_opt_data(conf) else: # TODO(bnemec): Implement this logic with group? raise RuntimeError('Neither namespace nor opt-data provided.') sections = {} parser = cfg.ConfigParser(conf.input_file, sections) parser.parse() warnings = False errors = False if conf.check_defaults: warnings = _validate_defaults(sections, opt_data, conf) for section, options in sections.items(): if section in conf.exclude_group: continue for option in options: if _validate_deprecated_opt(section, option, opt_data): logging.warning('Deprecated opt %s/%s found', section, option) warnings = True elif not _validate_opt(section, option, opt_data): if section in KNOWN_BAD_GROUPS: logging.info( 'Ignoring missing option "%s" from group ' '"%s" because the group is known to have ' 'incomplete sample config data and thus ' 'cannot be validated properly.', option, section) continue logging.error('%s/%s is not part of the sample config', section, option) errors = True if errors or (warnings and conf.fatal_warnings): return 1 return 0
def build_ansible_inventory(): """Get inventory list from config files returns python dict representing ansible inventory according to ansible inventory file yaml definition http://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html """ # TODO(radez): consider take advantage of ansible inventory grouping driver_tag = 'ansible:' booleans = ['manage_vlans'] inventory = {} for conffile in CONF.config_file: # parse each config file sections = {} parser = cfg.ConfigParser(conffile, sections) try: parser.parse() except IOError as e: LOG.error(str(e)) # filter out sections that begin with the driver's tag hosts = {k: v for k, v in sections.items() if k.startswith(driver_tag)} # munge the oslo_config data removing the device tag and # turning lists with single item strings into strings for host in hosts: dev_id = host.partition(driver_tag)[2] dev_cfg = {k: v[0] for k, v in hosts[host].items()} for b in booleans: if b in dev_cfg: dev_cfg[b] = types.Boolean()(dev_cfg[b]) inventory[dev_id] = dev_cfg LOG.info('Ansible Host List: %s', ', '.join(inventory)) return {'all': {'hosts': inventory}}
def __init__(self): """Get inventory list from config files builds a Network-Runner inventory object and a mac_map dictionary according to ansible inventory file yaml definition http://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html """ self.inventory = {} self.mac_map = {} for conffile in CONF.config_file: # parse each config file sections = {} parser = cfg.ConfigParser(conffile, sections) try: parser.parse() except IOError as e: LOG.error(str(e)) # filter out sections that begin with the driver's tag hosts = {k: v for k, v in sections.items() if k.startswith(c.DRIVER_TAG)} # munge the oslo_config data removing the device tag and # turning lists with single item strings into strings for host in hosts: dev_id = host.partition(c.DRIVER_TAG)[2] dev_cfg = {k: v[0] for k, v in hosts[host].items()} for b in c.BOOLEANS: if b in dev_cfg: dev_cfg[b] = types.Boolean()(dev_cfg[b]) self.inventory[dev_id] = dev_cfg # If mac is defined add it to the mac_map if 'mac' in dev_cfg: self.mac_map[dev_cfg['mac'].upper()] = dev_id LOG.info('Ansible Host List: %s', ', '.join(self.inventory))
def get_neutron_credentials(): """Retrieve service credentials from Neutron's configuration file. Since we are a subordinate of the neutron-api charm and have no direct relationship with Keystone ourselves we rely on gleaning Neutron's credentials from its config file. :returns: Map of environment variable name and appropriate value for auth. :rtype: Dict[str,str] """ sections = {} parser = cfg.ConfigParser(NEUTRON_CONF, sections) parser.parse() auth_section = 'keystone_authtoken' return { 'OS_USER_DOMAIN_NAME': sections[auth_section]['user_domain_name'][0], 'OS_PROJECT_DOMAIN_NAME': sections[auth_section]['project_domain_name'][0], 'OS_AUTH_URL': sections[auth_section]['auth_url'][0], 'OS_PROJECT_NAME': sections[auth_section]['project_name'][0], 'OS_USERNAME': sections[auth_section]['username'][0], 'OS_PASSWORD': sections[auth_section]['password'][0], }
# inidiff.py <file1> <file2> # # Author: Johannes Grassler <*****@*****.**> # License: GNU GPL Version 3.0 from oslo_config import cfg import sys f1 = sys.argv[1] f2 = sys.argv[2] s1 = {} s2 = {} p1 = cfg.ConfigParser(f1, s1) p2 = cfg.ConfigParser(f2, s2) p1.parse() p2.parse() for section in s1.keys(): try: sp2 = s2[section] out = [] for key in s1[section].keys(): try: vp1 = s1[section][key][0] vp2 = s2[section][key][0] if (vp1 != vp2): out.append('-%s = %s' % (key, vp1))
def parse_config(config_file): sections = {} parser = cfg.ConfigParser(config_file, sections) parser.parse() return {k: v.pop() for k, v in sections.get('influxdb').iteritems()}