From: Frank Brehm Date: Wed, 15 Aug 2018 10:11:37 +0000 (+0200) Subject: Reading metadata of all modules X-Git-Tag: 0.1.2~6^2~10^2^2~14 X-Git-Url: https://git.uhu-banane.net/?a=commitdiff_plain;h=4ef4669b8ecbfd40964157f7a209e81a62e42932;p=pixelpark%2Fadmin-tools.git Reading metadata of all modules --- diff --git a/pp_lib/check_puppet_env_app.py b/pp_lib/check_puppet_env_app.py index df5bc8d..52a0fdd 100644 --- a/pp_lib/check_puppet_env_app.py +++ b/pp_lib/check_puppet_env_app.py @@ -39,7 +39,7 @@ from .merge import merge_structure from .app import PpApplication -__version__ = '0.2.1' +__version__ = '0.3.1' LOG = logging.getLogger(__name__) @@ -59,6 +59,13 @@ class CheckPuppetEnvApp(PpApplication): default_puppet_root_env_dir = os.sep + os.path.join('etc', 'puppetlabs', 'code', 'environments') + open_args = {} + if six.PY3: + open_args = { + 'encoding': 'utf-8', + 'errors': 'surrogateescape', + } + # ------------------------------------------------------------------------- def __init__( self, appname=None, verbose=0, version=__version__, base_dir=None, @@ -74,6 +81,8 @@ class CheckPuppetEnvApp(PpApplication): self.environments = [] self.env_name = None self.env_dir = None + self.modules_root_dir = None + self.modules = {} super(CheckPuppetEnvApp, self).__init__( appname=appname, verbose=verbose, version=version, base_dir=base_dir, @@ -91,23 +100,23 @@ class CheckPuppetEnvApp(PpApplication): self.post_init() -# # ------------------------------------------------------------------------- -# def as_dict(self, short=True): -# """ -# Transforms the elements of the object into a dict -# -# @param short: don't include local properties in resulting dict. -# @type short: bool -# -# @return: structure as dict -# @rtype: dict -# """ -# -# res = super(CheckPuppetEnvApp, self).as_dict(short=short) -# res['cfg_dir'] = self.cfg_dir -# -# return res -# + # ------------------------------------------------------------------------- + def as_dict(self, short=True): + """ + Transforms the elements of the object into a dict + + @param short: don't include local properties in resulting dict. + @type short: bool + + @return: structure as dict + @rtype: dict + """ + + res = super(CheckPuppetEnvApp, self).as_dict(short=short) + res['open_args'] = self.open_args + + return res + # ------------------------------------------------------------------------- def init_arg_parser(self): """ @@ -245,6 +254,8 @@ class CheckPuppetEnvApp(PpApplication): self.perform_arg_parser() self.init_logging() + self.modules_root_dir = os.path.join(self.env_dir, 'modules') + self.initialized = True # ------------------------------------------------------------------------- @@ -253,8 +264,96 @@ class CheckPuppetEnvApp(PpApplication): Main application routine. """ - LOG.info("I'm walkin, yes indeed, I'm walkin ...") + self.collect_modules() + + # ------------------------------------------------------------------------- + def collect_modules(self): + + LOG.info("Collecting all modules from {!r} ...".format(self.modules_root_dir)) + self.modules = {} + + if not os.path.exists(self.modules_root_dir): + LOG.error("Directory {!r} does not exists.".format(self.modules_root_dir)) + self.exit(7) + if not os.path.isdir(self.modules_root_dir): + LOG.error("Path {!r} is not a directory".format(self.modules_root_dir)) + self.exit(7) + + pattern = os.path.join(self.modules_root_dir, '*') + if self.verbose > 2: + LOG.debug("Globbing pattern for module directories: {!r}".format(pattern)) + for module_dir in glob.glob(pattern): + module_info = self.get_module_info(module_dir) + if module_info: + base_name = module_info['base_name'] + self.modules[base_name] = module_info + + if self.verbose > 2: + LOG.debug("Found module information:\n{}".format(pp(self.modules))) + + # ------------------------------------------------------------------------- + def get_module_info(self, module_dir): + + if self.verbose > 2: + LOG.debug("Get module information from {!r}.".format(module_dir)) + + if not os.path.exists(module_dir): + LOG.warn("Directory {!r} does not exists.".format(module_dir)) + return None + + if not os.path.isdir(module_dir): + LOG.warn("Path {!r} is not a directory".format(module_dir)) + return None + + module_info = {} + module_info['base_name'] = os.path.basename(module_dir) + metadata_file = os.path.join(module_dir, 'metadata.json') + if not os.path.exists(metadata_file): + LOG.warn("Metadatafile {!r} does not exists.".format(metadata_file)) + return None + if not os.path.isfile(metadata_file): + LOG.warn("Metadatafile {!r} is not a regular file.".format(metadata_file)) + return None + if not os.access(metadata_file, os.R_OK): + LOG.warn("Metadatafile {!r} is readable.".format(metadata_file)) + return None + if self.verbose > 2: + LOG.debug("Reading and evaluating {!r}.".format(metadata_file)) + meta_info = {} + + try: + with open(metadata_file, 'r', **self.open_args) as fh: + meta_info = json.load(fh) + except json.JSONDecodeError as e: + LOG.warn(( + "Could not interprete {f!r} (line {l}, column {c}) " + "as a regular JSON file: {e}").format( + f=metadata_file, l=e.lineno, c=e.colno, e=e.msg)) + return None + + module_info['name'] = None + module_info['vendor'] = None + module_info['dependencies'] = {} + if 'name'in meta_info: + module_info['name'] = meta_info['name'] + pat_vendor = r'^(\S+)[-_/]' + re.escape(module_info['base_name']) + r'$' + match = re.match(pat_vendor, module_info['name']) + if match: + module_info['vendor'] = match.group(1) + + if 'dependencies' in meta_info: + for dep in meta_info['dependencies']: + if 'name' in dep: + dep_info = { + 'name': dep['name'], + 'version': None + } + if 'version_requirement' in dep: + dep_info['version'] = dep['version_requirement'] + module_info['dependencies'][dep['name']] = dep_info + + return module_info # =============================================================================