chef-provisioning-oneview 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +43 -3
  3. data/lib/chef/provisioning/create_machine.rb +52 -0
  4. data/lib/chef/provisioning/customize_machine.rb +78 -0
  5. data/lib/chef/provisioning/icsp/api_v104.rb +27 -0
  6. data/lib/chef/provisioning/icsp/icsp_api.rb +282 -0
  7. data/lib/chef/provisioning/oneview/oneview_api.rb +56 -357
  8. data/lib/chef/provisioning/oneview/san_storage.rb +91 -0
  9. data/lib/chef/provisioning/oneview/v1.2/api.rb +3 -0
  10. data/lib/chef/provisioning/oneview_driver.rb +42 -5
  11. data/lib/chef/provisioning/rest.rb +51 -0
  12. data/lib/chef/provisioning/{oneview/version.rb → version.rb} +1 -1
  13. data/spec/shared_context.rb +77 -0
  14. data/spec/spec_helper.rb +8 -6
  15. data/spec/{unit/support → support}/fake_action_handler.rb +0 -0
  16. data/spec/support/fake_icsp.rb +73 -21
  17. data/spec/support/fake_machine_spec.rb +18 -0
  18. data/spec/support/fake_oneview.rb +148 -21
  19. data/spec/support/fixtures/icsp/v102/error_404.json +13 -13
  20. data/spec/support/fixtures/icsp/v102/login.json +4 -4
  21. data/spec/support/fixtures/icsp/v102/os-deployment-build-plans.json +99 -99
  22. data/spec/support/fixtures/icsp/v102/{os-deployment-servers_managed.json → os-deployment-servers.json} +178 -178
  23. data/spec/support/fixtures/icsp/v102/os-deployment-servers_1670001.json +83 -0
  24. data/spec/support/fixtures/icsp/v102/os-deployment-servers_fakesn.json +9 -0
  25. data/spec/support/fixtures/icsp/v102/{server_by_sn.json → server_by_sn_VCGE9KB041.json} +44 -44
  26. data/spec/support/fixtures/icsp/v102/server_by_sn_empty.json +16 -0
  27. data/spec/support/fixtures/icsp/v102/version.json +3 -3
  28. data/spec/support/fixtures/oneview/v120/error_404.json +13 -13
  29. data/spec/support/fixtures/oneview/v120/login.json +4 -4
  30. data/spec/support/fixtures/oneview/v120/server-hardware.json +1475 -1475
  31. data/spec/support/fixtures/oneview/v120/server-hardware_Template-WebServer.json +468 -0
  32. data/spec/support/fixtures/oneview/v120/server-hardware_specific.json +151 -0
  33. data/spec/support/fixtures/oneview/v120/server-profiles.json +368 -746
  34. data/spec/support/fixtures/oneview/v120/server-profiles_invalid_filter.json +14 -0
  35. data/spec/support/fixtures/oneview/v120/{server-profiles_specific.json → server-profiles_name_Template-WebServer.json} +132 -132
  36. data/spec/support/fixtures/oneview/v120/server-profiles_name_Template-WebServerWithSAN.json +200 -0
  37. data/spec/support/fixtures/oneview/v120/server-profiles_name_chef-web01.json +133 -0
  38. data/spec/support/fixtures/oneview/v120/server-profiles_name_chef-web03.json +133 -0
  39. data/spec/support/fixtures/oneview/v120/server-profiles_name_empty.json +15 -0
  40. data/spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB041.json +133 -0
  41. data/spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB042.json +206 -0
  42. data/spec/support/fixtures/oneview/v120/server-profiles_sn_empty.json +15 -0
  43. data/spec/support/fixtures/oneview/v120/storage-volumes_1B5D3CA2-6C5B-41C2-8B97-1821F1883F22.json +26 -0
  44. data/spec/support/fixtures/oneview/v120/tasks_fake_active.json +5 -0
  45. data/spec/support/fixtures/oneview/v120/tasks_fake_complete.json +5 -0
  46. data/spec/support/fixtures/oneview/v120/version.json +3 -3
  47. data/spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplate.json +109 -0
  48. data/spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplateWithSAN.json +144 -0
  49. data/spec/support/fixtures/oneview/v200/server-profile-templates_invalid.json +16 -0
  50. data/spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplate.json +125 -0
  51. data/spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplateWithSAN.json +178 -0
  52. data/spec/support/fixtures/oneview/v200/version.json +4 -0
  53. data/spec/unit/create_machine_spec.rb +78 -0
  54. data/spec/unit/destroy_spec.rb +26 -0
  55. data/spec/unit/icsp_nic_teams_spec.rb +38 -0
  56. data/spec/unit/icsp_search_spec.rb +25 -0
  57. data/spec/unit/oneview_driver_spec.rb +37 -64
  58. data/spec/unit/oneview_login_spec.rb +23 -0
  59. data/spec/unit/oneview_power_spec.rb +51 -0
  60. data/spec/unit/oneview_san_spec.rb +86 -0
  61. data/spec/unit/oneview_search_spec.rb +63 -0
  62. data/spec/unit/rest_api_spec.rb +115 -0
  63. metadata +90 -9
  64. data/lib/chef/provisioning/oneview/v1.20/api.rb +0 -3
@@ -1,61 +1,11 @@
1
- require_relative 'v1.20/api'
2
- require_relative 'v2.0/api'
1
+ Dir[File.dirname(__FILE__) + '/**/*.rb'].each {|file| require file } # Include all helper files in this directory & subdirectories
3
2
 
4
3
  module OneViewAPI
5
4
  private
6
5
 
7
- include OneViewAPIv1_20
6
+ include OneViewAPIv1_2
8
7
  include OneViewAPIv2_0
9
-
10
- # API calls for OneView and ICSP
11
- def rest_api(host, type, path, options = {})
12
- disable_ssl = false
13
- case host
14
- when 'icsp', :icsp
15
- uri = URI.parse(URI.escape(@icsp_base_url + path))
16
- options['X-API-Version'] ||= @icsp_api_version unless [:put, 'put'].include?(type.downcase)
17
- options['auth'] ||= @icsp_key
18
- disable_ssl = true if @icsp_disable_ssl
19
- when 'oneview', :oneview
20
- uri = URI.parse(URI.escape(@oneview_base_url + path))
21
- options['X-API-Version'] ||= @oneview_api_version
22
- options['auth'] ||= @oneview_key
23
- disable_ssl = true if @oneview_disable_ssl
24
- else
25
- fail "Invalid rest host: #{host}"
26
- end
27
-
28
- http = Net::HTTP.new(uri.host, uri.port)
29
- http.use_ssl = true if uri.scheme == 'https'
30
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE if disable_ssl
31
-
32
- case type.downcase
33
- when 'get', :get
34
- request = Net::HTTP::Get.new(uri.request_uri)
35
- when 'post', :post
36
- request = Net::HTTP::Post.new(uri.request_uri)
37
- when 'put', :put
38
- request = Net::HTTP::Put.new(uri.request_uri)
39
- when 'delete', :delete
40
- request = Net::HTTP::Delete.new(uri.request_uri)
41
- else
42
- fail "Invalid rest call: #{type}"
43
- end
44
- options['Content-Type'] ||= 'application/json'
45
- options.delete('Content-Type') if [:none, 'none', nil].include?(options['Content-Type'])
46
- options.delete('X-API-Version') if [:none, 'none', nil].include?(options['X-API-Version'])
47
- options.delete('auth') if [:none, 'none', nil].include?(options['auth'])
48
- options.each do |key, val|
49
- if key.downcase == 'body'
50
- request.body = val.to_json rescue val
51
- else
52
- request[key] = val
53
- end
54
- end
55
-
56
- response = http.request(request)
57
- JSON.parse(response.body) rescue response
58
- end
8
+ include OneViewSanStorage
59
9
 
60
10
  def get_oneview_api_version
61
11
  begin
@@ -72,42 +22,6 @@ module OneViewAPI
72
22
  version
73
23
  end
74
24
 
75
- def get_icsp_api_version
76
- begin
77
- version = rest_api(:icsp, :get, '/rest/version', { 'Content-Type' => :none, 'X-API-Version' => :none, 'auth' => :none })['currentVersion']
78
- fail "Couldn't get API version" unless version
79
- if version.class != Fixnum
80
- version = version.to_i
81
- fail 'API version type mismatch' if !version > 0
82
- end
83
- rescue
84
- puts 'Failed to get ICSP API version. Setting to default (102)'
85
- version = 102
86
- end
87
- version
88
- end
89
-
90
- # Login functions
91
- def auth_tokens
92
- @icsp_key ||= login_to_icsp
93
- @oneview_key ||= login_to_oneview
94
- { 'icsp_key' => @icsp_key, 'oneview_key' => @oneview_key }
95
- end
96
-
97
- def login_to_icsp
98
- path = '/rest/login-sessions'
99
- options = {
100
- 'body' => {
101
- 'userName' => @icsp_username,
102
- 'password' => @icsp_password,
103
- 'authLoginDomain' => 'LOCAL'
104
- }
105
- }
106
- response = rest_api(:icsp, :post, path, options)
107
- return response['sessionID'] if response['sessionID']
108
- fail("\nERROR! Couldn't log into OneView server at #{@oneview_base_url}. Response:\n#{response}")
109
- end
110
-
111
25
  def login_to_oneview
112
26
  path = '/rest/login-sessions'
113
27
  options = {
@@ -122,33 +36,69 @@ module OneViewAPI
122
36
  fail("\nERROR! Couldn't log into OneView server at #{@oneview_base_url}. Response:\n#{response}")
123
37
  end
124
38
 
125
-
126
39
  def get_oneview_profile_by_sn(serialNumber)
40
+ fail 'Must specify a serialNumber!' if serialNumber.nil? || serialNumber.empty?
127
41
  matching_profiles = rest_api(:oneview, :get, "/rest/server-profiles?filter=serialNumber matches '#{serialNumber}'&sort=name:asc")
42
+ fail "Failed to get oneview profile by serialNumber: #{serialNumber}. Response: #{matching_profiles}" unless matching_profiles['count']
128
43
  return matching_profiles['members'].first if matching_profiles['count'] > 0
129
44
  nil
130
45
  end
131
46
 
132
- def get_icsp_server_by_sn(serialNumber)
133
- search_result = rest_api(:icsp, :get,
134
- "/rest/index/resources?category=osdserver&query='osdServerSerialNumber:\"#{serial_number}\"'")['members'] rescue nil
135
- if search_result && search_result.size == 1 && search_result.first['attributes']['osdServerSerialNumber'] == serial_number
136
- my_server = search_result.first
47
+ # Search for OneView Template by name
48
+ def get_oneview_template(template_name)
49
+ if @current_oneview_api_version >= 200
50
+ # Look for Server Profile Template (OneView 2.0 or higher)
51
+ options = { 'X-API-Version' => 200 }
52
+ templates = rest_api(:oneview, :get, "/rest/server-profile-templates?filter=\"name matches '#{template_name}'\"&sort=name:asc", options)['members']
53
+ return rest_api(:oneview, :get, "#{templates.first['uri']}/new-profile", options) if templates && templates.count == 1
54
+ fail "'#{template_name}' matches multiple templates! Please use a unique template name." if templates && templates.count > 1
137
55
  end
138
- unless my_server && my_server['uri']
139
- os_deployment_servers = rest_api(:icsp, :get, '/rest/os-deployment-servers')
140
- # Pick the relevant os deployment server from icsp
141
- my_server = nil
142
- os_deployment_servers['members'].each do |server|
143
- if server['serialNumber'] == serialNumber
144
- my_server = server
145
- break
146
- end
56
+
57
+ # Look for Server Profile as second option
58
+ templates = rest_api(:oneview, :get, "/rest/server-profiles?filter=\"name matches '#{template_name}'\"&sort=name:asc")['members']
59
+ if templates && templates.count == 1
60
+ # Remove unwanted fields
61
+ %w(uri serialNumber uuid taskUri).each {|key| templates.first[key] = nil}
62
+ templates.first['connections'].each do |c|
63
+ %w(wwnn wwpn mac deploymentStatus interconnectUri wwpnType macType).each {|key| c[key] = nil}
147
64
  end
65
+ return templates.first
148
66
  end
149
- my_server
67
+ fail "'#{template_name}' matches multiple profiles! Please use a unique template name." if templates && templates.count > 1
68
+
69
+ fail "Template '#{template_name}' not found! Please match the template name with one that exists on OneView."
150
70
  end
151
71
 
72
+ def available_hardware_for_template(template)
73
+ server_hardware_type_uri = template['serverHardwareTypeUri']
74
+ enclosure_group_uri = template['enclosureGroupUri']
75
+ fail 'Template must specify a valid hardware type uri!' if server_hardware_type_uri.nil? || server_hardware_type_uri.empty?
76
+ fail 'Template must specify a valid hardware type uri!' if enclosure_group_uri.nil? || enclosure_group_uri.empty?
77
+ params = "sort=name:asc&filter=serverHardwareTypeUri='#{server_hardware_type_uri}'&filter=serverGroupUri='#{enclosure_group_uri}'"
78
+ blades = rest_api(:oneview, :get, "/rest/server-hardware?#{params}")
79
+ fail 'Error! No available blades that are compatible with the server template!' unless blades['count'] > 0
80
+ blades['members'].each do |member|
81
+ return member if member['state'] == 'NoProfileApplied'
82
+ end
83
+ fail 'No more blades are available for provisioning!' # Every bay is full and no more machines can be allocated
84
+ end
85
+
86
+ def oneview_wait_for(task_uri, wait_iterations = 60, sleep_seconds = 10) # Default time is 10 min
87
+ fail 'Must specify a task_uri!' if task_uri.nil? || task_uri.empty?
88
+ wait_iterations.times do
89
+ task = rest_api(:oneview, :get, task_uri)
90
+ case task['taskState'].downcase
91
+ when 'completed'
92
+ return true
93
+ when 'error', 'killed', 'terminated'
94
+ return task
95
+ else
96
+ print '.'
97
+ sleep sleep_seconds
98
+ end
99
+ end
100
+ false
101
+ end
152
102
 
153
103
  def power_on(action_handler, machine_spec, hardware_uri = nil)
154
104
  set_power_state(action_handler, machine_spec, 'on', hardware_uri)
@@ -169,6 +119,7 @@ module OneViewAPI
169
119
 
170
120
  if hardware_uri.nil?
171
121
  profile = get_oneview_profile_by_sn(machine_spec.reference['serial_number'])
122
+ fail "Could not power #{state} #{machine_spec.name}: Profile with serial number '#{machine_spec.reference['serial_number']}' not found!" unless profile
172
123
  hardware_uri = profile['serverHardwareUri']
173
124
  end
174
125
 
@@ -190,258 +141,6 @@ module OneViewAPI
190
141
  hardware_uri
191
142
  end
192
143
 
193
- # Chef oneview provisioning
194
- def create_machine(action_handler, machine_spec, machine_options)
195
- host_name = machine_options[:driver_options][:host_name]
196
- server_template = machine_options[:driver_options][:server_template]
197
-
198
- auth_tokens # Login (to both ICSP and OneView)
199
-
200
- # Check if profile exists first
201
- matching_profiles = rest_api(:oneview, :get, "/rest/server-profiles?filter=name matches '#{host_name}'&sort=name:asc")
202
-
203
- if matching_profiles['count'] > 0
204
- profile = matching_profiles['members'].first
205
- power_on(action_handler, machine_spec, profile['serverHardwareUri']) # Make sure server is started
206
- return profile
207
- end
208
-
209
-
210
- # Get HPOVProfile by name (to see if it already exists)
211
- # For 120 verion of Oneview , we are going to retrive a predefined unassociated server profile
212
- templates = rest_api(:oneview, :get, "/rest/server-profiles?filter=name matches '#{server_template}'&sort=name:asc")
213
- unless templates['members'] && templates['members'].count > 0
214
- fail "Template '#{server_template}' not found! Please match the template name with one that exists on OneView."
215
- end
216
-
217
- template_uri = templates['members'].first['uri']
218
- server_hardware_type_uri = templates['members'].first['serverHardwareTypeUri']
219
- enclosure_group_uri = templates['members'].first['enclosureGroupUri']
220
-
221
- # Get availabe (and compatible) HP OV server blades. Take first one.
222
- blades = rest_api(:oneview, :get, "/rest/server-hardware?sort=name:asc&filter=serverHardwareTypeUri='#{server_hardware_type_uri}'&filter=serverGroupUri='#{enclosure_group_uri}'")
223
- fail 'Error! No available blades that are compatible with the server profile!' unless blades['count'] > 0
224
- chosen_blade = nil
225
- blades['members'].each do |member|
226
- if member['state'] != 'ProfileApplied' && member['state'] != 'ApplyingProfile'
227
- chosen_blade = member
228
- break
229
- end
230
- end
231
- if chosen_blade.nil? # TODO
232
- # Every bay is full and no more machines can be allocated
233
- fail 'No more blades are available for provisioning!'
234
- end
235
-
236
- power_off(action_handler, machine_spec, chosen_blade['uri'])
237
- # New-HPOVProfileFromTemplate
238
- # Create new profile instance from template
239
- action_handler.perform_action "Initialize creation of server template for #{machine_spec.name}" do
240
- action_handler.report_progress "INFO: Initializing creation of server template for #{machine_spec.name}"
241
-
242
- new_template_profile = rest_api(:oneview, :get, "#{template_uri}")
243
-
244
- # Take response, add name & hardware uri, and post back to /rest/server-profiles
245
- new_template_profile['name'] = host_name
246
- new_template_profile['uri'] = nil
247
- new_template_profile['serialNumber'] = nil
248
- new_template_profile['uuid'] = nil
249
- new_template_profile['connections'].each do |c|
250
- c['wwnn'] = nil
251
- c['wwpn'] = nil
252
- c['mac'] = nil
253
- end
254
-
255
- new_template_profile['serverHardwareUri'] = chosen_blade['uri']
256
- task = rest_api(:oneview, :post, '/rest/server-profiles', { 'body' => new_template_profile })
257
- task_uri = task['uri']
258
- # Poll task resource to see when profile has finished being applied
259
- 60.times do # Wait for up to 5 min
260
- matching_profiles = rest_api(:oneview, :get, "/rest/server-profiles?filter=name matches '#{host_name}'&sort=name:asc")
261
- break if matching_profiles['count'] > 0
262
- print '.'
263
- sleep 5
264
- end
265
- unless matching_profiles['count'] > 0
266
- task = rest_api(:oneview, :get, task_uri)
267
- fail "Server template coudln't be applied! #{task['taskStatus']}. #{task['taskErrors'].first['message']}"
268
- end
269
- end
270
- matching_profiles['members'].first
271
- end
272
-
273
-
274
- # Use ICSP to install OS
275
- def customize_machine(action_handler, machine_spec, machine_options, profile)
276
- auth_tokens # Login (to both ICSP and OneView)
277
-
278
- # Wait for server profile to finish building
279
- unless profile['state'] == 'Normal'
280
- action_handler.perform_action "Wait for #{machine_spec.name} server to start and profile to be applied" do
281
- action_handler.report_progress "INFO: Waiting for #{machine_spec.name} server to start and profile to be applied"
282
- task_uri = profile['taskUri']
283
- build_server_template_task = rest_api(:oneview, :get, task_uri)
284
- # Poll task resource to see when profile has finished being applied
285
- 240.times do # Wait for up to 40 min
286
- build_server_template_task = rest_api(:oneview, :get, task_uri)
287
- break if build_server_template_task['taskState'].downcase == 'completed'
288
- if build_server_template_task['taskState'].downcase == 'error'
289
- server_template = machine_options[:driver_options][:server_template]
290
- fail "Error creating server profile from template #{server_template}: #{build_server_template_task['taskErrors'].first['message']}"
291
- end
292
- print '.'
293
- sleep 10
294
- end
295
- fail 'Timed out waiting for server to start and profile to be applied' unless build_server_template_task['taskState'].downcase == 'completed'
296
- end
297
- profile = get_oneview_profile_by_sn(machine_spec.reference['serial_number']) # Refresh profile
298
- fail "Server profile state '#{profile['state']}' not 'Normal'" unless profile['state'] == 'Normal'
299
- end
300
-
301
- # Make sure server is started
302
- power_on(action_handler, machine_spec, profile['serverHardwareUri'])
303
-
304
- # Get ICSP servers to poll and wait until server PXE complete (to make sure ICSP is available).
305
- my_server = nil
306
- action_handler.perform_action "Wait for #{machine_spec.name} to boot" do
307
- action_handler.report_progress "INFO: Waiting for #{machine_spec.name} to PXE boot. This may take a while..."
308
- 360.times do # Wait for up to 1 hr
309
- os_deployment_servers = rest_api(:icsp, :get, '/rest/os-deployment-servers')
310
-
311
- # TODO: Maybe check for opswLifecycle = 'UNPROVISIONED' instead of serialNumber existance
312
- os_deployment_servers['members'].each do |server|
313
- if server['serialNumber'] == profile['serialNumber']
314
- my_server = server
315
- break
316
- end
317
- end
318
- break if !my_server.nil?
319
- print '.'
320
- sleep 10
321
- end
322
- fail "Timeout waiting for server #{machine_spec.name} to register with ICSP" if my_server.nil?
323
- end
324
-
325
- # Consume any custom attributes that were specified
326
- if machine_options[:driver_options][:custom_attributes]
327
- curr_server = rest_api(:icsp, :get, my_server['uri'])
328
- machine_options[:driver_options][:custom_attributes].each do |key, val|
329
- curr_server['customAttributes'].push({
330
- 'values' => [{ 'scope' => 'server', 'value' => val.to_s }],
331
- 'key' => key.to_s
332
- })
333
- end
334
- options = { 'body' => curr_server }
335
- rest_api(:icsp, :put, my_server['uri'], options)
336
- end
337
-
338
- # Run OS install on a server
339
- unless my_server['opswLifecycle'] == 'MANAGED' # Skip if already in MANAGED state
340
- os_build = machine_options[:driver_options][:os_build]
341
- action_handler.perform_action "Install OS: #{os_build} on #{machine_spec.name}" do
342
- action_handler.report_progress "INFO: Installing OS: #{os_build} on #{machine_spec.name}"
343
- # Get os-deployment-build-plans
344
- build_plan_uri = nil
345
- os_deployment_build_plans = rest_api(:icsp, :get, '/rest/os-deployment-build-plans')
346
- os_deployment_build_plans['members'].each do |bp|
347
- if bp['name'] == os_build
348
- build_plan_uri = bp['uri']
349
- break
350
- end
351
- end
352
- fail "OS build plan #{os_build} not found!" if build_plan_uri.nil?
353
-
354
- # Do the OS deployment
355
- options = { 'body' => {
356
- 'osbpUris' => [build_plan_uri],
357
- 'serverData' => [{ 'serverUri' => my_server['uri'] }]
358
- } }
359
- os_deployment_task = rest_api(:icsp, :post, '/rest/os-deployment-jobs/?force=true', options)
360
- os_deployment_task_uri = os_deployment_task['uri']
361
- 720.times do # Wait for up to 2 hr
362
- os_deployment_task = rest_api(:icsp, :get, os_deployment_task_uri, options) # TODO: Need options?
363
- break if os_deployment_task['running'] == 'false'
364
- print '.'
365
- sleep 10
366
- end
367
- unless os_deployment_task['state'] == 'STATUS_SUCCESS'
368
- fail "Error running OS build plan #{os_build}: #{os_deployment_task['jobResult'].first['jobMessage']}\n#{os_deployment_task['jobResult'].first['jobResultErrorDetails']}"
369
- end
370
- end
371
- end
372
-
373
- # Perform network personalization
374
- action_handler.perform_action "Perform network personalization on #{machine_spec.name}" do
375
- action_handler.report_progress "INFO: Performing network personalization on #{machine_spec.name}"
376
- nics = []
377
- if machine_options[:driver_options][:connections]
378
- machine_options[:driver_options][:connections].each do |id, data|
379
- c = data
380
- c[:macAddress] = profile['connections'].select {|x| x['id'] == id}.first['mac']
381
- c[:mask] ||= machine_options[:driver_options][:mask]
382
- c[:dhcp] ||= machine_options[:driver_options][:dhcp] || false
383
- c[:gateway] ||= machine_options[:driver_options][:gateway]
384
- c[:dns] ||= machine_options[:driver_options][:dns]
385
- c[:ip4Address] ||= machine_options[:driver_options][:ip_address]
386
- nics.push c
387
- end
388
- end
389
- options = { 'body' => [{
390
- 'serverUri' => my_server['uri'],
391
- 'personalityData' => {
392
- 'hostName' => machine_options[:driver_options][:host_name],
393
- 'domainType' => machine_options[:driver_options][:domainType],
394
- 'domainName' => machine_options[:driver_options][:domainName],
395
- 'nics' => nics
396
- }
397
- }] }
398
- network_personalization_task = rest_api(:icsp, :put, '/rest/os-deployment-apxs/personalizeserver', options)
399
- network_personalization_task_uri = network_personalization_task['uri']
400
- 60.times do # Wait for up to 10 min
401
- network_personalization_task = rest_api(:icsp, :get, network_personalization_task_uri, options)
402
- break if network_personalization_task['running'] == 'false'
403
- print '.'
404
- sleep 10
405
- end
406
- unless network_personalization_task['state'] == 'STATUS_SUCCESS'
407
- fail "Error performing network personalization: #{network_personalization_task['jobResult'].first['jobResultLogDetails']}\n#{network_personalization_task['jobResult'].first['jobResultErrorDetails']}"
408
- end
409
- end
410
- # Get all, search for yours. If not there or if it's in uninitialized state, pull again
411
- my_server_uri = my_server['uri']
412
- 30.times do # Wait for up to 5 min
413
- my_server = rest_api(:icsp, :get, my_server_uri)
414
- break if my_server['opswLifecycle'] == 'MANAGED'
415
- print '.'
416
- sleep 10
417
- end
418
-
419
- fail "Timeout waiting for server #{machine_spec.name} to finish network personalization" if my_server['opswLifecycle'] != 'MANAGED'
420
- my_server
421
- end
422
-
423
-
424
- def destroy_icsp_server(action_handler, machine_spec)
425
- my_server = get_icsp_server_by_sn(machine_spec.reference['serial_number'])
426
- return false if my_server.nil? || my_server['uri'].nil?
427
-
428
- action_handler.perform_action "Delete server #{machine_spec.name} from ICSP" do
429
- task = rest_api(:icsp, :delete, my_server['uri']) # TODO: This returns nil instead of task info
430
-
431
- if task['uri']
432
- task_uri = task['uri']
433
- 90.times do # Wait for up to 15 minutes
434
- task = rest_api(:icsp, :get, task_uri)
435
- break if task['taskState'].downcase == 'completed'
436
- print '.'
437
- sleep 10
438
- end
439
- fail "Deleting os deployment server #{machine_spec.name} at icsp failed!" unless task['taskState'].downcase == 'completed'
440
- end
441
- end
442
- end
443
-
444
-
445
144
  def destroy_oneview_profile(action_handler, machine_spec, profile = nil)
446
145
  profile ||= get_oneview_profile_by_sn(machine_spec.reference['serial_number'])
447
146