From 6c4f79c80ea44fd2bceba5b74c5ebc33e2f9da42 Mon Sep 17 00:00:00 2001 From: Andrew Grimberg Date: Fri, 16 Oct 2020 14:53:04 -0700 Subject: [PATCH] Create managed config files yaml from config dir This script requires ruamel.yaml to be installed in the environment that it is run in Will take a configuration tree and build up the JCasC managed files section and output to stdout the resultant yaml Expected configuration of the tree is as follows: top |- config_type |- file-id |- config-params.yaml |- content |- ??CredentialMappings.yaml |- ??CredentialMappings.sandbox.yaml ... The ??CredentialMappins.yaml will be used for production systems and the sandbox version for sandbox systems (pass a -s or --sandbox) Change-Id: I196e99f1db40223a29e892eb86efd70ecaa328f0 Signed-off-by: Andrew Grimberg --- jenkins-admin/create_jenkins_managed_files_yaml.py | 142 +++++++++++++++++++++ ...ate_jenkins_managed_files-3b763a3a29b862ab.yaml | 6 + 2 files changed, 148 insertions(+) create mode 100755 jenkins-admin/create_jenkins_managed_files_yaml.py create mode 100644 releasenotes/notes/create_jenkins_managed_files-3b763a3a29b862ab.yaml diff --git a/jenkins-admin/create_jenkins_managed_files_yaml.py b/jenkins-admin/create_jenkins_managed_files_yaml.py new file mode 100755 index 00000000..bf85a1d3 --- /dev/null +++ b/jenkins-admin/create_jenkins_managed_files_yaml.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +"""Convert Managed Config files to JCasC YAML""" + +from pprint import pformat + +import argparse +import configparser +import logging +import os +import ruamel.yaml +import sys + +yaml = ruamel.yaml.YAML() +yaml.allow_duplicate_keys = True +yaml.preserve_quotes = True + +logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s", + level=logging.INFO) + +def dir_path(path): + """Validate that path provided exists""" + + if os.path.isdir(path): + return path + else: + raise argparse.ArgumentTypeError( + "'%s' is not a valid path" % path) + +def getArgs(): + """Parse the commandline arguments""" + + parser = argparse.ArgumentParser( + description = __doc__, + formatter_class = argparse.ArgumentDefaultsHelpFormatter + ) + + # default argument options + parser.add_argument( + "-o", "--output", help = "Output file", + type = argparse.FileType("w") + ) + parser.add_argument( + "-p", "--path", help = "Path to configuration files to read", + type = dir_path, required = True + ) + parser.add_argument( + "-q", "--quiet", help = "Run quiet", dest = "quiet", + action = "store_true" + ) + parser.add_argument( + "-s", "--sandbox", + help = "Is configuration being created for a sandbox", + dest = "sandbox", action = "store_true" + ) + parser.add_argument( + "-v", "--verbose", dest = "verbose", action = "store_true", + help = "Enable verbose (debug) logging" + ) + + return parser.parse_args() + +def processConfig(path, subpath, files, sandbox): + """Process the configuration file and return the configuration object""" + + logging.debug("In processConfig") + logging.debug("\n" + pformat(path) + "\n" + pformat(subpath) + "\n" + pformat(files)) + + ret = { subpath[0]: + { + "id": subpath[1] + } + } + + for config in files: + # skip all hidden files + if '.' in config[0]: + continue + + if '.yaml' in config: + loadYaml = False + # Only load credential mappings files if the file matches + # the type of jenkins silo (ie production or sandbox) + if 'CredentialMappings' in config: + if sandbox and 'sandbox' in config: + loadYaml = True + elif not sandbox and 'sandbox' not in config: + loadYaml = True + else: + loadYaml = True + + if loadYaml: + stream = open(os.path.join(path, config), 'r') + ret[subpath[0]].update(yaml.load(stream)) + + if 'content' in config: + stream = open(os.path.join(path, config), 'r') + ret[subpath[0]].update({'content': stream.read()}) + + # custom files need to have ${ prefixed with ^ for some reason + if 'custom' in subpath[0] or 'properties' in subpath[0]: + ret[subpath[0]]['content'] = \ + ret[subpath[0]]['content'].replace('${', '^${') + + return ret + +def _main(): + args = getArgs() + + if args.verbose: + logging.getLogger().setLevel(logging.DEBUG) + + if args.quiet: + logging.getLogger().setLevel(logging.ERROR) + + output = { 'unclassified': + { 'globalConfigFiles': + { 'configs': [] } + } + } + + configs = [] + + pathsplit = args.path.split('/') + + for (dirpath, dirnames, filenames) in os.walk(args.path): + logging.debug("\n" + pformat((dirpath, dirnames, filenames))) + + curpath = [x for x in dirpath.split('/') if x not in pathsplit] + if len(curpath) > 1: + configs.append(processConfig(dirpath, curpath, filenames, args.sandbox)) + + + output['unclassified']['globalConfigFiles']['configs'] = configs + + if args.output: + yaml.dump(output, args.output) + else: + yaml.dump(output, sys.stdout) + +if __name__ == "__main__": + sys.exit(_main()) diff --git a/releasenotes/notes/create_jenkins_managed_files-3b763a3a29b862ab.yaml b/releasenotes/notes/create_jenkins_managed_files-3b763a3a29b862ab.yaml new file mode 100644 index 00000000..f39231fb --- /dev/null +++ b/releasenotes/notes/create_jenkins_managed_files-3b763a3a29b862ab.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Adds a create_jenkins_managed_files_yaml.py administrative script for + generating JCasC yaml files from a directory for control of the Managed + Configuration Files plugin -- 2.16.6