From be1fd87aa8a3d2900483326b93f4a2800ec716fc Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 15 Aug 2012 14:33:35 -0400 Subject: added bcfg2-lint plugin to check for malformed group names --- src/lib/Bcfg2/Server/Lint/GroupNames.py | 76 ++++++++++++++++++++++++++++++++ src/lib/Bcfg2/Server/Lint/__init__.py | 4 +- src/lib/Bcfg2/Server/Plugins/Metadata.py | 2 +- 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/lib/Bcfg2/Server/Lint/GroupNames.py 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: -- cgit v1.2.3-1-g7c22