Chore: Upgrade Jenkins-job-builder to 6.3.0
[releng/global-jjb.git] / jenkins-admin / create_jenkins_managed_files_yaml.py
1 #!/usr/bin/env python
2
3 """Convert Managed Config files to JCasC YAML"""
4
5 from pprint import pformat
6
7 import argparse
8 import configparser
9 import logging
10 import os
11 import ruamel.yaml
12 import sys
13
14 yaml = ruamel.yaml.YAML()
15 yaml.allow_duplicate_keys = True
16 yaml.preserve_quotes = True
17
18 logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s",
19     level=logging.INFO)
20
21 def dir_path(path):
22     """Validate that path provided exists"""
23
24     if os.path.isdir(path):
25         return path
26     else:
27         raise argparse.ArgumentTypeError(
28                 "'%s' is not a valid path" % path)
29
30 def getArgs():
31     """Parse the commandline arguments"""
32
33     parser = argparse.ArgumentParser(
34         description = __doc__,
35         formatter_class = argparse.ArgumentDefaultsHelpFormatter
36     )
37
38     # default argument options
39     parser.add_argument(
40         "-o", "--output", help = "Output file",
41         type = argparse.FileType("w")
42     )
43     parser.add_argument(
44         "-p", "--path", help = "Path to configuration files to read",
45         type = dir_path, required = True
46     )
47     parser.add_argument(
48         "-q", "--quiet", help = "Run quiet", dest = "quiet",
49         action = "store_true"
50     )
51     parser.add_argument(
52         "-s", "--sandbox",
53         help = "Is configuration being created for a sandbox",
54         dest = "sandbox", action = "store_true"
55     )
56     parser.add_argument(
57         "-v", "--verbose", dest = "verbose", action = "store_true",
58         help = "Enable verbose (debug) logging"
59     )
60
61     return parser.parse_args()
62
63 def processConfig(path, subpath, files, sandbox):
64     """Process the configuration file and return the configuration object"""
65
66     logging.debug("In processConfig")
67     logging.debug("\n" + pformat(path) + "\n" + pformat(subpath) + "\n" + pformat(files))
68
69     ret = { subpath[0]:
70             {
71                 "id": subpath[1]
72             }
73         }
74
75     for config in files:
76         # skip all hidden files
77         if '.' in config[0]:
78             continue
79
80         if '.yaml' in config:
81             loadYaml = False
82             # Only load credential mappings files if the file matches
83             # the type of jenkins silo (ie production or sandbox)
84             if 'CredentialMappings' in config:
85                 if sandbox and 'sandbox' in config:
86                     loadYaml = True
87                 elif not sandbox and 'sandbox' not in config:
88                     loadYaml = True
89             else:
90                 loadYaml = True
91
92             if loadYaml:
93                 stream = open(os.path.join(path, config), 'r')
94                 ret[subpath[0]].update(yaml.load(stream))
95
96         if 'content' in config:
97             stream = open(os.path.join(path, config), 'r')
98             ret[subpath[0]].update({'content': stream.read()})
99
100             # custom files need to have ${ prefixed with ^ for some reason
101             if 'custom' in subpath[0] or 'properties' in subpath[0]:
102                 ret[subpath[0]]['content'] = \
103                         ret[subpath[0]]['content'].replace('${', '^${')
104
105     return ret
106
107 def _main():
108     args = getArgs()
109
110     if args.verbose:
111         logging.getLogger().setLevel(logging.DEBUG)
112
113     if args.quiet:
114         logging.getLogger().setLevel(logging.ERROR)
115
116     output = { 'unclassified':
117                 { 'globalConfigFiles':
118                     { 'configs': [] }
119                 }
120             }
121
122     configs = []
123
124     pathsplit = args.path.split('/')
125
126     for (dirpath, dirnames, filenames) in os.walk(args.path):
127         logging.debug("\n" + pformat((dirpath, dirnames, filenames)))
128
129         curpath = [x for x in dirpath.split('/') if x not in pathsplit]
130         if len(curpath) > 1:
131             configs.append(processConfig(dirpath, curpath, filenames, args.sandbox))
132
133
134     output['unclassified']['globalConfigFiles']['configs'] = configs
135
136     if args.output:
137         yaml.dump(output, args.output)
138     else:
139         yaml.dump(output, sys.stdout)
140
141 if __name__ == "__main__":
142     sys.exit(_main())