def syntaxhilight(value, arg="diff", autoescape=None): """ Returns a syntax-hilighted version of Code; requires code/language arguments """ if autoescape: # Seems to cause a double escape #value = conditional_escape(value) arg = conditional_escape(arg) if colorize: try: output = u_str('<style type="text/css">') \ + smart_unicode(HtmlFormatter().get_style_defs('.highlight')) \ + u_str('</style>') lexer = get_lexer_by_name(arg) output += highlight(value, lexer, HtmlFormatter()) return mark_safe(output) except: return value else: return mark_safe(u_str('<div class="note-box">Tip: Install pygments ' 'for highlighting</div><pre>%s</pre>') % value)
def syntaxhilight(value, arg="diff", autoescape=None): """ Returns a syntax-hilighted version of Code; requires code/language arguments """ if autoescape: # Seems to cause a double escape #value = conditional_escape(value) arg = conditional_escape(arg) if colorize: try: output = u_str('<style type="text/css">') \ + smart_unicode(HtmlFormatter().get_style_defs('.highlight')) \ + u_str('</style>') lexer = get_lexer_by_name(arg) output += highlight(value, lexer, HtmlFormatter()) return mark_safe(output) except: return value else: return mark_safe( u_str('<div class="note-box">Tip: Install pygments ' 'for highlighting</div><pre>%s</pre>') % value)
def build_snap_ent(entry): basefields = [] if entry.tag in ['Package', 'Service']: basefields += ['type'] desired = dict([(key, u_str(entry.get(key))) for key in basefields]) state = dict([(key, u_str(entry.get(key))) for key in basefields]) desired.update([(key, u_str(entry.get(key))) for key in \ datafields[entry.tag]]) if entry.tag == 'ConfigFile' or \ ((entry.tag == 'Path') and (entry.get('type') == 'file')): if entry.text == None: desired['contents'] = None else: if entry.get('encoding', 'ascii') == 'ascii': desired['contents'] = u_str(entry.text) else: desired['contents'] = u_str(b64decode(entry.text)) if 'current_bfile' in entry.attrib: state['contents'] = u_str(b64decode(entry.get('current_bfile'))) elif 'current_bdiff' in entry.attrib: diff = b64decode(entry.get('current_bdiff')) state['contents'] = u_str( \ '\n'.join(difflib.restore(diff.split('\n'), 1))) state.update([(key, u_str(entry.get('current_' + key, entry.get(key)))) \ for key in datafields[entry.tag]]) if entry.tag in ['ConfigFile', 'Path'] and entry.get('exists', 'true') == 'false': state = None return [desired, state]
def bind_entry(self, entry, _): """ Bind the entry with the data of this key :param entry: The abstract entry to bind. This will be modified in place. :type entry: lxml.etree._Element :returns: None """ entry.set('type', 'file') if entry.get('encoding') == 'base64': entry.text = b64encode(self.data) else: try: entry.text = u_str(self.data, self.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) LOGGER.error(msg) LOGGER.error("Please verify you are using the proper encoding") raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) LOGGER.error(msg) LOGGER.error("You need to specify base64 encoding for %s" % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) if entry.text in ['', None]: entry.set('empty', 'true')
def test_get_data(self): orig_entry = lxml.etree.Element("Path", name="/test", type="file") setup = dict(encoding="ascii", ppath='/', max_copies=5) ptool = self.get_obj(posix=get_posix_object(setup=setup)) entry = copy.deepcopy(orig_entry) entry.text = b64encode("test") entry.set("encoding", "base64") self.assertEqual(ptool._get_data(entry), ("test", True)) entry = copy.deepcopy(orig_entry) entry.set("empty", "true") self.assertEqual(ptool._get_data(entry), ("", False)) entry = copy.deepcopy(orig_entry) entry.text = "test" self.assertEqual(ptool._get_data(entry), ("test", False)) if inPy3k: ustr = 'é' else: ustr = u_str('é', 'UTF-8') entry = copy.deepcopy(orig_entry) entry.text = ustr self.assertEqual(ptool._get_data(entry), (ustr, False))
def bind_entry(self, entry, _): """ Bind the entry with the data of this key :param entry: The abstract entry to bind. This will be modified in place. :type entry: lxml.etree._Element :returns: None """ entry.set('type', 'file') if entry.get('encoding') == 'base64': entry.text = b64encode(self.data) else: try: entry.text = u_str(self.data, Bcfg2.Options.setup.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("Please verify you are using the proper " "encoding") raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("You need to specify base64 encoding for %s" % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) if entry.text in ['', None]: entry.set('empty', 'true')
def bind_entry(self, entry, _): """ Bind the entry with the data of this key :param entry: The abstract entry to bind. This will be modified in place. :type entry: lxml.etree._Element :returns: None """ entry.set("type", "file") if entry.get("encoding") == "base64": entry.text = b64encode(self.data) else: try: entry.text = u_str(self.data, self.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get("name"), sys.exc_info()[1]) LOGGER.error(msg) LOGGER.error("Please verify you are using the proper encoding") raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get("name"), sys.exc_info()[1]) LOGGER.error(msg) LOGGER.error("You need to specify base64 encoding for %s" % entry.get("name")) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) if entry.text in ["", None]: entry.set("empty", "true")
def test_get_data(self): orig_entry = lxml.etree.Element("Path", name="/test", type="file") Bcfg2.Options.setup.encoding = "ascii" ptool = self.get_obj() entry = copy.deepcopy(orig_entry) entry.text = b64encode("test") entry.set("encoding", "base64") self.assertEqual(ptool._get_data(entry), ("test", True)) entry = copy.deepcopy(orig_entry) entry.set("encoding", "base64") entry.set("empty", "true") self.assertEqual(ptool._get_data(entry), ("", True)) entry = copy.deepcopy(orig_entry) entry.set("empty", "true") self.assertEqual(ptool._get_data(entry), ("", False)) entry = copy.deepcopy(orig_entry) self.assertEqual(ptool._get_data(entry), ("", False)) entry = copy.deepcopy(orig_entry) entry.text = "test" self.assertEqual(ptool._get_data(entry), ("test", False)) if inPy3k: ustr = 'é' else: ustr = u_str('é', 'UTF-8') entry = copy.deepcopy(orig_entry) entry.text = ustr self.assertEqual(ptool._get_data(entry), (ustr, False))
def from_metadata(cls, mysession, mymetadata): client = Client.by_value(mysession, name=u_str(mymetadata.hostname)) m = cls(client=client) for group in mymetadata.groups: m.groups.append(Group.by_value(mysession, name=u_str(group))) for connector in mymetadata.connectors: data = getattr(mymetadata, connector) if not isinstance(data, dict): continue for key, value in list(data.items()): if not isinstance(value, str): continue m.keyvals.append( ConnectorKeyVal.by_value(mysession, connector=u_str(connector), key=u_str(key), value=u_str(value)) ) return m
def statistics_from_old_stats(self, metadata, xdata): # entries are name -> (modified, correct, start, desired, end) # not sure we can get all of this from old format stats t1 = time.time() entries = dict([('Package', dict()), ('Service', dict()), ('Path', dict())]) extra = dict([('Package', dict()), ('Service', dict()), ('Path', dict())]) bad = [] state = xdata.find('.//Statistics') correct = state.get('state') == 'clean' revision = u_str(state.get('revision', '-1')) for entry in state.find('.//Bad'): data = [False, False, u_str(entry.get('name'))] \ + build_snap_ent(entry) if entry.tag in ftypes: etag = 'Path' else: etag = entry.tag entries[etag][entry.get('name')] = data for entry in state.find('.//Modified'): if entry.tag in ftypes: etag = 'Path' else: etag = entry.tag if entry.get('name') in entries[etag]: data = [True, False, u_str(entry.get('name'))] + \ build_snap_ent(entry) else: data = [True, False, u_str(entry.get('name'))] + \ build_snap_ent(entry) for entry in state.find('.//Extra'): if entry.tag in datafields: data = build_snap_ent(entry)[1] ename = u_str(entry.get('name')) data['name'] = ename extra[entry.tag][ename] = data else: print("extra", entry.tag, entry.get('name')) t2 = time.time() snap = Snapshot.from_data(self.session, correct, revision, metadata, entries, extra) self.session.add(snap) self.session.commit() t3 = time.time() logger.info("Snapshot storage took %fs" % (t3 - t2)) return True
def from_metadata(cls, mysession, mymetadata): client = Client.by_value(mysession, name=u_str(mymetadata.hostname)) m = cls(client=client) for group in mymetadata.groups: m.groups.append(Group.by_value(mysession, name=u_str(group))) for connector in mymetadata.connectors: data = getattr(mymetadata, connector) if not isinstance(data, dict): continue for key, value in list(data.items()): if not isinstance(value, str): continue m.keyvals.append( ConnectorKeyVal.by_value(mysession, connector=u_str(connector), key=u_str(key), value=u_str(value))) return m
def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) data, generator = self._generate_data(entry, metadata) if generator is not None: # apply no filters if the data was created by a CfgCreator for fltr in self.get_handlers(metadata, CfgFilter): if fltr.specific <= generator.specific: # only apply filters that are as specific or more # specific than the generator used for this entry. # Note that specificity comparison is backwards in # this sense, since it's designed to sort from # most specific to least specific. data = fltr.modify_data(entry, metadata, data) if SETUP['validate']: try: self._validate_data(entry, metadata, data) except CfgVerificationError: raise PluginExecutionError( "Failed to verify %s for %s: %s" % (entry.get('name'), metadata.hostname, sys.exc_info()[1])) if entry.get('encoding') == 'base64': data = b64encode(data) else: try: if not isinstance(data, unicode): if not isinstance(data, str): data = data.decode('utf-8') data = u_str(data, self.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("Please verify you are using the proper " "encoding") raise PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error( "You need to specify base64 encoding for %s" % entry.get('name')) raise PluginExecutionError(msg) except TypeError: # data is already unicode; newer versions of Cheetah # seem to return unicode pass if data: entry.text = data else: entry.set('empty', 'true') return entry
def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) data, generator = self._generate_data(entry, metadata) if generator is not None: # apply no filters if the data was created by a CfgCreator for fltr in self.get_handlers(metadata, CfgFilter): if fltr.specific <= generator.specific: # only apply filters that are as specific or more # specific than the generator used for this entry. # Note that specificity comparison is backwards in # this sense, since it's designed to sort from # most specific to least specific. data = fltr.modify_data(entry, metadata, data) if Bcfg2.Options.setup.cfg_validation: try: self._validate_data(entry, metadata, data) except CfgVerificationError: raise PluginExecutionError("Failed to verify %s for %s: %s" % (entry.get('name'), metadata.hostname, sys.exc_info()[1])) if entry.get('encoding') == 'base64': data = b64encode(data) else: try: if not isinstance(data, unicode): if not isinstance(data, str): data = data.decode('utf-8') data = u_str(data, Bcfg2.Options.setup.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("Please verify you are using the proper " "encoding") raise PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("You need to specify base64 encoding for %s" % entry.get('name')) raise PluginExecutionError(msg) except TypeError: # data is already unicode; newer versions of Cheetah # seem to return unicode pass if data: entry.text = data else: entry.set('empty', 'true') return entry
def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) data = self._generate_data(entry, metadata) for fltr in self.get_handlers(metadata, CfgFilter): data = fltr.modify_data(entry, metadata, data) if self.setup['validate']: try: self._validate_data(entry, metadata, data) except CfgVerificationError: raise PluginExecutionError("Failed to verify %s for %s: %s" % (entry.get('name'), metadata.hostname, sys.exc_info()[1])) if entry.get('encoding') == 'base64': data = b64encode(data) else: try: if not isinstance(data, unicode): if not isinstance(data, str): data = data.decode('utf-8') data = u_str(data, self.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("Please verify you are using the proper " "encoding") raise PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("You need to specify base64 encoding for %s" % entry.get('name')) raise PluginExecutionError(msg) except TypeError: # data is already unicode; newer versions of Cheetah # seem to return unicode pass if data: entry.text = data else: entry.set('empty', 'true') return entry
def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) data = self._generate_data(entry, metadata) for fltr in self.get_handlers(metadata, CfgFilter): data = fltr.modify_data(entry, metadata, data) if self.setup['validate']: try: self._validate_data(entry, metadata, data) except CfgVerificationError: raise PluginExecutionError( "Failed to verify %s for %s: %s" % (entry.get('name'), metadata.hostname, sys.exc_info()[1])) if entry.get('encoding') == 'base64': data = b64encode(data) else: try: if not isinstance(data, unicode): if not isinstance(data, str): data = data.decode('utf-8') data = u_str(data, self.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error("Please verify you are using the proper " "encoding") raise PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) self.logger.error(msg) self.logger.error( "You need to specify base64 encoding for %s" % entry.get('name')) raise PluginExecutionError(msg) except TypeError: # data is already unicode; newer versions of Cheetah # seem to return unicode pass if data: entry.text = data else: entry.set('empty', 'true') return entry
def bind_entry(self, entry, metadata): entry.set('type', 'file') if entry.get('encoding') == 'base64': entry.text = b64encode(self.data) else: try: entry.text = u_str(self.data, self.encoding) except UnicodeDecodeError: e = sys.exc_info()[1] logger.error("Failed to decode %s: %s" % (entry.get('name'), e)) logger.error("Please verify you are using the proper encoding.") raise Bcfg2.Server.Plugin.PluginExecutionError except ValueError: e = sys.exc_info()[1] logger.error("Error in specification for %s" % entry.get('name')) logger.error(str(e)) logger.error("You need to specify base64 encoding for %s." % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError if entry.text in ['', None]: entry.set('empty', 'true')
def __call__(self, args): Bcfg2.Server.Admin.Mode.__call__(self, args) if len(args) == 0 or args[0] == '-h': print(self.__usage__) raise SystemExit(0) if args[0] == 'query': if args[1] in self.q_dispatch: q_obj = self.q_dispatch[args[1]] if q_obj == Client: rows = [] labels = ('Client', 'Active') for host in \ self.session.query(q_obj).filter(q_obj.active == False): rows.append([host.name, 'No']) for host in \ self.session.query(q_obj).filter(q_obj.active == True): rows.append([host.name, 'Yes']) self.print_table([labels]+rows, justify='left', hdr=True, vdelim=" ", padding=1) elif q_obj == Group: print("Groups:") for group in self.session.query(q_obj).all(): print(" %s" % group.name) else: results = self.session.query(q_obj).all() else: print('error') raise SystemExit(1) elif args[0] == 'init': # Initialize the Snapshots database dbpath = Bcfg2.Server.Snapshots.db_from_config(self.cfile) engine = sqlalchemy.create_engine(dbpath, echo=True) metadata = Base.metadata metadata.create_all(engine) Session = sqlalchemy.orm.sessionmaker() Session.configure(bind=engine) session = Session() session.commit() elif args[0] == 'dump': client = args[1] snap = Snapshot.get_current(self.session, u_str(client)) if not snap: print("Current snapshot for %s not found" % client) sys.exit(1) print("Client %s last run at %s" % (client, snap.timestamp)) for pkg in snap.packages: print("C:", pkg.correct, 'M:', pkg.modified) print("start", pkg.start.name, pkg.start.version) print("end", pkg.end.name, pkg.end.version) elif args[0] == 'reports': # bcfg2-admin reporting interface for Snapshots if '-a' in args[1:]: # Query all hosts for Name, Status, Revision, Timestamp q = self.session.query(Client.name, Snapshot.correct, Snapshot.revision, Snapshot.timestamp)\ .filter(Client.id==Snapshot.client_id)\ .group_by(Client.id) rows = [] labels = ('Client', 'Correct', 'Revision', 'Time') for item in q.all(): cli, cor, time, rev = item rows.append([cli, cor, time, rev]) self.print_table([labels]+rows, justify='left', hdr=True, vdelim=" ", padding=1) elif '-b' in args[1:]: # Query a single host for bad entries if len(args) < 3: print("Usage: bcfg2-admin snapshots -b <client>") return client = args[2] snap = Snapshot.get_current(self.session, u_str(client)) if not snap: print("Current snapshot for %s not found" % client) sys.exit(1) print("Bad entries:") bad_pkgs = [self.session.query(Package) .filter(Package.id==p.start_id).one().name \ for p in snap.packages if p.correct == False] for p in bad_pkgs: print(" Package:%s" % p) bad_files = [self.session.query(File) .filter(File.id==f.start_id).one().name \ for f in snap.files if f.correct == False] for filename in bad_files: print(" File:%s" % filename) bad_svcs = [self.session.query(Service) .filter(Service.id==s.start_id).one().name \ for s in snap.services if s.correct == False] for svc in bad_svcs: print(" Service:%s" % svc) elif '-e' in args[1:]: # Query a single host for extra entries client = args[2] snap = Snapshot.get_current(self.session, u_str(client)) if not snap: print("Current snapshot for %s not found" % client) sys.exit(1) print("Extra entries:") for pkg in snap.extra_packages: print(" Package:%s" % pkg.name) # FIXME: Do we know about extra files yet? for f in snap.extra_files: print(" File:%s" % f.name) for svc in snap.extra_services: print(" Service:%s" % svc.name) elif '--date' in args[1:]: year, month, day = args[2:] timestamp = date(int(year), int(month), int(day)) snaps = [] for client in self.session.query(Client).filter(Client.active == True): snaps.append(Snapshot.get_by_date(self.session, client.name, timestamp)) rows = [] labels = ('Client', 'Correct', 'Revision', 'Time') for snap in snaps: rows.append([snap.client.name, snap.correct, snap.revision, snap.timestamp]) self.print_table([labels]+rows, justify='left', hdr=True, vdelim=" ", padding=1) else: print("Unknown options: ", args[1:])
def __call__(self, args): Bcfg2.Server.Admin.Mode.__call__(self, args) if len(args) == 0 or args[0] == '-h': print(self.__usage__) raise SystemExit(0) if args[0] == 'query': if args[1] in self.q_dispatch: q_obj = self.q_dispatch[args[1]] if q_obj == Client: rows = [] labels = ('Client', 'Active') for host in \ self.session.query(q_obj).filter(q_obj.active == False): rows.append([host.name, 'No']) for host in \ self.session.query(q_obj).filter(q_obj.active == True): rows.append([host.name, 'Yes']) self.print_table([labels] + rows, justify='left', hdr=True, vdelim=" ", padding=1) elif q_obj == Group: print("Groups:") for group in self.session.query(q_obj).all(): print(" %s" % group.name) else: results = self.session.query(q_obj).all() else: print('error') raise SystemExit(1) elif args[0] == 'init': # Initialize the Snapshots database dbpath = Bcfg2.Server.Snapshots.db_from_config(self.cfile) engine = sqlalchemy.create_engine(dbpath, echo=True) metadata = Base.metadata metadata.create_all(engine) Session = sqlalchemy.orm.sessionmaker() Session.configure(bind=engine) session = Session() session.commit() elif args[0] == 'dump': client = args[1] snap = Snapshot.get_current(self.session, u_str(client)) if not snap: print("Current snapshot for %s not found" % client) sys.exit(1) print("Client %s last run at %s" % (client, snap.timestamp)) for pkg in snap.packages: print("C:", pkg.correct, 'M:', pkg.modified) print("start", pkg.start.name, pkg.start.version) print("end", pkg.end.name, pkg.end.version) elif args[0] == 'reports': # bcfg2-admin reporting interface for Snapshots if '-a' in args[1:]: # Query all hosts for Name, Status, Revision, Timestamp q = self.session.query(Client.name, Snapshot.correct, Snapshot.revision, Snapshot.timestamp)\ .filter(Client.id==Snapshot.client_id)\ .group_by(Client.id) rows = [] labels = ('Client', 'Correct', 'Revision', 'Time') for item in q.all(): cli, cor, time, rev = item rows.append([cli, cor, time, rev]) self.print_table([labels] + rows, justify='left', hdr=True, vdelim=" ", padding=1) elif '-b' in args[1:]: # Query a single host for bad entries if len(args) < 3: print("Usage: bcfg2-admin snapshots -b <client>") return client = args[2] snap = Snapshot.get_current(self.session, u_str(client)) if not snap: print("Current snapshot for %s not found" % client) sys.exit(1) print("Bad entries:") bad_pkgs = [self.session.query(Package) .filter(Package.id==p.start_id).one().name \ for p in snap.packages if p.correct == False] for p in bad_pkgs: print(" Package:%s" % p) bad_files = [self.session.query(File) .filter(File.id==f.start_id).one().name \ for f in snap.files if f.correct == False] for filename in bad_files: print(" File:%s" % filename) bad_svcs = [self.session.query(Service) .filter(Service.id==s.start_id).one().name \ for s in snap.services if s.correct == False] for svc in bad_svcs: print(" Service:%s" % svc) elif '-e' in args[1:]: # Query a single host for extra entries client = args[2] snap = Snapshot.get_current(self.session, u_str(client)) if not snap: print("Current snapshot for %s not found" % client) sys.exit(1) print("Extra entries:") for pkg in snap.extra_packages: print(" Package:%s" % pkg.name) # FIXME: Do we know about extra files yet? for f in snap.extra_files: print(" File:%s" % f.name) for svc in snap.extra_services: print(" Service:%s" % svc.name) elif '--date' in args[1:]: year, month, day = args[2:] timestamp = date(int(year), int(month), int(day)) snaps = [] for client in self.session.query(Client).filter( Client.active == True): snaps.append( Snapshot.get_by_date(self.session, client.name, timestamp)) rows = [] labels = ('Client', 'Correct', 'Revision', 'Time') for snap in snaps: rows.append([ snap.client.name, snap.correct, snap.revision, snap.timestamp ]) self.print_table([labels] + rows, justify='left', hdr=True, vdelim=" ", padding=1) else: print("Unknown options: ", args[1:])
def bind_entry(self, entry, metadata): info_handlers = [] generators = [] filters = [] verifiers = [] for ent in self.entries.values(): if ent.__specific__ and not ent.specific.matches(metadata): continue if isinstance(ent, CfgInfo): info_handlers.append(ent) elif isinstance(ent, CfgGenerator): generators.append(ent) elif isinstance(ent, CfgFilter): filters.append(ent) elif isinstance(ent, CfgVerifier): verifiers.append(ent) if ent.deprecated: if ent.__basenames__: fdesc = "/".join(ent.__basenames__) elif ent.__extensions__: fdesc = "." + "/.".join(ent.__extensions__) logger.warning("Cfg: %s: Use of %s files is deprecated" % (ent.name, fdesc)) DEFAULT_INFO.bind_info_to_entry(entry, metadata) if len(info_handlers) > 1: logger.error("More than one info supplier found for %s: %s" % (entry.get("name"), info_handlers)) if len(info_handlers): info_handlers[0].bind_info_to_entry(entry, metadata) if entry.tag == 'Path': entry.set('type', 'file') generator = self.best_matching(metadata, generators) if entry.get('perms').lower() == 'inherit': # use on-disk permissions fname = os.path.join(self.path, generator.name) entry.set('perms', str(oct(stat.S_IMODE(os.stat(fname).st_mode)))) try: data = generator.get_data(entry, metadata) except: msg = "Cfg: exception rendering %s with %s: %s" % \ (entry.get("name"), generator, sys.exc_info()[1]) logger.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) for fltr in filters: data = fltr.modify_data(entry, metadata, data) if SETUP['validate']: # we can have multiple verifiers, but we only want to use the # best matching verifier of each class verifiers_by_class = dict() for verifier in verifiers: cls = verifier.__class__.__name__ if cls not in verifiers_by_class: verifiers_by_class[cls] = [verifier] else: verifiers_by_class[cls].append(verifier) for verifiers in verifiers_by_class.values(): verifier = self.best_matching(metadata, verifiers) try: verifier.verify_entry(entry, metadata, data) except CfgVerificationError: msg = "Data for %s for %s failed to verify: %s" % \ (entry.get('name'), metadata.hostname, sys.exc_info()[1]) logger.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) if entry.get('encoding') == 'base64': data = b64encode(data) else: try: if not isinstance(data, unicode): data = u_str(data, self.encoding) except UnicodeDecodeError: msg = "Failed to decode %s: %s" % (entry.get('name'), sys.exc_info()[1]) logger.error(msg) logger.error("Please verify you are using the proper encoding.") raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except ValueError: msg = "Error in specification for %s: %s" % (entry.get('name'), sys.exc_info()[1]) logger.error(msg) logger.error("You need to specify base64 encoding for %s." % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) except TypeError: # data is already unicode; newer versions of Cheetah # seem to return unicode pass if data: entry.text = data else: entry.set('empty', 'true')