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 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
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)