-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChef_File_Generator_with_GitConfig.py
345 lines (291 loc) · 16.1 KB
/
Chef_File_Generator_with_GitConfig.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
import os, re, shutil, git
api_version = 3000
i3s_api_versions = [1000, 1020, 1600, 2000, 2010, 2020, 2040]
# Resources dictionary
chef_resource_dict = {'Connection Template': 'connection_template_provider',
'Enclosure': 'enclosure_provider',
'Enclosure Group': 'enclosure_group_provider',
'Ethernet Network': 'ethernet_network_provider',
'FC Network': 'fc_network_provider',
'FCOE Network': 'fcoe_network_provider',
'Hypervisor Cluster Profile': 'hypervisor_cluster_profile_provider',
'Hypervisor Manager': 'hypervisor_manager_provider',
'Interconnect': 'interconnect_provider',
'Logical Enclosure': 'logical_enclosure_provider',
'Logical Interconnect': 'logical_interconnect_provider',
'Logical Interconnect Group': 'logical_interconnect_group_provider',
'Network Set': 'network_set_provider',
'Scope': 'scope_provider',
'Server Certificate': 'server_certificate_provider',
'Server Hardware': 'server_hardware_provider',
'Server Hardware Type': 'server_hardware_type_provider',
'Server Profile': 'server_profile_provider',
'Server Profile Template': 'server_profile_template_provider',
'Storage Pool': 'storage_pool_provider',
'Storage System': 'storage_system_provider',
'Uplink Set': 'uplink_set_provider',
'Volume': 'volume_provider',
'Volume Attachment': 'volume_attachment_provider',
'Volume Template': 'volume_template_provider'
}
chef_i3s_resource_dict = {
'Artifact Bundle': 'artifact_bundle_provider',
'Deployment Plan': 'deployment_plan_provider',
}
path = os.getcwd()
clone_dir = 'chef'
# Deleting the clone directory if exists
if os.path.exists(clone_dir):
shutil.rmtree(clone_dir, ignore_errors=True)
repo = git.Repo.clone_from('https://github.com/HewlettPackard/oneview-chef',
path + os.path.sep + clone_dir)
os.chdir(path + os.path.sep + clone_dir)
cwd = os.getcwd() # gets the path of current working directory(should be SDK repo path)
lib_path_list = ['libraries', 'resource_providers']
lib_path = str(cwd) + os.path.sep + os.path.sep.join(lib_path_list)
spec_path = str(cwd) + os.path.sep + 'spec'
i3s_lib_path_list = ['libraries', 'resource_providers', 'image_streamer']
i3s_lib_path = str(cwd) + os.path.sep + os.path.sep.join(i3s_lib_path_list)
chef_example_path = str(cwd) + os.path.sep + 'examples'
chef_i3s_example_path = chef_example_path + os.path.sep + 'image_streamer'
branchName = 'feature'
remote_branches = []
for ref in repo.git.branch('-r').split('\n'):
remote_branches.append(ref.replace(" ", ""))
branch_present = True if 'origin/' + branchName in remote_branches else False
def checkIfBranchPresent(branchName, remote_branches):
num = 0
while True:
branchName = branchName + '_' + str(num)
num = num + 1
branch_present = True if 'origin/' + branchName in remote_branches else False
if branch_present is False:
break
return branchName
if branch_present is True:
branchName = checkIfBranchPresent(branchName, remote_branches)
else:
pass
new_branch = repo.create_head(branchName)
new_branch.checkout()
def generate_library_files(current_api_version, filepath, file_type, resource_name):
"""
This method will generate the libraries/spec files for each api version for chef SDK.
:param
current_api_version - oneview api version (2200 for OV 5.50)
filepath - location of library/spec files
file_type - Can be library (or) spec
resource_name - Oneview resource name
"""
prev_api_version = int(current_api_version) - 200
prev_api_version_directory = 'api' + str(prev_api_version)
current_api_version_directory = 'api' + str(current_api_version)
file_extension = '.rb' if file_type == 'library' else '_spec.rb'
prev_api_version_file = str(prev_api_version_directory) + file_extension
current_api_version_file = str(current_api_version_directory) + file_extension
c7000_variant_file = 'c7000' + file_extension
synergy_variant_file = 'synergy' + file_extension
# Create api.rb/api_spec.rb file and api folder structure for different variants
create_api_version_file(prev_api_version, current_api_version, filepath, filepath,
prev_api_version_file, current_api_version_file)
create_folder_structure(filepath, prev_api_version_directory, current_api_version_directory)
# Create variant.rb/variant_spec.rb file(c7000 and synergy)
old_api_path = filepath + os.path.sep + str(prev_api_version_directory)
new_api_path = filepath + os.path.sep + str(current_api_version_directory)
create_api_version_file(prev_api_version, current_api_version, old_api_path, new_api_path, c7000_variant_file, c7000_variant_file)
create_api_version_file(prev_api_version, current_api_version, old_api_path, new_api_path, synergy_variant_file, synergy_variant_file)
# Create library/spec files for a resource
resource_file_name = chef_resource_dict[resource_name] + file_extension
c7000_old_path = old_api_path + os.path.sep + 'c7000'
c7000_new_path = new_api_path + os.path.sep + 'c7000'
create_api_version_file(prev_api_version, current_api_version, c7000_old_path, c7000_new_path,
resource_file_name, resource_file_name)
file_rewrite(c7000_new_path, resource_file_name, file_type)
synergy_old_path = old_api_path + os.path.sep + 'synergy'
synergy_new_path = new_api_path + os.path.sep + 'synergy'
create_api_version_file(prev_api_version, current_api_version, synergy_old_path, synergy_new_path,
resource_file_name, resource_file_name)
file_rewrite(synergy_new_path, resource_file_name, file_type)
def generate_i3s_library_files(current_api_version, filepath, file_type, resource_name):
"""
This method will generate the libraries/spec files for i3s for each api version for chef SDK.
:param
current_api_version - i3s api version (2000 for OV 5.40)
filepath - location of library/spec files
file_type - Can be library (or) spec
resource_name - i3s resource name
"""
current_api_version = i3s_api_versions[-1]
prev_api_version = i3s_api_versions[-2]
pre_prev_api_version = i3s_api_versions[-3]
prev_api_version_directory = 'api' + str(prev_api_version)
current_api_version_directory = 'api' + str(current_api_version)
file_extension = '.rb' if file_type == 'library' else '_spec.rb'
prev_api_version_file = str(prev_api_version_directory) + file_extension
current_api_version_file = str(current_api_version_directory) + file_extension
# Create api.rb/api_spec.rb file and api folder structure for different variants
create_i3s_api_version_file(pre_prev_api_version, prev_api_version, current_api_version, filepath, filepath,
prev_api_version_file, current_api_version_file)
create_i3s_folder_structure(filepath, prev_api_version_directory, current_api_version_directory)
old_api_path = filepath + os.path.sep + str(prev_api_version_directory)
new_api_path = filepath + os.path.sep + str(current_api_version_directory)
# Create library/spec files for i3s resource
resource_file_name = chef_i3s_resource_dict[resource_name] + file_extension
create_i3s_api_version_file(pre_prev_api_version, prev_api_version, current_api_version, old_api_path, new_api_path,
resource_file_name, resource_file_name)
file_rewrite(new_api_path, resource_file_name, file_type)
def create_folder_structure(target_path, old_directory, new_directory):
"""
Creates folder structures for each api version
"""
os.chdir(target_path) # switches the python environment to resource directory
if not os.path.exists(new_directory):
print("Created new directory - '{}' in path - '{}'".format(new_directory, target_path))
os.mkdir(new_directory)
os.chdir(new_directory)
if not os.path.exists('c7000'):
print("Created new directory - '{}' in path - '{}'".format('c7000', new_directory))
os.mkdir('c7000')
if not os.path.exists('synergy'):
print("Created new directory - '{}' in path - '{}'".format('synergy', new_directory))
os.mkdir('synergy')
def create_i3s_folder_structure(target_path, old_directory, new_directory):
"""
Creates folder structures for each i3s api version
"""
os.chdir(target_path) # switches the python environment to resource directory
if not os.path.exists(new_directory):
print("Created new directory - '{}' in path - '{}'".format(new_directory, target_path))
os.mkdir(new_directory)
os.chdir(new_directory)
def create_api_version_file(prev_api_version, current_api_version, old_path, new_path, old_file, new_file):
"""
Creates an api_version file for each release if not present (Chef)
"""
os.chdir(old_path) # switches the python environment to resource directory
if os.path.exists(old_file):
f_read = open(old_file).read()
else:
raise Exception("No such file named {}".format(old_file))
os.chdir(new_path)
if not os.path.exists(new_file):
f_read = f_read.replace(str(prev_api_version), str(current_api_version))
pre_prev_api_version = int(prev_api_version) - 200
f_read = f_read.replace(str(pre_prev_api_version), str(prev_api_version)) # this changes inherit path
f_out = open(new_file, 'w') # open the file with the WRITE option
print("Created file - '{}' in path - '{}'".format(new_file, new_path))
f_out.write(f_read) # write the the changes to the file
f_out.close()
def create_i3s_api_version_file(pre_prev_api_version, prev_api_version, current_api_version, old_path, new_path, old_file, new_file):
"""
Creates an api_version file for each release if not present (Chef)
"""
os.chdir(old_path) # switches the python environment to resource directory
if os.path.exists(old_file):
f_read = open(old_file).read()
else:
raise Exception("No such file named {}".format(old_file))
os.chdir(new_path)
if not os.path.exists(new_file):
f_read = f_read.replace(str(prev_api_version), str(current_api_version))
f_read = f_read.replace(str(pre_prev_api_version), str(prev_api_version)) # this changes inherit path
f_out = open(new_file, 'w') # open the file with the WRITE option
print("Created file - '{}' in path - '{}'".format(new_file, new_path))
f_out.write(f_read) # write the the changes to the file
f_out.close()
def modify_spec_helper(current_api_version, filepath):
"""
Adds the spec context for latest api version in 'spec_helper.rb' file
"""
prev_api_version = int(current_api_version) - 200
next_api_version = int(current_api_version) + 200
os.chdir(filepath)
spec_helper_file = 'spec_helper.rb'
search_string1 = "allow_any_instance_of(OneviewSDK::Client).to receive(:appliance_api_version).and_return({})".format(current_api_version)
replace_string1 = search_string1.replace(str(current_api_version), str(next_api_version))
search_string2 = " let(:client{0}) do\n OneviewSDK::Client.new(url: 'https://oneview.example.com', user: 'Administrator', password: 'secret123', api_version: {0})\n end\n".format(prev_api_version)
search_string3 = search_string2.replace(str(prev_api_version), str(current_api_version))
replace_string2 = search_string2 + "\n" + search_string3
f_read = open(spec_helper_file).read()
if search_string1 in f_read and replace_string1 not in f_read:
f_read = f_read.replace(str(search_string1), str(replace_string1))
print("Updating '{}' file with '{}' api version".format(spec_helper_file, current_api_version))
if search_string3 not in f_read and search_string2 in f_read:
f_read = f_read.replace(str(search_string2), str(replace_string2))
print("Updating '{}' file with spec context for '{}' api version".format(spec_helper_file, current_api_version))
f_out = open(spec_helper_file, 'w') # open the file with the WRITE option
f_out.write(f_read) # write the the changes to the file
f_out.close()
def modify_i3s_spec_helper(filepath):
"""
Adds the spec context for latest api version in 'spec_helper.rb' file
"""
prev_api_version = i3s_api_versions[-2]
current_api_version = i3s_api_versions[-1]
os.chdir(filepath)
spec_helper_file = 'spec_helper.rb'
search_string1 = " let(:i3s_client{0}) do\n OneviewSDK::ImageStreamer::Client.new(url: 'https://i3s.example.com', token: 'token123', api_version: {0})\n end\n".format(prev_api_version)
search_string2 = search_string1.replace(str(prev_api_version), str(current_api_version))
replace_string1 = search_string1 + "\n" + search_string2
f_read = open(spec_helper_file).read()
if search_string2 not in f_read and search_string1 in f_read:
f_read = f_read.replace(str(search_string1), str(replace_string1))
print("Updating '{}' file with spec context for '{}' api version".format(spec_helper_file, current_api_version))
f_out = open(spec_helper_file, 'w') # open the file with the WRITE option
f_out.write(f_read) # write the the changes to the file
f_out.close()
def file_rewrite(file_path, filename, file_type):
"""
Re-writes the file contents by removing extra code. Writes only basic inherit part.
"""
if file_type == 'library':
search_string = '^' + '\s+' + 'class'
end_lines = 4
else:
search_string = '^' + '\s+' + 'end'
end_lines = 1
os.chdir(file_path)
file_lines = open(filename).readlines()
fw = open(filename, 'w')
for line in file_lines:
if re.match(search_string, line.strip("\n")):
fw.write(line)
break
else:
fw.write(line)
fw.writelines(file_lines[-end_lines:])
fw.close()
def modify_example_api_version(filepath, file_name, prev_api_version, current_api_version):
os.chdir(filepath)
if os.path.exists(file_name):
f_read = open(file_name).read()
search_string = "api_version: {}".format(str(prev_api_version))
replace_string = "api_version: {}".format(str(current_api_version))
f_read = f_read.replace(search_string, replace_string)
f_out = open(file_name, 'w') # open the file with the WRITE option
f_out.write(f_read) # write the the changes to the file
f_out.close()
if __name__ == '__main__':
for resource in chef_resource_dict:
generate_library_files(api_version, lib_path, 'library', resource)
for i3s_resource in chef_i3s_resource_dict:
generate_i3s_library_files(api_version, i3s_lib_path, 'library', i3s_resource)
modify_spec_helper(api_version, spec_path)
modify_i3s_spec_helper(spec_path)
# Update current api version in examples
chef_example_files = [filename.replace('_provider','')+'.rb' for filename in chef_resource_dict.values()]
chef_i3s_example_files = [filename.replace('_provider','')+'.rb' for filename in chef_i3s_resource_dict.values()]
for resource in chef_example_files:
modify_example_api_version(chef_example_path, resource, int(api_version)-200, api_version)
for resource in chef_i3s_example_files:
modify_example_api_version(chef_i3s_example_path, resource, i3s_api_versions[-2], i3s_api_versions[-1])
repo.git.add(A=True)
repo.git.commit('-m', 'PR for config changes #API{0}'.format(api_version),
author='[email protected]') # to commit changes
repo.git.push('--set-upstream', 'origin', branchName)
repo.close()
os.chdir(path) # Navigate to parent directory
# Delete chef directory as cleanup
if os.path.exists(clone_dir):
print("Deleted clone directory")
shutil.rmtree(clone_dir, ignore_errors=True)