summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/Bcfg2/Server/Lint/GroupNames.py76
-rw-r--r--src/lib/Bcfg2/Server/Lint/__init__.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Metadata.py2
3 files changed, 79 insertions, 3 deletions
diff --git a/src/lib/Bcfg2/Server/Lint/GroupNames.py b/src/lib/Bcfg2/Server/Lint/GroupNames.py
new file mode 100644
index 000000000..069d5d2a5
--- /dev/null
+++ b/src/lib/Bcfg2/Server/Lint/GroupNames.py
@@ -0,0 +1,76 @@
+import os
+import re
+import Bcfg2.Server.Lint
+from Bcfg2.Server.Plugins.Bundler import have_genshi
+if have_genshi:
+ from Bcfg2.Server.Plugins.SGenshi import SGenshiTemplateFile
+
+class GroupNames(Bcfg2.Server.Lint.ServerPlugin):
+ """ ensure that all named groups are valid group names """
+ pattern = r'\S+$'
+ valid = re.compile(r'^' + pattern)
+
+ def Run(self):
+ self.check_metadata()
+ if 'Rules' in self.core.plugins:
+ self.check_rules()
+ if 'Bundler' in self.core.plugins:
+ self.check_bundles()
+ if 'GroupPatterns' in self.core.plugins:
+ self.check_grouppatterns()
+ if 'Cfg' in self.core.plugins:
+ self.check_cfg()
+
+ @classmethod
+ def Errors(cls):
+ return {"invalid-group-name": "error"}
+
+ def check_rules(self):
+ for rules in self.core.plugins['Rules'].entries.values():
+ if not self.HandlesFile(rules.name):
+ continue
+ xdata = rules.pnode.data
+ self.check_entries(xdata.xpath("//Group"),
+ os.path.join(self.config['repo'], rules.name))
+
+ def check_bundles(self):
+ """ check bundles for BoundPath entries with missing attrs """
+ for bundle in self.core.plugins['Bundler'].entries.values():
+ if (self.HandlesFile(bundle.name) and
+ (not have_genshi or
+ not isinstance(bundle, SGenshiTemplateFile))):
+ self.check_entries(bundle.xdata.xpath("//Group"),
+ bundle.name)
+
+ def check_metadata(self):
+ self.check_entries(self.metadata.groups_xml.xdata.xpath("//Group"),
+ os.path.join(self.config['repo'],
+ self.metadata.groups_xml.name))
+
+ def check_grouppatterns(self):
+ cfg = self.core.plugins['GroupPatterns'].config
+ if not self.HandlesFile(cfg.name):
+ return
+ for grp in cfg.xdata.xpath('//GroupPattern/Group'):
+ if not self.valid.search(grp.text):
+ self.LintError("invalid-group-name",
+ "Invalid group name in %s: %s" %
+ (cfg.name, self.RenderXML(grp, keep_text=True)))
+
+ def check_cfg(self):
+ for root, dirs, files in os.walk(self.core.plugins['Cfg'].data):
+ for fname in files:
+ basename = os.path.basename(root)
+ if (re.search(r'^%s\.G\d\d_' % basename, fname) and
+ not re.search(r'^%s\.G\d\d_' % basename + self.pattern,
+ fname)):
+ self.LintError("invalid-group-name",
+ "Invalid group name referenced in %s" %
+ os.path.join(root, fname))
+
+ def check_entries(self, entries, fname):
+ for grp in entries:
+ if not self.valid.search(grp.get("name")):
+ self.LintError("invalid-group-name",
+ "Invalid group name in %s: %s" %
+ (fname, self.RenderXML(grp)))
diff --git a/src/lib/Bcfg2/Server/Lint/__init__.py b/src/lib/Bcfg2/Server/Lint/__init__.py
index 5d7dd707b..42ea6ba8c 100644
--- a/src/lib/Bcfg2/Server/Lint/__init__.py
+++ b/src/lib/Bcfg2/Server/Lint/__init__.py
@@ -81,13 +81,13 @@ class Plugin (object):
def LintError(self, err, msg):
self.errorhandler.dispatch(err, msg)
- def RenderXML(self, element):
+ def RenderXML(self, element, keep_text=False):
"""render an XML element for error output -- line number
prefixed, no children"""
xml = None
if len(element) or element.text:
el = copy(element)
- if el.text:
+ if el.text and not keep_text:
el.text = '...'
[el.remove(c) for c in el.iterchildren()]
xml = lxml.etree.tostring(el).strip()
diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py
index 3c2c3701a..6be189cfd 100644
--- a/src/lib/Bcfg2/Server/Plugins/Metadata.py
+++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py
@@ -1212,7 +1212,7 @@ class MetadataLint(Bcfg2.Server.Lint.ServerPlugin):
"deprecated-clients-options": "warning"}
def deprecated_options(self):
- groupdata = self.metadata.clients_xml.xdata
+ clientdata = self.metadata.clients_xml.xdata
for el in groupdata.xpath("//Client"):
loc = el.get("location")
if loc: