diff --git a/ldapcherry/__init__.py b/ldapcherry/__init__.py index 6e81d7d..7b0acea 100644 --- a/ldapcherry/__init__.py +++ b/ldapcherry/__init__.py @@ -168,7 +168,7 @@ class ldapCherry(object): else: return logging.INFO - def _reraise(self, exception): + def _reraise(self, exception): """ reraise a given exception""" raise exception diff --git a/ldapcherry/exceptions.py b/ldapcherry/exceptions.py index f8e91cf..21a0876 100644 --- a/ldapcherry/exceptions.py +++ b/ldapcherry/exceptions.py @@ -9,3 +9,16 @@ class MissingParameter(Exception): def __init__(self, section, key): self.section = section self.key = key + +class MissingKey(Exception): + def __init__(self, key): + self.key = key + +class DumplicateRoleKey(Exception): + def __init__(self, role): + self.role = role + +class DumplicateRoleContent(Exception): + def __init__(self, role1, role2): + self.role1 = role1 + self.role2 = role2 diff --git a/ldapcherry/pyyamlwrapper.py b/ldapcherry/pyyamlwrapper.py new file mode 100644 index 0000000..e0af1c9 --- /dev/null +++ b/ldapcherry/pyyamlwrapper.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- + +import os +import sys +from yaml.error import * +from yaml.nodes import * +from yaml.reader import * +from yaml.scanner import * +from yaml.parser import * +from yaml.composer import * +from yaml.constructor import * +from yaml.resolver import * + + +class RelationError(Exception): + def __init__(self, key, value): + self.key = key + self.value = value + +class DumplicatedKey(Exception): + def __init__(self, host, key): + self.host = host + self.key = key + +import yaml + +try: + from yaml import CLoader as Loader, CDumper as Dumper +except ImportError: + from yaml import Loader, Dumper + +# PyYaml wrapper that loads yaml files throwing an exception +#if a key is dumplicated +class MyLoader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) + + def construct_mapping(self, node, deep=False): + exc = sys.exc_info()[1] + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + mapping = {} + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + try: + hash(key) + except TypeError: + raise ConstructorError("while constructing a mapping", node.start_mark, + "found unacceptable key (%s)" % exc, key_node.start_mark) + value = self.construct_object(value_node, deep=deep) + if key in mapping: + raise DumplicatedKey(key, '') + mapping[key] = value + return mapping + + +def loadNoDump(stream): + loader = MyLoader(stream) + try: + return loader.get_single_data() + finally: + loader.dispose() + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/ldapcherry/roles.py b/ldapcherry/roles.py index ccefbf5..f4627c8 100644 --- a/ldapcherry/roles.py +++ b/ldapcherry/roles.py @@ -8,19 +8,20 @@ import os import sys -try: - from yaml import CLoader as Loader, CDumper as Dumper -except ImportError: - from yaml import Loader, Dumper +from ldapcherry.pyyamlwrapper import loadNoDump + class Roles: def __init__(self, role_file): - pass + stream = open(role_file, 'r') + self.roles_raw = loadNoDump(stream) + stream.close() + self._nest() - def _nest(self, role_file): + def _nest(self): """nests the roles (creates roles hierarchy)""" - pass + self.roles = self.roles_raw def write(self, out_file): """write the nested role hierarchy to a file"""