Update the create script with V3 flavors.
[releng/global-jjb.git] / jenkins-admin / create_jenkins_clouds_openstack_yaml.py
1 #!/usr/bin/env python
2
3 import argparse
4 import configparser
5 import glob
6 import os
7 import sys
8
9 from jinja2 import Environment
10 from jinja2 import FileSystemLoader
11 from jinja2 import Template
12
13 #Template section
14 lookuptable = {
15     "acumos-highcpu-4-avx": "c720c1f8-62e9-4695-823d-f7f54db46c86",
16     "lf-highcpu-2": "1051d06a-61ea-45e3-b9b4-93de92880b27",
17     "lf-highcpu-4": "35eb8e11-490f-4d1a-9f19-76091fc04547",
18     "lf-highcpu-8": "68af673f-54ee-4255-871c-158c18e4f643",
19     "lf-standard-1": "7d76cbb0-f547-4c2c-beaf-554f33832721",
20     "lf-standard-2": "ef454088-7839-42a0-bf23-5e0ab6386a27",
21     "lf-standard-4": "bd74e1e6-c2ed-475b-ab3f-2ce13936a215",
22     "lf-standard-8": "32d74024-8418-41b6-9675-b77816748148",
23     "odl-highcpu-2": "def1b86f-b7f8-4943-b430-4a0599170006",
24     "odl-highcpu-4": "0c8ec795-2ff8-4623-98cf-b4c1d92bb37c",
25     "odl-highcpu-8": "458d6499-e2c8-4580-aa88-a4a04a33ee25",
26     "odl-standard-1": "35800a3f-0c69-428d-b5cb-136d17d46c48",
27     "odl-standard-2": "8ead227a-acfe-4290-be70-fbab92e6dd2f",
28     "odl-standard-4": "f76fb18d-d5fb-4175-95c1-b29d8039d102",
29     "odl-standard-8": "ba38b1af-4f87-4e4e-860e-94e8329d0d78",
30     "v1-standard-1": "bbcb7eb5-5c8d-498f-9d7e-307c575d3566",
31     "v1-standard-2": "ca2a6e9c-2236-4107-8905-7ae9427132ff",
32     "v1-standard-4": "5cf64088-893b-46b5-9bb1-ee020277635d",
33     "v1-standard-8": "6eec77b4-2286-4e3b-b3f0-cac67aa2c727",
34     "v1-standard-16": "2f8730dd-7688-4b72-a512-99fb9a482414",
35     "v1-standard-32": "0da688af-bb0c-4116-a158-cbf37240a8b1",
36     "v1-standard-48": "69471d69-61fb-40dd-bdf3-e6b7f4e6daa3",
37     "v1-standard-64": "0c1d9008-f546-4608-9e8f-f8bdaec8dddd",
38     "v1-standard-96": "5741c775-92a4-4488-bd77-dd7b08e2be81",
39     "v1-standard-128": "e82d0a5b-8031-4526-9a5d-a15f7b4d48ff",
40     "v2-highcpu-1": "c04abb7a-2b61-4ed3-8ce8-6c40ad9df750",
41     "v2-highcpu-2": "03bdf34e-8905-46bc-a4b9-8dbf94b6e06d",
42     "v2-highcpu-4": "3b72e578-7875-4e0e-91b7-71ed292f3ca2",
43     "v2-highcpu-8": "221de281-95ec-414f-8e42-c86c9e0b318d",
44     "v2-highcpu-16": "ddd6863a-ef4f-475c-9aee-61d46898651d",
45     "v2-highcpu-32": "21dfb8a3-c472-4a2c-a8e1-4da8de415ff8",
46     "v2-standard-1": "52a01f6b-e660-48b5-8c06-5fb2a0fab0ec",
47     "v2-standard-2": "ac2c4d17-8d6f-4e3c-a9eb-57c155f0a949",
48     "v2-standard-4": "d9115351-defe-4fac-986b-1a1187e2c31c",
49     "v2-standard-8": "e6fe2e37-0e38-438c-8fa5-fc2d79d0a7bb",
50     "v2-standard-16": "9e4b01cd-6744-4120-aafe-1b5e17584919",
51     "v2-standard-360": "f0d27f44-a410-4f0f-9781-d722f5b5489e",
52     "v3-standard-2": "d6906d2a-e83f-42be-b33e-fbaeb5c511cb",
53     "v3-standard-4": "5f1eb09f-e764-4642-a16f-a7230ec025e7",
54     "v3-standard-8": "47d3707a-c6c6-46ea-a15b-095e336b1edc",
55     "v3-standard-16": "8587d458-69de-4fc5-be51-c5e671bc35d5",
56     "v3-standard-32": "3e01b39f-45a9-4b7b-b6dc-14378433dc36",
57     "v3-standard-48": "06a0e8b7-949a-439d-a185-208ae9e645b2",
58     "v3-standard-64": "402a2759-cc01-481d-a8b7-2c7056f153f7",
59     "v3-standard-96": "883b0564-dec6-4e51-88c7-83d86994fcf0"
60 }
61 maintemplate = """\
62 ---
63 jenkins:
64   clouds:
65     - openstack:
66         credentialsId: {{ cloud_credential_id }}
67         endPointUrl: {{ cloud_url }}
68         ignoreSsl: {{ cloud_ignore_ssl }}
69         name: {{ cloud_name }}
70         slaveOptions:
71           availabilityZone: {{ availability_zone }}
72           bootSource:
73             volumeFromImage:
74               name: {{ image_name }}
75               volumeSize: {{ volume_size }}
76           fsRoot: {{ fs_root }}
77           hardwareId: {{ hardware_id }}
78 {%- if is_sandbox is defined %}
79           instanceCap: {{ sandbox_cap }}
80 {%- else %}
81           instanceCap: {{ instance_cap }}{% endif %}
82           keyPairName: {{ key_pair_name }}
83           launcherFactory:
84             ssh:
85               credentialsId: {{ key_pair_name }}
86           networkId: {{ network_id }}
87           retentionTime: {{ retention_time }}
88           userDataId: {{ user_data_id }}
89         templates:
90 """
91 machinetemplate = """\
92           - labels: {{ labels }}
93             name: {{ name_prefix }}-{{ labels }}
94             slaveOptions:
95               bootSource:
96                 volumeFromImage:
97                   name: {{ image_name }}
98                   volumeSize: {{ volume_size }}
99 {%- if hardware_id  %}
100               hardwareId: {{ hardware_id }}{% endif %}
101 {%- if instance_cap %}
102               instanceCap: {{ instance_cap }}{% endif %}
103 {%- if num_executors %}
104               numExectorts: {{ num_executors }}{% endif %}
105 {%- if retention_time %}
106               retentionTime: {{ retention_time }}
107 {%- else %}
108               retentionTime: 0{% endif %}
109 """
110 footertemplate = """\
111         zone: {{ cloud_zone}}
112 """
113
114 #Command line args section
115 def dir_path(path):
116     if os.path.isdir(path):
117         return path
118     else:
119         raise argparse.ArgumentTypeError(f"readable_dir:{path} is not a valid path")
120
121 def parse_arguments():
122     parser = argparse.ArgumentParser(
123         description='Create jcasc yaml from path to jenkins config dir.')
124
125
126     parser.add_argument('--path', type=dir_path,
127                         help="Path to jenkins-admin directory")
128     parser.add_argument('--name', type=str,
129                         help="cloud name IE: cattle")
130
131     parser.add_argument(
132         "-s", "--sandbox",
133         help = "Is configuration being created for a sandbox",
134         dest = "sandbox", action = "store_true"
135     )
136
137     return parser.parse_args()
138
139 parsed_args = parse_arguments()
140 path = (parsed_args.path)
141 path = ("{}**/*.cfg".format(path))
142
143 #sandbox switch section
144 section_cloud = {}
145 name_prefix = "prd"
146 if parsed_args.sandbox:
147     name_prefix = "snd"
148     section_cloud.update(is_sandbox=True)
149
150 #Config parser from merged files section
151 class Iterfiles:
152     def __init__(self, filename):
153         self.filename = filename
154
155     def iterf(self):
156         shortname = os.path.basename(filename)
157         shortname1 = os.path.splitext(shortname)[0]
158         return (self.filename, shortname1)
159
160 class Openfile:
161     def __init__(self, filename, shortname1):
162         self.filename = filename
163         self.shortname1 = shortname1
164     def openf(self):
165         file = open(self.filename, encoding="utf_8")
166         config.read_file(add_section_header(file, self.shortname1), source=self.filename)
167         return config
168
169 #cfg files are not real ini files, need to add section headers.
170 def add_section_header(properties_file, header_name):
171     yield '[{}]\n'.format(header_name)
172     for line in properties_file:
173         yield line
174
175 config = configparser.ConfigParser()
176 for filename in glob.iglob(path, recursive=True):
177     #This just returns the filename you sent it and a shortname
178     # dumb but just messing around with classes.
179     r1 = Iterfiles(filename)
180     r3 = r1.iterf()
181     #now i send the file name and the shortname to Openfile class
182     #which builds up a big configparser with sections divided by shortname
183     r5 = Openfile(r3[0], r3[1])
184     #config_parser_merged is the configparser object with all the configs from *.cfg
185     config_parser_merged = r5.openf()
186
187
188 # Global cloud config section
189 for section in config_parser_merged.sections():
190     if section == "cloud":
191         afinal = (config.items(section))
192         name = parsed_args.name
193         final = (*afinal, ("cloud_name", name))
194
195
196 for index, _ in enumerate(final):
197     a = final[index][0]
198     b = final[index][1]
199     for x, y in lookuptable.items():
200         if b == x:
201             b = y
202     section_cloud[a] = b
203
204 j2_template = Template(maintemplate)
205 print(j2_template.render(section_cloud))
206
207
208 # All machines section
209 for section in config_parser_merged.sections():
210     if section != "cloud":
211         machine = (config.items(section))
212         section_all_machines = {}
213         for index, _ in enumerate(machine):
214             a = machine[index][0]
215             b = machine[index][1]
216             for x, y in lookuptable.items():
217                 if b == x:
218                     b = y
219             #a = format(a)
220             section_all_machines[a] = b
221
222
223         #Default volume size of 10
224         if not "volume_size" in section_all_machines:
225             section_all_machines.update(volume_size="10")
226         if not "labels" in section_all_machines:
227             print("LABELS not Set in builder config")
228             print(section_all_machines)
229             exit(1)
230
231
232         j2_template = Template(machinetemplate)
233         section_all_machines.update(name_prefix=name_prefix)
234         print(j2_template.render(section_all_machines))
235
236
237 #Footer section
238 j2_template = Template(footertemplate)
239 print(j2_template.render(section_cloud))