/usr/lib/python2.7/dist-packages/Bcfg2/Server/Lint/Cfg.py is in bcfg2-server 1.4.0~pre2+git141-g6d40dace6358-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | """ ``bcfg2-lint`` plugin for :ref:`Cfg
<server-plugins-generators-cfg>` """
import os
import Bcfg2.Options
from fnmatch import fnmatch
from Bcfg2.Server.Lint import ServerPlugin
from Bcfg2.Server.Plugins.Cfg import CfgGenerator
class Cfg(ServerPlugin):
""" warn about Cfg issues """
__serverplugin__ = 'Cfg'
def Run(self):
for basename, entry in list(self.core.plugins['Cfg'].entries.items()):
self.check_pubkey(basename, entry)
self.check_missing_files()
self.check_conflicting_handlers()
@classmethod
def Errors(cls):
return {"no-pubkey-xml": "warning",
"unknown-cfg-files": "error",
"extra-cfg-files": "error",
"multiple-global-handlers": "error"}
def check_conflicting_handlers(self):
""" Check that a single entryset doesn't have multiple
non-specific (i.e., 'all') handlers. """
cfg = self.core.plugins['Cfg']
for eset in cfg.entries.values():
alls = [e for e in eset.entries.values()
if (e.specific.all and
issubclass(e.__class__, CfgGenerator))]
if len(alls) > 1:
self.LintError("multiple-global-handlers",
"%s has multiple global handlers: %s" %
(eset.path, ", ".join(os.path.basename(e.name)
for e in alls)))
def check_pubkey(self, basename, entry):
""" check that privkey.xml files have corresponding pubkey.xml
files """
if "privkey.xml" not in entry.entries:
return
privkey = entry.entries["privkey.xml"]
if not self.HandlesFile(privkey.name):
return
pubkey = basename + ".pub"
if pubkey not in self.core.plugins['Cfg'].entries:
self.LintError("no-pubkey-xml",
"%s has no corresponding pubkey.xml at %s" %
(basename, pubkey))
else:
pubset = self.core.plugins['Cfg'].entries[pubkey]
if "pubkey.xml" not in pubset.entries:
self.LintError("no-pubkey-xml",
"%s has no corresponding pubkey.xml at %s" %
(basename, pubkey))
def _list_path_components(self, path):
""" Get a list of all components of a path. E.g.,
``self._list_path_components("/foo/bar/foobaz")`` would return
``["foo", "bar", "foo", "baz"]``. The list is not guaranteed
to be in order."""
rv = []
remaining, component = os.path.split(path)
while component != '':
rv.append(component)
remaining, component = os.path.split(remaining)
return rv
def check_missing_files(self):
""" check that all files on the filesystem are known to Cfg """
cfg = self.core.plugins['Cfg']
# first, collect ignore patterns from handlers
ignore = set()
for hdlr in Bcfg2.Options.setup.cfg_handlers:
ignore.update(hdlr.__ignore__)
# next, get a list of all non-ignored files on the filesystem
all_files = set()
for root, _, files in os.walk(cfg.data):
for fname in files:
fpath = os.path.join(root, fname)
# check against the handler ignore patterns and the
# global FAM ignore list
if (not any(fname.endswith("." + i) for i in ignore) and
not any(fnmatch(fpath, p)
for p in Bcfg2.Options.setup.ignore_files) and
not any(fnmatch(c, p)
for p in Bcfg2.Options.setup.ignore_files
for c in self._list_path_components(fpath))):
all_files.add(fpath)
# next, get a list of all files known to Cfg
cfg_files = set()
for root, eset in cfg.entries.items():
cfg_files.update(os.path.join(cfg.data, root.lstrip("/"), fname)
for fname in eset.entries.keys())
# finally, compare the two
unknown_files = all_files - cfg_files
extra_files = cfg_files - all_files
if unknown_files:
self.LintError(
"unknown-cfg-files",
"Files on the filesystem could not be understood by Cfg: %s" %
"; ".join(unknown_files))
if extra_files:
self.LintError(
"extra-cfg-files",
"Cfg has entries for files that do not exist on the "
"filesystem: %s\nThis is probably a bug." %
"; ".join(extra_files))
|