blob: 8e9bf0688c370924f2b2144f306c6cf0235e1bec [file] [log] [blame]
Benjamin Copeland4e096712020-08-11 16:09:55 +01001import argparse
2import yaml
3import os
4from jinja2 import FileSystemLoader, Environment
5import jenkins
6import logging
7
8
9class LoaderMeta(type):
10
11 def __new__(metacls, __name__, __bases__, __dict__):
12 """Add include constructer to class."""
13
14 # register the include constructor on the class
15 cls = super().__new__(metacls, __name__, __bases__, __dict__)
16 cls.add_constructor('!include', cls.construct_include)
17
18 return cls
19
20
21class Loader(yaml.Loader, metaclass=LoaderMeta):
22 """YAML Loader with `!include` constructor."""
23
24 def __init__(self, stream):
25 """Initialise Loader."""
26
27 try:
28 self._root = os.path.split(stream.name)[0]
29 except AttributeError:
30 self._root = os.path.curdir
31
32 super().__init__(stream)
33
34 def construct_include(self, node):
35 if isinstance(node, yaml.ScalarNode):
36 return self.extractFile(self.construct_scalar(node))
37
38 elif isinstance(node, yaml.SequenceNode):
39 result = []
40 for filename in self.construct_sequence(node):
41 result += self.extractFile(filename)
42 return result
43
44 elif isinstance(node, yaml.MappingNode):
45 result = {}
46 for k,v in self.construct_mapping(node).iteritems():
47 result[k] = self.extractFile(v)
48 return result
49
50 else:
51 print "Error:: unrecognised node type in !include statement"
52 raise yaml.constructor.ConstructorError
53
54
55 def extractFile(self, filename):
56 filepath = os.path.join(self._root, filename)
57 with open(filepath, 'r') as f:
58 return yaml.load(f, Loader=Loader)
59
60
61def jinja2_from_template(directory, template_name, data, dryrun=False):
62 loader = FileSystemLoader(directory)
63 env = Environment(loader=loader)
64 template = env.get_template(template_name)
65 return template.render(hosts=data, dryrun=dryrun)
66
67
68def get_parser():
69 parser = argparse.ArgumentParser()
70 parser.add_argument('-u', '--username', type=str,
71 default=os.environ.get('JJB_USER'),
72 help='Username for Jenkins server')
73 parser.add_argument('-p', '--password', type=str,
74 default=os.environ.get('JJB_PASSWORD'),
75 help='Password for Jenkins server')
76 parser.add_argument('-s', '--server', type=str,
77 default='http://localhost:8080',
78 help='Jenkins server URL. e.g. http://localhost:8080')
79 parser.add_argument('-i', '--inventory', type=str, default='hosts',
80 help='specify inventory host path')
81 parser.add_argument('-l', '--loglevel', default='INFO',
82 help="Setting logging level, default: %(default)s")
83 parser.add_argument('--dryrun', action='store_true',
84 help='Do not publish to Jenkins')
85 parser.add_argument('--local', action='store_true',
86 help='Create tmp file only, to be used with dryrun.')
87 return parser
88
89
90if __name__ == '__main__':
91 parser = get_parser()
92 args = parser.parse_args()
93 logging.basicConfig(level=args.loglevel)
94 with open(args.inventory, 'r') as f:
95 data = yaml.load(f, Loader=Loader)
96 logging.debug(data)
97 template_output = jinja2_from_template(
98 './templates',
99 'configure-yadocker-cloud.groovy.j2', data)
100
101 if not args.local:
102 server = jenkins.Jenkins(args.server, username=args.username,
103 password=args.password)
104 if args.dryrun:
105 with open('/tmp/configure-yadocker-cloud.groovy', 'w') as fw:
106 fw.write(template_output)
107 template_output = jinja2_from_template(
108 './templates',
109 'configure-yadocker-cloud.groovy.j2', data, args.dryrun)
110 if not args.local:
111 publishdry = server.run_script(template_output)
112 if 'error' in publishdry:
113 logging.info(publishdry)
114 exit(1)
115 logging.info(publishdry)
116 else:
117 logging.info('Template file created at \
118 /tmp/configure-yadocker-cloud.groovy')
119 else:
120 publish = server.run_script(template_output)
121 logging.info(publish)