def test_getboolean(self, mock_getboolean): dcp = DefaultConfigParser() mock_getboolean.return_value = True self.assertEqual(dcp.getboolean("section", "option"), True) mock_getboolean.assert_called_with(dcp, "section", "option") mock_getboolean.reset_mock() self.assertEqual( dcp.getboolean("section", "option", default=False, other="test"), True) mock_getboolean.assert_called_with(dcp, "section", "option", other="test") for etype, err in [(ConfigParser.NoOptionError, ConfigParser.NoOptionError(None, None)), (ConfigParser.NoSectionError, ConfigParser.NoSectionError(None))]: mock_getboolean.side_effect = err mock_getboolean.reset_mock() self.assertEqual( dcp.getboolean("section", "option", default=False), False) mock_getboolean.assert_called_with(dcp, "section", "option") mock_getboolean.reset_mock() self.assertRaises(etype, dcp.getboolean, "section", "option") mock_getboolean.assert_called_with(dcp, "section", "option")
def parse_options(): config = ConfigParser.SafeConfigParser(DEFAULTS) config.read(CONFIG) optinfo = dict( profile=Bcfg2.Options.CLIENT_PROFILE, dryrun=Bcfg2.Options.CLIENT_DRYRUN, groups=Bcfg2.Options.Option("Groups", default=[], cmd="-g", odesc='<group>:<group>', cook=Bcfg2.Options.colon_split)) optinfo.update(Bcfg2.Options.CLI_COMMON_OPTIONS) optinfo.update(Bcfg2.Options.SERVER_COMMON_OPTIONS) argv = [Bcfg2.Options.CFILE.cmd, config.get("global", "config")] argv.extend(sys.argv[1:]) setup = Bcfg2.Options.OptionParser(optinfo, argv=argv) setup.parse(argv) setup['commit'] = Bcfg2.Options.list_split(config.get("global", "commit")) for opt in ['debug', 'verbose']: try: setup[opt] = config.getboolean("global", opt) except ConfigParser.NoOptionError: pass try: hostname = setup['args'][0] except IndexError: print(setup.hm) raise SystemExit(1) return (setup, hostname)
def __init__(self, **kwargs): """ See :class:`argparse.ArgumentParser` for a full list of accepted parameters. In addition to supporting all arguments and keyword arguments from :class:`argparse.ArgumentParser`, several additional keyword arguments are allowed. :param components: A list of components to add to the parser. :type components: list :param namespace: The namespace to store options in. Default is :attr:`Bcfg2.Options.setup`. :type namespace: argparse.Namespace :param add_base_options: Whether or not to add the options in :attr:`Bcfg2.Options.Parser.options` to the parser. Setting this to False is default for subparsers. Default is True. :type add_base_options: bool """ self._cfp = ConfigParser.ConfigParser() components = kwargs.pop('components', []) #: The namespace options will be stored in. self.namespace = kwargs.pop('namespace', setup) if self.namespace is None: self.namespace = setup add_base_options = kwargs.pop('add_base_options', True) #: Flag to indicate that this is the pre-parsing 'early' run #: for important options like database settings that must be #: loaded before other components can be. self._early = kwargs.pop('early', False) if 'add_help' not in kwargs: kwargs['add_help'] = add_base_options argparse.ArgumentParser.__init__(self, **kwargs) #: Whether or not parsing has completed on all current options. self.parsed = False #: The argument list that was parsed. self.argv = None #: Components that have been added to the parser self.components = [] #: Options that have been added to the parser self.option_list = [] self._defaults_set = [] self._config_files = [] if add_base_options: self.add_component(self) if components: for component in components: self.add_component(component)
def main(): parser = Bcfg2.Options.get_parser( description="Migrate from Bcfg2 1.2 per-plugin config files to 1.3 " "unified config file") parser.add_options([Bcfg2.Options.Common.repository]) parser.parse() repo = Bcfg2.Options.setup.repository cfp = ConfigParser.ConfigParser() cfp.read(Bcfg2.Options.setup.config) # files that you should remove manually remove = [] # move rules config out of rules.conf and into bcfg2.conf rules_conf = os.path.join(repo, 'Rules', 'rules.conf') if os.path.exists(rules_conf): remove.append(rules_conf) copy_section(rules_conf, cfp, "rules") # move packages config out of packages.conf and into bcfg2.conf pkgs_conf = os.path.join(repo, 'Packages', 'packages.conf') if os.path.exists(pkgs_conf): remove.append(pkgs_conf) copy_section(pkgs_conf, cfp, "global", newsection="packages") for section in ["apt", "yum", "pulp"]: copy_section(pkgs_conf, cfp, section, newsection="packages:" + section) # move reports database config into [database] section if cfp.has_section("statistics"): if not cfp.has_section("database"): cfp.add_section("database") for opt in cfp.options("statistics"): if opt.startswith("database_"): newopt = opt[9:] if cfp.has_option("database", newopt): print("%s in [database] already populated, skipping" % newopt) else: cfp.set("database", newopt, cfp.get("statistics", opt)) cfp.remove_option("statistics", opt) print("Writing %s" % Bcfg2.Options.setup.config) try: cfp.write(open(Bcfg2.Options.setup.config, "w")) if len(remove): print("Settings were migrated, but you must remove these files " "manually:") for path in remove: print(" %s" % path) except IOError: err = sys.exc_info()[1] print("Could not write %s: %s" % (Bcfg2.Options.setup.config, err))
def test_get(self, mock_get): dcp = DefaultConfigParser() mock_get.return_value = "foo" self.assertEqual(dcp.get("section", "option"), "foo") mock_get.assert_called_with(dcp, "section", "option") mock_get.reset_mock() self.assertEqual( dcp.get("section", "option", default="bar", other="test"), "foo") mock_get.assert_called_with(dcp, "section", "option", other="test") for etype, err in [(ConfigParser.NoOptionError, ConfigParser.NoOptionError(None, None)), (ConfigParser.NoSectionError, ConfigParser.NoSectionError(None))]: mock_get.side_effect = err mock_get.reset_mock() self.assertEqual(dcp.get("section", "option", default="bar"), "bar") mock_get.assert_called_with(dcp, "section", "option") mock_get.reset_mock() self.assertRaises(etype, dcp.get, "section", "option") mock_get.assert_called_with(dcp, "section", "option")
def db_from_config(cfile): cp = ConfigParser.ConfigParser() cp.read([cfile]) driver = cp.get('snapshots', 'driver') if driver == 'sqlite': path = cp.get('snapshots', 'database') return 'sqlite:///%s' % path elif driver in ['mysql', 'postgres']: user = cp.get('snapshots', 'user') password = cp.get('snapshots', 'password') host = cp.get('snapshots', 'host') db = cp.get('snapshots', 'database') return '%s://%s:%s@%s/%s' % (driver, user, password, host, db) else: raise Exception("unsupported db driver %s" % driver)
def build_req_config(self, metadata): """ generates a temporary openssl configuration file that is used to generate the required certificate request """ # create temp request config file fd, fname = tempfile.mkstemp() cfp = ConfigParser.ConfigParser({}) cfp.optionxform = str defaults = { 'req': { 'default_md': 'sha1', 'distinguished_name': 'req_distinguished_name', 'req_extensions': 'v3_req', 'x509_extensions': 'v3_req', 'prompt': 'no' }, 'req_distinguished_name': {}, 'v3_req': { 'subjectAltName': '@alt_names' }, 'alt_names': {} } for section in list(defaults.keys()): cfp.add_section(section) for key in defaults[section]: cfp.set(section, key, defaults[section][key]) cert_spec = self.cert.get_spec(metadata) altnamenum = 1 altnames = cert_spec['subjectaltname'] altnames.extend(list(metadata.aliases)) altnames.append(metadata.hostname) for altname in altnames: cfp.set('alt_names', 'DNS.' + str(altnamenum), altname) altnamenum += 1 for item in ['C', 'L', 'ST', 'O', 'OU', 'emailAddress']: if cert_spec[item]: cfp.set('req_distinguished_name', item, cert_spec[item]) cfp.set('req_distinguished_name', 'CN', metadata.hostname) self.debug_log("SSLCA: Writing temporary request config to %s" % fname) try: cfp.write(os.fdopen(fd, 'w')) except IOError: raise PluginExecutionError("SSLCA: Failed to write temporary CSR " "config file: %s" % sys.exc_info()[1]) return fname
def inner(*args, **kwargs): """decorated function.""" cfp = ConfigParser.ConfigParser() for section, options in self.config_data.items(): cfp.add_section(section) for key, val in options.items(): cfp.set(section, key, val) fd, name = tempfile.mkstemp() config_file = os.fdopen(fd, 'w') cfp.write(config_file) config_file.close() args = list(args) + [name] try: rv = func(*args, **kwargs) finally: os.unlink(name) return rv
def build_req_config(self, entry, metadata): """ generates a temporary openssl configuration file that is used to generate the required certificate request """ # create temp request config file conffile = open(tempfile.mkstemp()[1], 'w') cfp = ConfigParser.ConfigParser({}) cfp.optionxform = str defaults = { 'req': { 'default_md': 'sha1', 'distinguished_name': 'req_distinguished_name', 'req_extensions': 'v3_req', 'x509_extensions': 'v3_req', 'prompt': 'no' }, 'req_distinguished_name': {}, 'v3_req': { 'subjectAltName': '@alt_names' }, 'alt_names': {} } for section in list(defaults.keys()): cfp.add_section(section) for key in defaults[section]: cfp.set(section, key, defaults[section][key]) altnamenum = 1 altnames = list(metadata.aliases) altnames.append(metadata.hostname) for altname in altnames: cfp.set('alt_names', 'DNS.' + str(altnamenum), altname) altnamenum += 1 for item in ['C', 'L', 'ST', 'O', 'OU', 'emailAddress']: if self.cert_specs[entry.get('name')][item]: cfp.set('req_distinguished_name', item, self.cert_specs[entry.get('name')][item]) cfp.set('req_distinguished_name', 'CN', metadata.hostname) cfp.write(conffile) conffile.close() return conffile.name
def build_req_config(self, metadata): """ Generates a temporary openssl configuration file that is used to generate the required certificate request. """ fd, fname = tempfile.mkstemp() cfp = ConfigParser.ConfigParser({}) cfp.optionxform = str defaults = dict( req=dict( default_md='sha1', distinguished_name='req_distinguished_name', req_extensions='v3_req', x509_extensions='v3_req', prompt='no'), req_distinguished_name=dict(), v3_req=dict(subjectAltName='@alt_names'), alt_names=dict()) for section in list(defaults.keys()): cfp.add_section(section) for key in defaults[section]: cfp.set(section, key, defaults[section][key]) spec = self.XMLMatch(metadata) cert = spec.find("Cert") altnamenum = 1 altnames = spec.findall('subjectAltName') altnames.extend(list(metadata.aliases)) altnames.append(metadata.hostname) for altname in altnames: cfp.set('alt_names', 'DNS.' + str(altnamenum), altname) altnamenum += 1 for item in ['C', 'L', 'ST', 'O', 'OU', 'emailAddress']: if cert.get(item): cfp.set('req_distinguished_name', item, cert.get(item)) cfp.set('req_distinguished_name', 'CN', metadata.hostname) self.debug_log("Cfg: Writing temporary CSR config to %s" % fname) try: cfp.write(os.fdopen(fd, 'w')) except IOError: raise CfgCreationError("Cfg: Failed to write temporary CSR config " "file: %s" % sys.exc_info()[1]) return fname
def test_reparse(self, config_file): """reparse options.""" result = argparse.Namespace() parser = Parser(components=[self], namespace=result) parser.parse(["-C", config_file]) self.assertFalse(result.test_false_boolean) parser.parse(["-C", config_file]) self.assertFalse(result.test_false_boolean) parser.reparse() self.assertFalse(result.test_false_boolean) parser.reparse(["-C", config_file, "--test-false-boolean"]) self.assertTrue(result.test_false_boolean) cfp = ConfigParser.ConfigParser() cfp.add_section("test") cfp.set("test", "false_boolean", "on") parser.parse(["-C", config_file]) cfp.write(open(config_file, "w")) self.assertTrue(result.test_false_boolean)
def copy_section(src_file, tgt_cfg, section, newsection=None): if newsection is None: newsection = section cfg = ConfigParser.ConfigParser() if len(cfg.read(src_file)) == 1: if cfg.has_section(section): try: tgt_cfg.add_section(newsection) except ConfigParser.DuplicateSectionError: print("[%s] section already exists in %s, adding options" % (newsection, setup['cfile'])) for opt in cfg.options(section): val = cfg.get(section, opt) if tgt_cfg.has_option(newsection, opt): print("%s in [%s] already populated in %s, skipping" % (opt, newsection, setup['cfile'])) print(" %s: %s" % (setup['cfile'], tgt_cfg.get(newsection, opt))) print(" %s: %s" % (src_file, val)) else: print("Set %s in [%s] to %s" % (opt, newsection, val)) tgt_cfg.set(newsection, opt, val)
import os.path # Compatibility import from Bcfg2.Compat import ConfigParser PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) c = ConfigParser.ConfigParser() #This needs to be configurable one day somehow c.read(['./bcfg2.conf']) defaults = { 'database_engine': 'sqlite3', 'database_name': './dev.db', 'database_user': '', 'database_password': '', 'database_host': '', 'database_port': 3306, 'default_mx': 'localhost', 'priority': 10, 'authorized_group': 'admins', } if c.has_section('hostbase'): options = dict(c.items('hostbase')) else: options = defaults # Django settings for Hostbase project. DEBUG = True TEMPLATE_DEBUG = DEBUG ADMINS = (('Root', 'root'), )
def getCFP(self): """ get a config parser for the Bcfg2 config file """ if not self.__cfp: self.__cfp = ConfigParser.ConfigParser() self.__cfp.read(self.configfile) return self.__cfp
self.indent_level = self.indent_level + 1 self._write_common_entries(pkgdata) self._write_perarch_entries(pkgdata) for group in self.groups: self.indent_level = self.indent_level - 1 self._write_to_file('</Group>') self.indent_level = self.indent_level - 1 self._write_to_file('</PackageList>') self._close_file() self._rename_file() if __name__ == '__main__': # Prefix is relative to script path complete_script_path = os.path.join(os.getcwd(), sys.argv[0]) prefix = complete_script_path[:-len('etc/create-debian-pkglist.py')] confparser = ConfigParser.SafeConfigParser() confparser.read(prefix + "etc/debian-pkglist.conf") # We read the whole configuration file before processing each entries # to avoid doing work if there is a problem in the file. sources_list = [] for section in confparser.sections(): sources_list.append(Source(confparser, section, prefix)) for source in sources_list: source.process()
def HandleEvent(self, event=None): """ Updates which files this plugin handles based upon filesystem events. Allows configuration items to be added/removed without server restarts. """ action = event.code2str() if event.filename[0] == '/': return epath = "".join( [self.data, self.handles[event.requestID], event.filename]) if os.path.isdir(epath): ident = self.handles[event.requestID] + event.filename else: ident = self.handles[event.requestID][:-1] fname = os.path.join(ident, event.filename) if event.filename.endswith('.xml'): if action in ['exists', 'created', 'changed']: if event.filename.endswith('key.xml'): key_spec = dict( list( lxml.etree.parse( epath, parser=Bcfg2.Server.XMLParser).find( 'Key').items())) self.key_specs[ident] = { 'bits': key_spec.get('bits', 2048), 'type': key_spec.get('type', 'rsa') } self.Entries['Path'][ident] = self.get_key elif event.filename.endswith('cert.xml'): cert_spec = dict( list( lxml.etree.parse( epath, parser=Bcfg2.Server.XMLParser).find( 'Cert').items())) ca = cert_spec.get('ca', 'default') self.cert_specs[ident] = { 'ca': ca, 'format': cert_spec.get('format', 'pem'), 'key': cert_spec.get('key'), 'days': cert_spec.get('days', 365), 'C': cert_spec.get('c'), 'L': cert_spec.get('l'), 'ST': cert_spec.get('st'), 'OU': cert_spec.get('ou'), 'O': cert_spec.get('o'), 'emailAddress': cert_spec.get('emailaddress') } cfp = ConfigParser.ConfigParser() cfp.read(self.core.cfile) self.CAs[ca] = dict(cfp.items('sslca_' + ca)) self.Entries['Path'][ident] = self.get_cert elif event.filename.endswith("info.xml"): self.infoxml[ident] = Bcfg2.Server.Plugin.InfoXML(epath) self.infoxml[ident].HandleEvent(event) if action == 'deleted': if ident in self.Entries['Path']: del self.Entries['Path'][ident] else: if action in ['exists', 'created']: if os.path.isdir(epath): self.AddDirectoryMonitor(epath[len(self.data):]) if ident not in self.entries and os.path.isfile(epath): self.entries[fname] = self.__child__(epath) self.entries[fname].HandleEvent(event) if action == 'changed': self.entries[fname].HandleEvent(event) elif action == 'deleted': if fname in self.entries: del self.entries[fname] else: self.entries[fname].HandleEvent(event)
self.indent_level = self.indent_level + 1 self._write_common_entries(pkgdata) self._write_perarch_entries(pkgdata) for group in self.groups: self.indent_level = self.indent_level - 1 self._write_to_file('</Group>') self.indent_level = self.indent_level - 1 self._write_to_file('</PackageList>') self._close_file() self._rename_file() if __name__ == '__main__': main_conf_parser = ConfigParser.SafeConfigParser() main_conf_parser.read(['/etc/bcfg2.conf']) repo = main_conf_parser.get('server', 'repository') confparser = ConfigParser.SafeConfigParser() confparser.read(os.path.join(repo, "etc/debian-pkglist.conf")) # We read the whole configuration file before processing each entries # to avoid doing work if there is a problem in the file. sources_list = [] for section in confparser.sections(): sources_list.append(Source(confparser, section, repo)) for source in sources_list: source.process()
def get_config(self, raw=False): # pylint: disable=W0221 """ Get the yum configuration for this collection. :param raw: Return a :class:`ConfigParser.SafeConfigParser` object representing the configuration instead of a string. This is useful if you need to modify the config before writing it (as :func:`write_config` does in order to produce a server-specific configuration). :type raw: bool :returns: string or ConfigParser.SafeConfigParser """ config = ConfigParser.SafeConfigParser() for source in self: for url_map in source.url_map: if url_map['arch'] not in self.metadata.groups: continue basereponame = source.get_repo_name(url_map) reponame = basereponame added = False while not added: try: config.add_section(reponame) added = True except ConfigParser.DuplicateSectionError: match = re.search("-(\d+)", reponame) if match: rid = int(match.group(1)) + 1 else: rid = 1 reponame = "%s-%d" % (basereponame, rid) config.set(reponame, "name", reponame) config.set(reponame, "baseurl", url_map['url']) config.set(reponame, "enabled", "1") if len(source.gpgkeys): config.set(reponame, "gpgcheck", "1") config.set(reponame, "gpgkey", " ".join(source.gpgkeys)) else: config.set(reponame, "gpgcheck", "0") if len(source.blacklist): config.set(reponame, "exclude", " ".join(source.blacklist)) if len(source.whitelist): config.set(reponame, "includepkgs", " ".join(source.whitelist)) if raw: opts = source.server_options else: opts = source.client_options for opt, val in opts.items(): config.set(reponame, opt, val) if raw: return config else: # configparser only writes to file, so we have to use a # StringIO object to get the data out as a string buf = StringIO() config.write(buf) return "# This config was generated automatically by the Bcfg2 " \ "Packages plugin\n\n" + buf.getvalue()
def main(): opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY} setup = Bcfg2.Options.OptionParser(opts) setup.parse(sys.argv[1:]) repo = setup['repo'] configpath = os.path.join(repo, 'Packages') oldconfigfile = os.path.join(configpath, 'config.xml') newconfigfile = os.path.join(configpath, 'packages.conf') newsourcesfile = os.path.join(configpath, 'sources.xml') if not os.path.exists(oldconfigfile): print("%s does not exist, nothing to do" % oldconfigfile) return 1 if not os.path.exists(configpath): print("%s does not exist, cannot write %s" % (configpath, newconfigfile)) return 2 newconfig = ConfigParser.SafeConfigParser() newconfig.add_section("global") oldconfig = lxml.etree.parse(oldconfigfile).getroot() config = oldconfig.xpath('//Sources/Config') if config: if config[0].get("resolver", "enabled").lower() == "disabled": newconfig.add_option("global", "resolver", "disabled") if config[0].get("metadata", "enabled").lower() == "disabled": newconfig.add_option("global", "metadata", "disabled") newconfig.write(open(newconfigfile, "w")) print("%s written" % newconfigfile) oldsources = [oldconfigfile] while oldsources: oldfile = oldsources.pop() oldsource = lxml.etree.parse(oldfile).getroot() if oldfile == oldconfigfile: newfile = newsourcesfile else: newfile = os.path.join(configpath, oldfile.replace("%s/" % configpath, '')) newsource = lxml.etree.Element("Sources", nsmap=oldsource.nsmap) for el in oldsource.getchildren(): if el.tag == lxml.etree.Comment or el.tag == 'Config': # skip comments and Config continue if el.tag == XI + 'include': oldsources.append(os.path.join(configpath, el.get('href'))) newsource.append(el) continue # element must be a *Source newel = lxml.etree.Element("Source", type=el.tag.replace("Source", "").lower()) try: newel.set('recommended', el.find('Recommended').text.lower()) except AttributeError: pass for tag in ['RawURL', 'URL', 'Version']: try: newel.set(tag.lower(), el.find(tag).text) except AttributeError: pass for child in el.getchildren(): if child.tag in [ 'Component', 'Blacklist', 'Whitelist', 'Arch' ]: newel.append(child) groups = [e.text for e in el.findall("Group")] newsource = place_source(newsource, newel, groups) try: open(newfile, 'w').write(lxml.etree.tostring(newsource, pretty_print=True)) print("%s written" % newfile) except IOError: print("Failed to write %s" % newfile)