chef-provisioning-oneview 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +119 -65
  3. data/chef-provisioning-oneview.gemspec +39 -0
  4. data/lib/chef/provisioning/create_machine.rb +43 -46
  5. data/lib/chef/provisioning/customize_machine.rb +50 -48
  6. data/lib/chef/provisioning/helpers.rb +18 -0
  7. data/lib/chef/provisioning/icsp/api_v104.rb +3 -2
  8. data/lib/chef/provisioning/icsp/icsp_helper.rb +288 -0
  9. data/lib/chef/provisioning/icsp/rest.rb +50 -0
  10. data/lib/chef/provisioning/oneview/oneview_helper.rb +53 -0
  11. data/lib/chef/provisioning/oneview/san_storage.rb +69 -69
  12. data/lib/chef/provisioning/oneview_driver.rb +124 -105
  13. data/lib/chef/provisioning/version.rb +1 -1
  14. metadata +23 -61
  15. data/Rakefile +0 -19
  16. data/lib/chef/provisioning/icsp/icsp_api.rb +0 -284
  17. data/lib/chef/provisioning/oneview/oneview_api.rb +0 -186
  18. data/lib/chef/provisioning/oneview/v1.2/api.rb +0 -3
  19. data/lib/chef/provisioning/oneview/v2.0/api.rb +0 -3
  20. data/lib/chef/provisioning/rest.rb +0 -52
  21. data/spec/shared_context.rb +0 -78
  22. data/spec/spec_helper.rb +0 -23
  23. data/spec/support/fake_action_handler.rb +0 -6
  24. data/spec/support/fake_icsp.rb +0 -73
  25. data/spec/support/fake_machine_spec.rb +0 -18
  26. data/spec/support/fake_oneview.rb +0 -148
  27. data/spec/support/fixtures/icsp/v102/error_404.json +0 -14
  28. data/spec/support/fixtures/icsp/v102/login.json +0 -5
  29. data/spec/support/fixtures/icsp/v102/os-deployment-build-plans.json +0 -99
  30. data/spec/support/fixtures/icsp/v102/os-deployment-servers.json +0 -179
  31. data/spec/support/fixtures/icsp/v102/os-deployment-servers_1670001.json +0 -83
  32. data/spec/support/fixtures/icsp/v102/os-deployment-servers_fakesn.json +0 -9
  33. data/spec/support/fixtures/icsp/v102/server_by_sn_VCGE9KB041.json +0 -45
  34. data/spec/support/fixtures/icsp/v102/server_by_sn_empty.json +0 -16
  35. data/spec/support/fixtures/icsp/v102/version.json +0 -4
  36. data/spec/support/fixtures/oneview/v120/error_404.json +0 -14
  37. data/spec/support/fixtures/oneview/v120/login.json +0 -5
  38. data/spec/support/fixtures/oneview/v120/server-hardware.json +0 -1476
  39. data/spec/support/fixtures/oneview/v120/server-hardware_Template-WebServer.json +0 -468
  40. data/spec/support/fixtures/oneview/v120/server-hardware_specific.json +0 -151
  41. data/spec/support/fixtures/oneview/v120/server-profiles.json +0 -369
  42. data/spec/support/fixtures/oneview/v120/server-profiles_invalid_filter.json +0 -14
  43. data/spec/support/fixtures/oneview/v120/server-profiles_name_Template-WebServer.json +0 -133
  44. data/spec/support/fixtures/oneview/v120/server-profiles_name_Template-WebServerWithSAN.json +0 -200
  45. data/spec/support/fixtures/oneview/v120/server-profiles_name_chef-web01.json +0 -133
  46. data/spec/support/fixtures/oneview/v120/server-profiles_name_chef-web03.json +0 -133
  47. data/spec/support/fixtures/oneview/v120/server-profiles_name_empty.json +0 -15
  48. data/spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB041.json +0 -133
  49. data/spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB042.json +0 -206
  50. data/spec/support/fixtures/oneview/v120/server-profiles_sn_empty.json +0 -15
  51. data/spec/support/fixtures/oneview/v120/storage-volumes_1B5D3CA2-6C5B-41C2-8B97-1821F1883F22.json +0 -26
  52. data/spec/support/fixtures/oneview/v120/tasks_fake_active.json +0 -5
  53. data/spec/support/fixtures/oneview/v120/tasks_fake_complete.json +0 -5
  54. data/spec/support/fixtures/oneview/v120/version.json +0 -4
  55. data/spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplate.json +0 -109
  56. data/spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplateWithSAN.json +0 -144
  57. data/spec/support/fixtures/oneview/v200/server-profile-templates_invalid.json +0 -16
  58. data/spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplate.json +0 -125
  59. data/spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplateWithSAN.json +0 -178
  60. data/spec/support/fixtures/oneview/v200/version.json +0 -4
  61. data/spec/unit/create_machine_spec.rb +0 -78
  62. data/spec/unit/destroy_spec.rb +0 -26
  63. data/spec/unit/icsp_nic_teams_spec.rb +0 -38
  64. data/spec/unit/icsp_search_spec.rb +0 -25
  65. data/spec/unit/oneview_driver_spec.rb +0 -79
  66. data/spec/unit/oneview_login_spec.rb +0 -17
  67. data/spec/unit/oneview_power_spec.rb +0 -51
  68. data/spec/unit/oneview_san_spec.rb +0 -86
  69. data/spec/unit/oneview_search_spec.rb +0 -63
  70. data/spec/unit/rest_api_spec.rb +0 -115
@@ -1,5 +1,5 @@
1
1
  class Chef
2
2
  module Provisioning
3
- ONEVIEW_DRIVER_VERSION = '1.2.1'.freeze
3
+ ONEVIEW_DRIVER_VERSION = '1.3.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-provisioning-oneview
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hewlett Packard Enterprise
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-14 00:00:00.000000000 Z
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '12.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oneview-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: chef-provisioning
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -138,9 +152,8 @@ dependencies:
138
152
  version: '0'
139
153
  description: Chef Provisioning driver for creating and managing OneView infrastructure.
140
154
  email:
141
- - jared.smartt@hp.com
142
- - gunjan.kamle@hp.com
143
- - matthew.frahry@hp.com
155
+ - jared.smartt@hpe.com
156
+ - gunjan.kamle@hpe.com
144
157
  executables: []
145
158
  extensions: []
146
159
  extra_rdoc_files:
@@ -149,69 +162,18 @@ extra_rdoc_files:
149
162
  files:
150
163
  - LICENSE
151
164
  - README.md
152
- - Rakefile
165
+ - chef-provisioning-oneview.gemspec
153
166
  - lib/chef/provisioning/create_machine.rb
154
167
  - lib/chef/provisioning/customize_machine.rb
155
168
  - lib/chef/provisioning/driver_init/oneview.rb
169
+ - lib/chef/provisioning/helpers.rb
156
170
  - lib/chef/provisioning/icsp/api_v104.rb
157
- - lib/chef/provisioning/icsp/icsp_api.rb
158
- - lib/chef/provisioning/oneview/oneview_api.rb
171
+ - lib/chef/provisioning/icsp/icsp_helper.rb
172
+ - lib/chef/provisioning/icsp/rest.rb
173
+ - lib/chef/provisioning/oneview/oneview_helper.rb
159
174
  - lib/chef/provisioning/oneview/san_storage.rb
160
- - lib/chef/provisioning/oneview/v1.2/api.rb
161
- - lib/chef/provisioning/oneview/v2.0/api.rb
162
175
  - lib/chef/provisioning/oneview_driver.rb
163
- - lib/chef/provisioning/rest.rb
164
176
  - lib/chef/provisioning/version.rb
165
- - spec/shared_context.rb
166
- - spec/spec_helper.rb
167
- - spec/support/fake_action_handler.rb
168
- - spec/support/fake_icsp.rb
169
- - spec/support/fake_machine_spec.rb
170
- - spec/support/fake_oneview.rb
171
- - spec/support/fixtures/icsp/v102/error_404.json
172
- - spec/support/fixtures/icsp/v102/login.json
173
- - spec/support/fixtures/icsp/v102/os-deployment-build-plans.json
174
- - spec/support/fixtures/icsp/v102/os-deployment-servers.json
175
- - spec/support/fixtures/icsp/v102/os-deployment-servers_1670001.json
176
- - spec/support/fixtures/icsp/v102/os-deployment-servers_fakesn.json
177
- - spec/support/fixtures/icsp/v102/server_by_sn_VCGE9KB041.json
178
- - spec/support/fixtures/icsp/v102/server_by_sn_empty.json
179
- - spec/support/fixtures/icsp/v102/version.json
180
- - spec/support/fixtures/oneview/v120/error_404.json
181
- - spec/support/fixtures/oneview/v120/login.json
182
- - spec/support/fixtures/oneview/v120/server-hardware.json
183
- - spec/support/fixtures/oneview/v120/server-hardware_Template-WebServer.json
184
- - spec/support/fixtures/oneview/v120/server-hardware_specific.json
185
- - spec/support/fixtures/oneview/v120/server-profiles.json
186
- - spec/support/fixtures/oneview/v120/server-profiles_invalid_filter.json
187
- - spec/support/fixtures/oneview/v120/server-profiles_name_Template-WebServer.json
188
- - spec/support/fixtures/oneview/v120/server-profiles_name_Template-WebServerWithSAN.json
189
- - spec/support/fixtures/oneview/v120/server-profiles_name_chef-web01.json
190
- - spec/support/fixtures/oneview/v120/server-profiles_name_chef-web03.json
191
- - spec/support/fixtures/oneview/v120/server-profiles_name_empty.json
192
- - spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB041.json
193
- - spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB042.json
194
- - spec/support/fixtures/oneview/v120/server-profiles_sn_empty.json
195
- - spec/support/fixtures/oneview/v120/storage-volumes_1B5D3CA2-6C5B-41C2-8B97-1821F1883F22.json
196
- - spec/support/fixtures/oneview/v120/tasks_fake_active.json
197
- - spec/support/fixtures/oneview/v120/tasks_fake_complete.json
198
- - spec/support/fixtures/oneview/v120/version.json
199
- - spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplate.json
200
- - spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplateWithSAN.json
201
- - spec/support/fixtures/oneview/v200/server-profile-templates_invalid.json
202
- - spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplate.json
203
- - spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplateWithSAN.json
204
- - spec/support/fixtures/oneview/v200/version.json
205
- - spec/unit/create_machine_spec.rb
206
- - spec/unit/destroy_spec.rb
207
- - spec/unit/icsp_nic_teams_spec.rb
208
- - spec/unit/icsp_search_spec.rb
209
- - spec/unit/oneview_driver_spec.rb
210
- - spec/unit/oneview_login_spec.rb
211
- - spec/unit/oneview_power_spec.rb
212
- - spec/unit/oneview_san_spec.rb
213
- - spec/unit/oneview_search_spec.rb
214
- - spec/unit/rest_api_spec.rb
215
177
  homepage: https://github.com/HewlettPackard/chef-provisioning-oneview
216
178
  licenses:
217
179
  - Apache-2.0
data/Rakefile DELETED
@@ -1,19 +0,0 @@
1
- require 'bundler'
2
- require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
4
- require 'rubocop/rake_task'
5
-
6
- task default: :spec
7
-
8
- desc 'Run specs'
9
- RSpec::Core::RakeTask.new(:spec) do |spec|
10
- spec.pattern = 'spec/**/*_spec.rb'
11
- end
12
-
13
- RuboCop::RakeTask.new
14
-
15
- desc 'Runs rubocop and rspec'
16
- task :test do
17
- Rake::Task[:rubocop].invoke
18
- Rake::Task[:spec].invoke
19
- end
@@ -1,284 +0,0 @@
1
- Dir[File.dirname(__FILE__) + '/**/*.rb'].each {|file| require file } # Include all helper files in this directory & subdirectories
2
-
3
- module ICspAPI
4
- private
5
-
6
- include ICspAPIv104
7
-
8
- def get_icsp_api_version
9
- begin
10
- version = rest_api(:icsp, :get, '/rest/version', { 'Content-Type' => :none, 'X-API-Version' => :none, 'auth' => :none })['currentVersion']
11
- raise "Couldn't get API version" unless version
12
- if version.class != Fixnum
13
- version = version.to_i
14
- raise 'API version type mismatch' if !version > 0
15
- end
16
- rescue
17
- puts 'Failed to get ICSP API version. Setting to default (102)'
18
- version = 102
19
- end
20
- version
21
- end
22
-
23
- def login_to_icsp
24
- path = '/rest/login-sessions'
25
- options = {
26
- 'body' => {
27
- 'userName' => @icsp_username,
28
- 'password' => @icsp_password,
29
- 'authLoginDomain' => 'LOCAL'
30
- }
31
- }
32
- response = rest_api(:icsp, :post, path, options)
33
- return response['sessionID'] if response['sessionID']
34
- raise("\nERROR! Couldn't log into ICSP server at #{@icsp_base_url}. Response:\n#{response}")
35
- end
36
-
37
- def get_icsp_server_by_sn(serial_number)
38
- raise 'Must specify a serialNumber!' if serial_number.nil? || serial_number.empty?
39
- search_result = rest_api(:icsp, :get,
40
- "/rest/index/resources?category=osdserver&query='osdServerSerialNumber:\"#{serial_number}\"'")['members'] rescue nil
41
- if search_result && search_result.size == 1 && search_result.first['attributes']['osdServerSerialNumber'] == serial_number
42
- my_server_uri = search_result.first['uri']
43
- my_server = rest_api(:icsp, :get, my_server_uri)
44
- end
45
- unless my_server && my_server['uri']
46
- os_deployment_servers = rest_api(:icsp, :get, '/rest/os-deployment-servers')
47
- # Pick the relevant os deployment server from icsp
48
- my_server = nil
49
- os_deployment_servers['members'].each do |server|
50
- if server['serialNumber'] == serial_number
51
- my_server = server
52
- break
53
- end
54
- end
55
- end
56
- my_server
57
- end
58
-
59
- def icsp_wait_for(task_uri, wait_iterations = 60, sleep_seconds = 10)
60
- raise 'Must specify a task_uri!' if task_uri.nil? || task_uri.empty?
61
- wait_iterations.times do
62
- task = rest_api(:icsp, :get, task_uri)
63
- if task['taskState']
64
- case task['taskState'].downcase
65
- when 'completed'
66
- return true
67
- when 'error', 'killed', 'terminated'
68
- return task
69
- end
70
- elsif task['running'] == 'false' && task['jobResult']
71
- if task['state'] == 'STATUS_SUCCESS'
72
- return true
73
- else
74
- return task
75
- end
76
- end
77
- print '.'
78
- sleep sleep_seconds
79
- end
80
- false
81
- end
82
-
83
- # Consume and set any custom attributes that were specified
84
- def icsp_set_custom_attributes(machine_options, my_server)
85
- if machine_options[:driver_options][:custom_attributes]
86
- curr_server = rest_api(:icsp, :get, my_server['uri'])
87
- machine_options[:driver_options][:custom_attributes].each do |key, val|
88
- curr_server['customAttributes'].push({
89
- 'values' => [{ 'scope' => 'server', 'value' => val.to_s }],
90
- 'key' => key.to_s
91
- })
92
- end
93
- options = { 'body' => curr_server }
94
- rest_api(:icsp, :put, my_server['uri'], options)
95
- end
96
- end
97
-
98
- def icsp_run_os_install(action_handler, machine_spec, machine_options, my_server, profile)
99
- return if my_server['state'] == 'OK' # Skip if the OS has already been deployed
100
-
101
- # Wait for my_server['state'] to be in MAINTENANCE mode
102
- if my_server['state'] != 'MAINTENANCE'
103
- action_handler.perform_action "Wait for #{machine_spec.name} to go into maintenance mode in ICsp" do
104
- action_handler.report_progress "INFO: Waiting for #{machine_spec.name} to go into maintenance mode in ICsp"
105
- 120.times do # Wait for up to 20 min
106
- my_server = get_icsp_server_by_sn(profile['serialNumber'])
107
- break if my_server['state'] != 'MAINTENANCE'
108
- print '.'
109
- sleep 10
110
- end
111
- raise "Timed out waiting for #{machine_spec.name} to go into maintenance mode in ICsp. State: #{my_server['state']}" unless my_server['state'] == 'MAINTENANCE'
112
- end
113
- end
114
-
115
- # Get the specified OS Build Plan(s)
116
- os_builds = machine_options[:driver_options][:os_build]
117
- os_builds = [os_builds] if os_builds.class == String
118
- build_plan_uris = []
119
- action_handler.perform_action "Get OS Build Plan(s) info for #{machine_spec.name}" do
120
- action_handler.report_progress "INFO: Getting OS Build Plan(s) for #{machine_spec.name}"
121
- os_builds.each do |os_build|
122
- uri = "/rest/index/resources?userQuery=\"'#{os_build}'\"&category=osdbuildplan"
123
- while uri
124
- matching_plans = rest_api(:icsp, :get, uri)
125
- raise "Search failed for OSBP '#{os_build}'. Response: #{matching_plans}" unless matching_plans['members']
126
- build_plan_uri = matching_plans['members'].find {|bp| bp['name'] == os_build}['uri'] rescue nil
127
- break unless build_plan_uri.nil?
128
- uri = URI.unescape(matching_plans['nextPageUri']) rescue nil
129
- end
130
- raise "OS build plan #{os_build} not found!" if build_plan_uri.nil?
131
- build_plan_uris.push build_plan_uri
132
- end
133
- end
134
-
135
- # Build options for the OS deployment
136
- options = {}
137
- options['X-API-Version'] = 104 if @current_icsp_api_version.between?(104, 108)
138
- options['body'] = {
139
- 'osbpUris' => build_plan_uris,
140
- 'serverData' => [{
141
- 'serverUri' => my_server['uri']
142
- }]
143
- }
144
-
145
- # Do the OS deployment
146
- action_handler.perform_action "Run: #{os_builds} OS Build Plan(s) on #{machine_spec.name}" do
147
- action_handler.report_progress "INFO: Running: #{os_builds} OS Build Plan(s) on #{machine_spec.name}"
148
- task = rest_api(:icsp, :post, '/rest/os-deployment-jobs/?force=true', options)
149
- task_uri = task['uri']
150
- raise "Failed to start OS Deployment Job. Details: #{task['details'] || task['message'] || task}" unless task_uri
151
- task = icsp_wait_for(task_uri, 720)
152
- raise "Error running OS build plan(s) #{os_builds}: #{task['jobResult'].first['jobMessage']}\n#{task['jobResult'].first['jobResultErrorDetails']}" unless task == true
153
- end
154
- end
155
-
156
- def icsp_configure_networking(action_handler, machine_spec, machine_options, my_server, profile)
157
- return if machine_options[:driver_options][:skip_network_configuration] == true
158
- action_handler.perform_action "Configure networking on #{machine_spec.name}" do
159
- action_handler.report_progress "INFO: Configuring networking on #{machine_spec.name}"
160
- personality_data = icsp_build_personality_data(machine_options, profile)
161
- options = {}
162
- options['X-API-Version'] = 104 if @current_icsp_api_version.between?(104, 108)
163
- options['body'] = {
164
- 'serverData' => [{
165
- 'serverUri' => my_server['uri'],
166
- 'personalityData' => personality_data
167
- }]
168
- }
169
-
170
- task = rest_api(:icsp, :post, '/rest/os-deployment-jobs/?force=true', options)
171
- task_uri = task['uri']
172
- raise "Failed to start network personalization job. Details: #{task['details']}" unless task_uri
173
- task = icsp_wait_for(task_uri, 60) # Wait for up to 10 min
174
- raise "Error running network personalization job: #{task['jobResult'].first['jobMessage']}\n#{task['jobResult'].first['jobResultErrorDetails']}" unless task == true
175
-
176
- # Check if ICsp IP config matches machine options
177
- requested_ips = []
178
- machine_options[:driver_options][:connections].each do |_id, c|
179
- requested_ips.push c[:ip4Address] if c[:ip4Address] && c[:dhcp] == false
180
- end
181
- my_server_connections = []
182
- 10.times do
183
- my_server_connections = rest_api(:icsp, :get, my_server['uri'])['interfaces']
184
- my_server_connections.each { |c| requested_ips.delete c['ipv4Addr'] }
185
- break if requested_ips.empty?
186
- print ','
187
- sleep 10
188
- end
189
- puts "\nWARN: The following IPs are not visible on ICsp, so they may not have gotten configured correctly: #{requested_ips}" unless requested_ips.empty?
190
-
191
- # Set interface data as normal node attributes
192
- my_server_connections.each do |c|
193
- c['oneViewId'] = profile['connections'].find {|x| x['mac'] == c['macAddr']}['id'] rescue nil
194
- end
195
- machine_spec.data['normal']['icsp'] ||= {}
196
- machine_spec.data['normal']['icsp']['interfaces'] = my_server_connections
197
- end
198
- end
199
-
200
- # Build options for the network configuration
201
- def icsp_build_personality_data(machine_options, profile)
202
- nics = []
203
- if machine_options[:driver_options][:connections]
204
- machine_options[:driver_options][:connections].each do |id, data|
205
- c = Marshal.load(Marshal.dump(data))
206
- next unless c[:dhcp] || c[:dhcpv4] || c[:ip4Address] || c[:ipv6autoconfig] || c[:staticNetworks] # Invalid network or only switch networks specified
207
- c.delete_if { |k, _v| k.to_s == 'bootstrap' }
208
- begin
209
- c[:macAddress] = profile['connections'].find {|x| x['id'] == id}['mac']
210
- rescue NoMethodError
211
- ids = []
212
- profile['connections'].each {|x| ids.push x['id']}
213
- raise "Could not find connection id #{id} for #{profile['name']}. Available connection ids are: #{ids}. Please make sure the connection ids map to those on OneView."
214
- end
215
- if @current_icsp_api_version.between?(104, 108)
216
- icsp_v104_parse_connection(machine_options, c)
217
- else
218
- c[:mask] ||= machine_options[:driver_options][:mask]
219
- c[:dhcp] ||= false
220
- c[:gateway] ||= machine_options[:driver_options][:gateway]
221
- c[:dns] ||= machine_options[:driver_options][:dns]
222
- end
223
- nics.push c
224
- end
225
- end
226
-
227
- if @current_icsp_api_version.between?(104, 108)
228
- personality_data = icsp_v104_build_personality_data(machine_options, nics)
229
- else
230
- personality_data = {
231
- 'hostName' => machine_options[:driver_options][:host_name],
232
- 'domainType' => machine_options[:driver_options][:domainType],
233
- 'domainName' => machine_options[:driver_options][:domainName],
234
- 'nics' => nics
235
- }
236
- end
237
- personality_data
238
- end
239
-
240
- def destroy_icsp_server(action_handler, machine_spec)
241
- my_server = get_icsp_server_by_sn(machine_spec.reference['serial_number'])
242
- return false if my_server.nil? || my_server['uri'].nil?
243
-
244
- action_handler.perform_action "Delete server #{machine_spec.name} from ICSP" do
245
- task = rest_api(:icsp, :delete, my_server['uri']) # TODO: This returns nil instead of task info
246
- if task['uri']
247
- task_uri = task['uri']
248
- 90.times do # Wait for up to 15 minutes
249
- task = rest_api(:icsp, :get, task_uri)
250
- break if task['taskState'].casecmp('completed') == 0
251
- print '.'
252
- sleep 10
253
- end
254
- raise "Deleting os deployment server #{machine_spec.name} at icsp failed!" unless task['taskState'].casecmp('completed') == 0
255
- end
256
- end
257
- end
258
-
259
- def icsp_configure_nic_teams(machine_options, profile)
260
- return false if machine_options[:driver_options][:connections].nil?
261
- teams = {}
262
-
263
- machine_options[:driver_options][:connections].each do |id, options|
264
- next unless options.is_a?(Hash) && options[:team]
265
- raise "#{options[:team]}: Team names must not include hyphens" if options[:team].to_s.include?('-')
266
- teams[options[:team].to_s] ||= []
267
- begin
268
- mac = profile['connections'].find {|x| x['id'] == id}['mac']
269
- teams[options[:team].to_s].push mac
270
- rescue NoMethodError
271
- ids = []
272
- profile['connections'].each {|x| ids.push x['id']}
273
- raise "Failed to configure nic teams: Could not find connection id #{id} for #{profile['name']}. Available connection ids are: #{ids}. Please make sure the connection ids map to those on OneView."
274
- end
275
- end
276
- team_strings = []
277
- teams.each do |name, macs|
278
- raise "Team '#{name}' must have at least 2 associated connections to form a NIC team" unless macs.size >= 2
279
- team_strings.push "#{name}-#{macs.join(',')}"
280
- end
281
- machine_options[:driver_options][:custom_attributes] ||= {}
282
- machine_options[:driver_options][:custom_attributes][:teams] = team_strings.join('|')
283
- end
284
- end # End module
@@ -1,186 +0,0 @@
1
- Dir[File.dirname(__FILE__) + '/**/*.rb'].each {|file| require file } # Include all helper files in this directory & subdirectories
2
-
3
- module OneViewAPI
4
- private
5
-
6
- include OneViewAPIv1_2
7
- include OneViewAPIv2_0
8
- include OneViewSanStorage
9
-
10
- def get_oneview_api_version
11
- begin
12
- version = rest_api(:oneview, :get, '/rest/version', { 'Content-Type' => :none, 'X-API-Version' => :none, 'auth' => :none })['currentVersion']
13
- raise "Couldn't get API version" unless version
14
- if version.class != Fixnum
15
- version = version.to_i
16
- raise 'API version type mismatch' if !version > 0
17
- end
18
- rescue
19
- Chef::Log.warn 'Failed to get OneView API version. Setting to default (120)'
20
- version = 120
21
- end
22
- version
23
- end
24
-
25
- def login_to_oneview
26
- path = '/rest/login-sessions'
27
- options = {
28
- 'body' => {
29
- 'userName' => @oneview_username,
30
- 'password' => @oneview_password,
31
- 'authLoginDomain' => 'LOCAL'
32
- }
33
- }
34
- response = rest_api(:oneview, :post, path, options)
35
- return response['sessionID'] if response['sessionID']
36
- raise("\nERROR! Couldn't log into OneView server at #{@oneview_base_url}. Response:\n#{response}")
37
- end
38
-
39
- def get_oneview_profile_by_sn(serial_number)
40
- raise 'Must specify a serialNumber!' if serial_number.nil? || serial_number.empty?
41
- matching_profiles = rest_api(:oneview, :get, "/rest/server-profiles?filter=serialNumber matches '#{serial_number}'&sort=name:asc")
42
- raise "Failed to get oneview profile by serialNumber: #{serial_number}. Response: #{matching_profiles}" unless matching_profiles['count']
43
- return matching_profiles['members'].first if matching_profiles['count'] > 0
44
- nil
45
- end
46
-
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
- raise "'#{template_name}' matches multiple templates! Please use a unique template name." if templates && templates.count > 1
55
- 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}
64
- end
65
- return templates.first
66
- end
67
- raise "'#{template_name}' matches multiple profiles! Please use a unique template name." if templates && templates.count > 1
68
-
69
- raise "Template '#{template_name}' not found! Please match the template name with one that exists on OneView."
70
- end
71
-
72
- def available_hardware_for_template(template, location = nil)
73
- server_hardware_type_uri = template['serverHardwareTypeUri']
74
- enclosure_group_uri = template['enclosureGroupUri']
75
- raise 'Template must specify a valid hardware type uri!' if server_hardware_type_uri.nil? || server_hardware_type_uri.empty?
76
- raise '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
- raise 'Error! No available blades that are compatible with the server template!' unless blades['count'] > 0
80
- Chef::Log.debug "Specific hardware requested: #{location}" if location
81
- blades['members'].each do |member|
82
- next unless member['state'] == 'NoProfileApplied'
83
- next if location && member['name'] != location
84
- return member
85
- end
86
- raise 'No more blades are available for provisioning!' # Every bay is full and no more machines can be allocated
87
- end
88
-
89
- def oneview_wait_for(task_uri, wait_iterations = 60, sleep_seconds = 10) # Default time is 10 min
90
- raise 'Must specify a task_uri!' if task_uri.nil? || task_uri.empty?
91
- wait_iterations.times do
92
- task = rest_api(:oneview, :get, task_uri)
93
- case task['taskState'].downcase
94
- when 'completed'
95
- return true
96
- when 'error', 'killed', 'terminated'
97
- return task
98
- else
99
- print '.'
100
- sleep sleep_seconds
101
- end
102
- end
103
- false
104
- end
105
-
106
- def wait_for_profile(action_handler, machine_spec, machine_options, profile)
107
- unless profile['state'] == 'Normal'
108
- action_handler.perform_action "Wait for #{machine_spec.name} server to start and profile to be applied" do
109
- action_handler.report_progress "INFO: Waiting for #{machine_spec.name} server to start and profile to be applied"
110
- task = oneview_wait_for(profile['taskUri'], 360) # Wait up to 60 min for profile to be created
111
- raise 'Timed out waiting for server to start and profile to be applied' if task == false
112
- unless task == true
113
- server_template = machine_options[:driver_options][:server_template]
114
- raise "Error creating server profile from template #{server_template}: #{task['taskErrors'].first['message']}"
115
- end
116
- end
117
- profile = get_oneview_profile_by_sn(machine_spec.reference['serial_number']) # Refresh profile
118
- raise "Server profile state '#{profile['state']}' not 'Normal'" unless profile['state'] == 'Normal'
119
- end
120
- end
121
-
122
-
123
- def power_on(action_handler, machine_spec, hardware_uri = nil)
124
- set_power_state(action_handler, machine_spec, 'on', hardware_uri)
125
- end
126
-
127
- def power_off(action_handler, machine_spec, hardware_uri = nil)
128
- set_power_state(action_handler, machine_spec, 'off', hardware_uri)
129
- end
130
-
131
- def set_power_state(action_handler, machine_spec, state, hardware_uri = nil)
132
- case state
133
- when :on, 'on', true
134
- state = 'on'
135
- when :off, 'off', false
136
- state = 'off'
137
- else raise "Invalid power state #{state}"
138
- end
139
-
140
- if hardware_uri.nil?
141
- profile = get_oneview_profile_by_sn(machine_spec.reference['serial_number'])
142
- raise "Could not power #{state} #{machine_spec.name}: Profile with serial number '#{machine_spec.reference['serial_number']}' not found!" unless profile
143
- hardware_uri = profile['serverHardwareUri']
144
- end
145
-
146
- hardware_info = rest_api(:oneview, :get, hardware_uri)
147
- unless hardware_info['powerState'].casecmp(state) == 0
148
- action_handler.perform_action "Power #{state} server #{hardware_info['name']} for #{machine_spec.name}" do
149
- action_handler.report_progress "INFO: Powering #{state} server #{hardware_info['name']} for #{machine_spec.name}"
150
- task = rest_api(:oneview, :put, "#{hardware_uri}/powerState", { 'body' => { 'powerState' => state.capitalize, 'powerControl' => 'MomentaryPress' } })
151
- task_uri = task['uri']
152
- 60.times do # Wait for up to 10 minutes
153
- task = rest_api(:oneview, :get, task_uri)
154
- break if task['taskState'].casecmp('completed') == 0
155
- print '.'
156
- sleep 10
157
- end
158
- raise "Powering #{state} machine #{machine_spec.name} failed!" unless task['taskState'].casecmp('completed') == 0
159
- end
160
- end
161
- hardware_uri
162
- end
163
-
164
- def destroy_oneview_profile(action_handler, machine_spec, profile = nil)
165
- profile ||= get_oneview_profile_by_sn(machine_spec.reference['serial_number'])
166
-
167
- hardware_info = rest_api(:oneview, :get, profile['serverHardwareUri'])
168
- if hardware_info.nil?
169
- action_handler.report_progress "INFO: #{machine_spec.name} is already deleted."
170
- else
171
- action_handler.perform_action "Delete server #{machine_spec.name} from oneview" do
172
- action_handler.report_progress "INFO: Deleting server profile #{machine_spec.name}"
173
- task = rest_api(:oneview, :Delete, profile['uri'])
174
- task_uri = task['uri']
175
-
176
- 60.times do # Wait for up to 10 minutes
177
- task = rest_api(:oneview, :get, task_uri)
178
- break if task['taskState'].casecmp('completed') == 0
179
- print '.'
180
- sleep 10
181
- end
182
- raise "Deleting server profile #{machine_spec.name} failed!" unless task['taskState'].casecmp('completed') == 0
183
- end
184
- end
185
- end
186
- end