chef-provisioning-oneview 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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