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.
- checksums.yaml +4 -4
- data/README.md +43 -3
- data/lib/chef/provisioning/create_machine.rb +52 -0
- data/lib/chef/provisioning/customize_machine.rb +78 -0
- data/lib/chef/provisioning/icsp/api_v104.rb +27 -0
- data/lib/chef/provisioning/icsp/icsp_api.rb +282 -0
- data/lib/chef/provisioning/oneview/oneview_api.rb +56 -357
- data/lib/chef/provisioning/oneview/san_storage.rb +91 -0
- data/lib/chef/provisioning/oneview/v1.2/api.rb +3 -0
- data/lib/chef/provisioning/oneview_driver.rb +42 -5
- data/lib/chef/provisioning/rest.rb +51 -0
- data/lib/chef/provisioning/{oneview/version.rb → version.rb} +1 -1
- data/spec/shared_context.rb +77 -0
- data/spec/spec_helper.rb +8 -6
- data/spec/{unit/support → support}/fake_action_handler.rb +0 -0
- data/spec/support/fake_icsp.rb +73 -21
- data/spec/support/fake_machine_spec.rb +18 -0
- data/spec/support/fake_oneview.rb +148 -21
- data/spec/support/fixtures/icsp/v102/error_404.json +13 -13
- data/spec/support/fixtures/icsp/v102/login.json +4 -4
- data/spec/support/fixtures/icsp/v102/os-deployment-build-plans.json +99 -99
- data/spec/support/fixtures/icsp/v102/{os-deployment-servers_managed.json → os-deployment-servers.json} +178 -178
- data/spec/support/fixtures/icsp/v102/os-deployment-servers_1670001.json +83 -0
- data/spec/support/fixtures/icsp/v102/os-deployment-servers_fakesn.json +9 -0
- data/spec/support/fixtures/icsp/v102/{server_by_sn.json → server_by_sn_VCGE9KB041.json} +44 -44
- data/spec/support/fixtures/icsp/v102/server_by_sn_empty.json +16 -0
- data/spec/support/fixtures/icsp/v102/version.json +3 -3
- data/spec/support/fixtures/oneview/v120/error_404.json +13 -13
- data/spec/support/fixtures/oneview/v120/login.json +4 -4
- data/spec/support/fixtures/oneview/v120/server-hardware.json +1475 -1475
- data/spec/support/fixtures/oneview/v120/server-hardware_Template-WebServer.json +468 -0
- data/spec/support/fixtures/oneview/v120/server-hardware_specific.json +151 -0
- data/spec/support/fixtures/oneview/v120/server-profiles.json +368 -746
- data/spec/support/fixtures/oneview/v120/server-profiles_invalid_filter.json +14 -0
- data/spec/support/fixtures/oneview/v120/{server-profiles_specific.json → server-profiles_name_Template-WebServer.json} +132 -132
- data/spec/support/fixtures/oneview/v120/server-profiles_name_Template-WebServerWithSAN.json +200 -0
- data/spec/support/fixtures/oneview/v120/server-profiles_name_chef-web01.json +133 -0
- data/spec/support/fixtures/oneview/v120/server-profiles_name_chef-web03.json +133 -0
- data/spec/support/fixtures/oneview/v120/server-profiles_name_empty.json +15 -0
- data/spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB041.json +133 -0
- data/spec/support/fixtures/oneview/v120/server-profiles_sn_VCGE9KB042.json +206 -0
- data/spec/support/fixtures/oneview/v120/server-profiles_sn_empty.json +15 -0
- data/spec/support/fixtures/oneview/v120/storage-volumes_1B5D3CA2-6C5B-41C2-8B97-1821F1883F22.json +26 -0
- data/spec/support/fixtures/oneview/v120/tasks_fake_active.json +5 -0
- data/spec/support/fixtures/oneview/v120/tasks_fake_complete.json +5 -0
- data/spec/support/fixtures/oneview/v120/version.json +3 -3
- data/spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplate.json +109 -0
- data/spec/support/fixtures/oneview/v200/server-profile-templates_WebServerTemplateWithSAN.json +144 -0
- data/spec/support/fixtures/oneview/v200/server-profile-templates_invalid.json +16 -0
- data/spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplate.json +125 -0
- data/spec/support/fixtures/oneview/v200/server-profile-templates_new-profile_WebServerTemplateWithSAN.json +178 -0
- data/spec/support/fixtures/oneview/v200/version.json +4 -0
- data/spec/unit/create_machine_spec.rb +78 -0
- data/spec/unit/destroy_spec.rb +26 -0
- data/spec/unit/icsp_nic_teams_spec.rb +38 -0
- data/spec/unit/icsp_search_spec.rb +25 -0
- data/spec/unit/oneview_driver_spec.rb +37 -64
- data/spec/unit/oneview_login_spec.rb +23 -0
- data/spec/unit/oneview_power_spec.rb +51 -0
- data/spec/unit/oneview_san_spec.rb +86 -0
- data/spec/unit/oneview_search_spec.rb +63 -0
- data/spec/unit/rest_api_spec.rb +115 -0
- metadata +90 -9
- data/lib/chef/provisioning/oneview/v1.20/api.rb +0 -3
@@ -0,0 +1,91 @@
|
|
1
|
+
# Methods for configuring SAN storage on OneView
|
2
|
+
module OneViewSanStorage
|
3
|
+
def fill_volume_details(v)
|
4
|
+
details = rest_api(:oneview, :get, v['volumeUri'])
|
5
|
+
v['volumeName'] = details['name']
|
6
|
+
v['permanent'] = details['isPermanent']
|
7
|
+
v['volumeShareable'] = details['shareable']
|
8
|
+
v['volumeProvisionType'] = details['provisionType']
|
9
|
+
v['volumeProvisionedCapacityBytes'] = details['provisionedCapacity']
|
10
|
+
v['volumeDescription'] = details['description']
|
11
|
+
v
|
12
|
+
end
|
13
|
+
|
14
|
+
# Prepare profile for SAN storage
|
15
|
+
def update_san_info(machine_spec, profile)
|
16
|
+
san_storage = profile['sanStorage']
|
17
|
+
return profile unless san_storage && !san_storage['volumeAttachments'].empty?
|
18
|
+
|
19
|
+
# Sanitize old SAN entries and fill in details
|
20
|
+
boot_vols = []
|
21
|
+
san_storage['volumeAttachments'].each do |v|
|
22
|
+
fill_volume_details(v) unless profile['serverProfileTemplateUri']
|
23
|
+
fail "#{machine_spec.name}: Should know if volume is sharable:\n#{v}" unless v.key?('volumeShareable')
|
24
|
+
|
25
|
+
# Match boot disks by name
|
26
|
+
boot_vols.push(v['volumeName']) if v['volumeName'].downcase.match(/^boot/)
|
27
|
+
v['volumeName'] += " #{profile['name']}" unless v['volumeShareable'] # Append profile name to volume name
|
28
|
+
|
29
|
+
unless profile['serverProfileTemplateUri'] # Only needed when coppied from profile
|
30
|
+
v['state'] = nil
|
31
|
+
v['status'] = nil
|
32
|
+
v['storagePaths'].each { |s| s['status'] = nil }
|
33
|
+
|
34
|
+
unless v['volumeShareable']
|
35
|
+
# It is private in the profile, so we will clone it
|
36
|
+
v['volumeUri'] = nil
|
37
|
+
|
38
|
+
# Assumes all cloned volumes are non-permanet. Might want some global config to control this
|
39
|
+
v['permanent'] = false
|
40
|
+
v['lun'] = nil if v['lunType'].downcase == 'auto'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
fail "#{machine_spec.name}: There should only be 1 SAN boot volume. Boot volumes: #{boot_vols}" if boot_vols.size > 1
|
45
|
+
profile
|
46
|
+
end
|
47
|
+
|
48
|
+
# Make sure connections for SAN boot volumes are configured to boot from the correct SAN volume
|
49
|
+
def enable_boot_from_san(action_handler, machine_spec, profile)
|
50
|
+
return false if profile['connections'].nil? || profile['connections'].empty?
|
51
|
+
|
52
|
+
# If there is a san volume we might need to update boot connections
|
53
|
+
update_needed = false
|
54
|
+
profile['sanStorage']['volumeAttachments'].each do |v|
|
55
|
+
vol_details = rest_api(:oneview, :get, v['volumeUri'])
|
56
|
+
next unless vol_details['name'].downcase.match(/^boot/)
|
57
|
+
# Find the enabled path(s), get target wwpn, and then update connection, setting boot targets
|
58
|
+
v['storagePaths'].each do |s|
|
59
|
+
next if !s['isEnabled'] || s['storageTargets'].nil? || s['storageTargets'].empty?
|
60
|
+
connection = profile['connections'].find { |c| c['id'] == s['connectionId'] }
|
61
|
+
fail "#{machine_spec.name}: Connection #{s['connectionId']} not found! Check SAN settings" unless connection
|
62
|
+
if connection['boot'].nil? || connection['boot']['priority'] == 'NotBootable'
|
63
|
+
msg = "#{machine_spec.name}: Connection #{s['connectionId']} is labeled for boot, but the connection is not marked as bootable."
|
64
|
+
fail "#{msg} Set the connection boot target to Primary or Secondary"
|
65
|
+
end
|
66
|
+
target = {}
|
67
|
+
target['arrayWwpn'] = s['storageTargets'].first.delete(':')
|
68
|
+
target['lun'] = v['lun']
|
69
|
+
unless connection['boot']['targets'] && connection['boot']['targets'].first &&
|
70
|
+
connection['boot']['targets'].first['arrayWwpn'] == target['arrayWwpn'] &&
|
71
|
+
connection['boot']['targets'].first['lun'] == target['lun']
|
72
|
+
connection['boot']['targets'] = [target]
|
73
|
+
update_needed = true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
if update_needed
|
79
|
+
action_handler.perform_action "Enable SAN-bootable connections for #{machine_spec.name}" do
|
80
|
+
action_handler.report_progress "INFO: Enabling SAN-bootable connections for #{machine_spec.name}"
|
81
|
+
power_off(action_handler, machine_spec, profile['serverHardwareUri'])
|
82
|
+
task = rest_api(:oneview, :put, profile['uri'], { 'body' => profile })
|
83
|
+
task = oneview_wait_for(task['uri'], 90) # Wait for up to 15 min for profile to be updated
|
84
|
+
fail "Timed out waiting for enabling SAN-bootable connections on #{machine_spec.name}" if task == false
|
85
|
+
fail "Error enabling SAN-bootable connections on #{machine_spec.name}. Response: #{task}" unless task == true
|
86
|
+
end
|
87
|
+
profile = rest_api(:oneview, :get, profile['uri'])
|
88
|
+
end
|
89
|
+
profile # Return profile
|
90
|
+
end
|
91
|
+
end
|
@@ -7,12 +7,20 @@ require 'chef/provisioning/machine/unix_machine'
|
|
7
7
|
require 'json'
|
8
8
|
require 'ridley'
|
9
9
|
require_relative 'driver_init/oneview'
|
10
|
-
require_relative '
|
10
|
+
require_relative 'version'
|
11
|
+
require_relative 'rest'
|
12
|
+
require_relative 'create_machine'
|
13
|
+
require_relative 'customize_machine'
|
11
14
|
require_relative 'oneview/oneview_api'
|
15
|
+
require_relative 'icsp/icsp_api'
|
12
16
|
|
13
17
|
module Chef::Provisioning
|
14
18
|
class OneViewDriver < Chef::Provisioning::Driver
|
19
|
+
include CreateMachine
|
20
|
+
include CustomizeMachine
|
21
|
+
include RestAPI
|
15
22
|
include OneViewAPI
|
23
|
+
include ICspAPI
|
16
24
|
|
17
25
|
def self.canonicalize_url(url, config)
|
18
26
|
_scheme, oneview_url = url.split(':', 2)
|
@@ -37,7 +45,8 @@ module Chef::Provisioning
|
|
37
45
|
@oneview_password = config[:knife][:oneview_password]
|
38
46
|
fail 'Must set the knife[:oneview_password] attribute!' if @oneview_password.nil? || @oneview_password.empty?
|
39
47
|
@oneview_disable_ssl = config[:knife][:oneview_ignore_ssl]
|
40
|
-
@oneview_api_version = 120 #
|
48
|
+
@oneview_api_version = 120 # Use this version for all calls that don't override it
|
49
|
+
@current_oneview_api_version = get_oneview_api_version
|
41
50
|
@oneview_key = login_to_oneview
|
42
51
|
|
43
52
|
@icsp_base_url = config[:knife][:icsp_url]
|
@@ -47,7 +56,8 @@ module Chef::Provisioning
|
|
47
56
|
@icsp_password = config[:knife][:icsp_password]
|
48
57
|
fail 'Must set the knife[:icsp_password] attribute!' if @icsp_password.nil? || @icsp_password.empty?
|
49
58
|
@icsp_disable_ssl = config[:knife][:icsp_ignore_ssl]
|
50
|
-
@icsp_api_version = 102 #
|
59
|
+
@icsp_api_version = 102 # Use this version for all calls that don't override it
|
60
|
+
@current_icsp_api_version = get_icsp_api_version
|
51
61
|
@icsp_key = login_to_icsp
|
52
62
|
end
|
53
63
|
|
@@ -58,6 +68,9 @@ module Chef::Provisioning
|
|
58
68
|
if get_oneview_profile_by_sn(machine_spec.reference['serial_number']).nil? # It doesn't really exist
|
59
69
|
action_handler.report_progress "Machine #{host_name} does not really exist. Recreating ..."
|
60
70
|
machine_spec.reference = nil
|
71
|
+
else # Update reference data
|
72
|
+
machine_spec.reference['driver_url'] = driver_url
|
73
|
+
machine_spec.reference['driver_version'] = ONEVIEW_DRIVER_VERSION
|
61
74
|
end
|
62
75
|
end
|
63
76
|
if !machine_spec.reference
|
@@ -82,6 +95,7 @@ module Chef::Provisioning
|
|
82
95
|
|
83
96
|
def ready_machine(action_handler, machine_spec, machine_options)
|
84
97
|
profile = get_oneview_profile_by_sn(machine_spec.reference['serial_number'])
|
98
|
+
fail "Failed to retrieve Server Profile for #{machine_spec.name}. Serial Number used to search: #{machine_spec.reference['serial_number']}" unless profile
|
85
99
|
customize_machine(action_handler, machine_spec, machine_options, profile)
|
86
100
|
machine_for(machine_spec, machine_options) # Return the Machine object
|
87
101
|
end
|
@@ -89,10 +103,24 @@ module Chef::Provisioning
|
|
89
103
|
|
90
104
|
def machine_for(machine_spec, machine_options)
|
91
105
|
bootstrap_ip_address = machine_options[:driver_options][:ip_address]
|
106
|
+
unless bootstrap_ip_address
|
107
|
+
id, connection = machine_options[:driver_options][:connections].find { |_id, c| c[:bootstrap] == true }
|
108
|
+
fail 'Must specify a connection to use to bootstrap!' unless id && connection
|
109
|
+
bootstrap_ip_address = connection[:ip4Address] # For static IPs
|
110
|
+
unless bootstrap_ip_address # Look for dhcp address given to this connection
|
111
|
+
profile = get_oneview_profile_by_sn(machine_spec.reference['serial_number'])
|
112
|
+
my_server = get_icsp_server_by_sn(machine_spec.reference['serial_number'])
|
113
|
+
mac = profile['connections'].find {|x| x['id'] == id}['mac']
|
114
|
+
interface = my_server['interfaces'].find { |i| i['macAddr'] == mac }
|
115
|
+
bootstrap_ip_address = interface['ipv4Addr'] || interface['ipv6Addr']
|
116
|
+
end
|
117
|
+
bootstrap_ip_address ||= my_server['hostName'] # Fall back on hostName
|
118
|
+
end
|
119
|
+
fail 'Server IP address not specified and could not be retrieved!' unless bootstrap_ip_address
|
92
120
|
username = machine_options[:transport_options][:user] || 'root' rescue 'root'
|
93
121
|
default_ssh_options = {
|
94
|
-
# auth_methods: ['publickey'],
|
95
|
-
# keys: ['/
|
122
|
+
# auth_methods: ['password', 'publickey'],
|
123
|
+
# keys: ['~/.ssh/id_rsa'],
|
96
124
|
password: Chef::Config.knife[:node_root_password]
|
97
125
|
}
|
98
126
|
ssh_options = machine_options[:transport_options][:ssh_options] || default_ssh_options rescue default_ssh_options
|
@@ -169,5 +197,14 @@ module Chef::Provisioning
|
|
169
197
|
machine_for(machine_spec, machine_options)
|
170
198
|
end
|
171
199
|
|
200
|
+
private
|
201
|
+
|
202
|
+
# Login to both OneView and ICsp
|
203
|
+
def auth_tokens
|
204
|
+
@icsp_key ||= login_to_icsp
|
205
|
+
@oneview_key ||= login_to_oneview
|
206
|
+
{ 'icsp_key' => @icsp_key, 'oneview_key' => @oneview_key }
|
207
|
+
end
|
208
|
+
|
172
209
|
end # class end
|
173
210
|
end # module end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RestAPI
|
2
|
+
# API calls for OneView and ICsp
|
3
|
+
def rest_api(host, type, path, options = {})
|
4
|
+
disable_ssl = false
|
5
|
+
case host
|
6
|
+
when 'icsp', :icsp
|
7
|
+
uri = URI.parse(URI.escape(@icsp_base_url + path))
|
8
|
+
options['X-API-Version'] ||= @icsp_api_version unless [:put, 'put'].include?(type.downcase)
|
9
|
+
options['auth'] ||= @icsp_key
|
10
|
+
disable_ssl = true if @icsp_disable_ssl
|
11
|
+
when 'oneview', :oneview
|
12
|
+
uri = URI.parse(URI.escape(@oneview_base_url + path))
|
13
|
+
options['X-API-Version'] ||= @oneview_api_version
|
14
|
+
options['auth'] ||= @oneview_key
|
15
|
+
disable_ssl = true if @oneview_disable_ssl
|
16
|
+
else
|
17
|
+
fail "Invalid rest host: #{host}"
|
18
|
+
end
|
19
|
+
|
20
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
21
|
+
http.use_ssl = true if uri.scheme == 'https'
|
22
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if disable_ssl
|
23
|
+
|
24
|
+
case type.downcase
|
25
|
+
when 'get', :get
|
26
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
27
|
+
when 'post', :post
|
28
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
29
|
+
when 'put', :put
|
30
|
+
request = Net::HTTP::Put.new(uri.request_uri)
|
31
|
+
when 'delete', :delete
|
32
|
+
request = Net::HTTP::Delete.new(uri.request_uri)
|
33
|
+
else
|
34
|
+
fail "Invalid rest call: #{type}"
|
35
|
+
end
|
36
|
+
options['Content-Type'] ||= 'application/json'
|
37
|
+
options.delete('Content-Type') if [:none, 'none', nil].include?(options['Content-Type'])
|
38
|
+
options.delete('X-API-Version') if [:none, 'none', nil].include?(options['X-API-Version'])
|
39
|
+
options.delete('auth') if [:none, 'none', nil].include?(options['auth'])
|
40
|
+
options.each do |key, val|
|
41
|
+
if key.downcase == 'body'
|
42
|
+
request.body = val.to_json rescue val
|
43
|
+
else
|
44
|
+
request[key] = val
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
response = http.request(request)
|
49
|
+
JSON.parse(response.body) rescue response
|
50
|
+
end
|
51
|
+
end # End module
|
@@ -0,0 +1,77 @@
|
|
1
|
+
RSpec.shared_context 'shared context', a: :b do
|
2
|
+
|
3
|
+
domain = 'my-domain.com'
|
4
|
+
chef_server = "https://my-chef-server.#{domain}/organizations/oneview"
|
5
|
+
oneview = "https://my-oneview.#{domain}"
|
6
|
+
icsp = "https://my-icsp.#{domain}"
|
7
|
+
|
8
|
+
let(:knife_config) do
|
9
|
+
{ knife: {
|
10
|
+
oneview_url: oneview,
|
11
|
+
oneview_username: 'Administrator',
|
12
|
+
oneview_password: 'password12',
|
13
|
+
oneview_ignore_ssl: true,
|
14
|
+
|
15
|
+
icsp_url: icsp,
|
16
|
+
icsp_username: 'administrator',
|
17
|
+
icsp_password: 'password123'
|
18
|
+
} }
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:valid_machine_options) do
|
22
|
+
{
|
23
|
+
convergence_options: {
|
24
|
+
ssl_verify_mode: :verify_none,
|
25
|
+
bootstrap_proxy: "http://proxy.#{domain}:8080",
|
26
|
+
chef_server: {
|
27
|
+
chef_server_url: chef_server,
|
28
|
+
options: {
|
29
|
+
client_name: 'user',
|
30
|
+
signing_key_filename: 'spec/fixtures/.chef/user.pem'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
},
|
34
|
+
driver_options: {
|
35
|
+
server_template: 'Template - Web Server',
|
36
|
+
os_build: 'CHEF-RHEL-6.5-x64',
|
37
|
+
host_name: 'chef-web01',
|
38
|
+
ip_address: '192.168.1.2',
|
39
|
+
domainType: 'workgroup',
|
40
|
+
domainName: domain,
|
41
|
+
gateway: '192.168.1.1',
|
42
|
+
dns: '192.168.1.1,10.1.1.1',
|
43
|
+
connections: {
|
44
|
+
1 => { dhcp: true, team: 'team1' },
|
45
|
+
2 => { ip4Address: '192.168.1.2', mask: '255.255.254.0', dhcp: false, team: 'team1' }
|
46
|
+
}
|
47
|
+
},
|
48
|
+
custom_attributes: {
|
49
|
+
|
50
|
+
},
|
51
|
+
transport_options: {
|
52
|
+
ssh_options: { password: 'password1234' }
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:action_handler) do
|
58
|
+
ChefProvisioningOneviewHelpers::FakeActionHandler.new
|
59
|
+
end
|
60
|
+
|
61
|
+
let(:machine_spec) do
|
62
|
+
ChefProvisioningOneviewHelpers::FakeMachineSpec.new('server-1', 'VCGE9KB041')
|
63
|
+
end
|
64
|
+
|
65
|
+
let(:machine_spec2) do
|
66
|
+
ChefProvisioningOneviewHelpers::FakeMachineSpec.new('server-2', '789123')
|
67
|
+
end
|
68
|
+
|
69
|
+
before :each do
|
70
|
+
@oneview_key = 'A954A2A6Psy7Alg3HApAcEbAcAwa-ftA'
|
71
|
+
@icsp_key = 'AA_aaAaa3AA3Aa0_aAaAA4AAAA3AAAAA'
|
72
|
+
@url = oneview
|
73
|
+
@canonical_url = "oneview:#{@url}"
|
74
|
+
@instance = Chef::Provisioning::OneViewDriver.new(@canonical_url, knife_config)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
require 'pry'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start
|
5
|
+
|
2
6
|
require_relative './../lib/chef/provisioning/driver_init/oneview'
|
3
7
|
require_relative 'support/fake_oneview'
|
4
8
|
require_relative 'support/fake_icsp'
|
5
|
-
|
9
|
+
require_relative 'support/fake_machine_spec'
|
10
|
+
require_relative 'support/fake_action_handler'
|
11
|
+
require_relative 'shared_context'
|
6
12
|
# WebMock.disable_net_connect!(allow_localhost: true)
|
7
13
|
|
8
14
|
RSpec.configure do |config|
|
9
15
|
config.before(:each) do
|
10
|
-
allow_any_instance_of(Chef::Provisioning::OneViewDriver).to receive(:get_oneview_api_version).and_return(120)
|
11
|
-
allow_any_instance_of(Chef::Provisioning::OneViewDriver).to receive(:get_icsp_api_version).and_return(102)
|
12
|
-
allow_any_instance_of(Chef::Provisioning::OneViewDriver).to receive(:login_to_oneview).and_return('long_oneview_key')
|
13
|
-
allow_any_instance_of(Chef::Provisioning::OneViewDriver).to receive(:login_to_icsp).and_return('long_icsp_key')
|
14
|
-
|
15
16
|
stub_request(:any, /my-oneview.my-domain.com/).to_rack(FakeOneView)
|
16
17
|
stub_request(:any, /my-icsp.my-domain.com/).to_rack(FakeIcsp)
|
17
18
|
end
|
19
|
+
|
18
20
|
end
|
19
21
|
|
20
22
|
# Chef::Log.level = :debug
|
File without changes
|
data/spec/support/fake_icsp.rb
CHANGED
@@ -1,21 +1,73 @@
|
|
1
|
-
require 'sinatra/base'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class FakeIcsp < Sinatra::Base
|
5
|
+
|
6
|
+
get '/rest/version' do
|
7
|
+
json_response(200, 'version.json', '102')
|
8
|
+
end
|
9
|
+
|
10
|
+
get '/rest/index/resources' do
|
11
|
+
version = env['HTTP_X_API_VERSION']
|
12
|
+
category = params['category']
|
13
|
+
return json_response(404, 'error_404.json', version) if category.nil?
|
14
|
+
if category == 'osdserver' && params['query'].match(/osdServerSerialNumber:"VCGE9KB041"/)
|
15
|
+
return json_response(200, 'server_by_sn_VCGE9KB041.json', version)
|
16
|
+
elsif category == 'osdserver' && params['query'].match(/osdServerSerialNumber:"FAKESN"/)
|
17
|
+
return json_response(200, 'server_by_sn_empty.json', version)
|
18
|
+
else
|
19
|
+
return json_response(404, 'error_404.json', version)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
get '/rest/os-deployment-servers' do
|
24
|
+
version = env['HTTP_X_API_VERSION']
|
25
|
+
json_response(200, 'os-deployment-servers.json', version)
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/rest/os-deployment-servers/:id' do
|
29
|
+
version = env['HTTP_X_API_VERSION']
|
30
|
+
if params[:id] == '1670001'
|
31
|
+
return json_response(200, 'os-deployment-servers_1670001.json', version)
|
32
|
+
else
|
33
|
+
return json_response(200, 'os-deployment-servers_fakesn.json', version)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
post '/rest/login-sessions' do
|
38
|
+
version = env['HTTP_X_API_VERSION']
|
39
|
+
json_response(200, 'login.json', version)
|
40
|
+
end
|
41
|
+
|
42
|
+
get '/' do
|
43
|
+
{ message: 'Fake ICsp works!', method: env['REQUEST_METHOD'], content_type: env['CONTENT_TYPE'], query: env['QUERY_STRING'],
|
44
|
+
api_version: env['HTTP_X_API_VERSION'], auth: env['HTTP_AUTH'], params: params }.to_json
|
45
|
+
end
|
46
|
+
|
47
|
+
post '/' do
|
48
|
+
{ message: 'Fake ICsp works!', method: env['REQUEST_METHOD'], content_type: env['CONTENT_TYPE'], query: env['QUERY_STRING'],
|
49
|
+
api_version: env['HTTP_X_API_VERSION'], auth: env['HTTP_AUTH'], params: params }.to_json
|
50
|
+
end
|
51
|
+
|
52
|
+
put '/' do
|
53
|
+
{ message: 'Fake ICsp works!', method: env['REQUEST_METHOD'], content_type: env['CONTENT_TYPE'], query: env['QUERY_STRING'],
|
54
|
+
api_version: env['HTTP_X_API_VERSION'], auth: env['HTTP_AUTH'], params: params }.to_json
|
55
|
+
end
|
56
|
+
|
57
|
+
delete '/' do
|
58
|
+
{ message: 'Fake ICsp works!', method: env['REQUEST_METHOD'], content_type: env['CONTENT_TYPE'], query: env['QUERY_STRING'],
|
59
|
+
api_version: env['HTTP_X_API_VERSION'], auth: env['HTTP_AUTH'], params: params }.to_json
|
60
|
+
end
|
61
|
+
|
62
|
+
get '/*' do # All other paths should return a 404 error
|
63
|
+
json_response(404, 'error_404.json', '102')
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def json_response(response_code, file_name, version = 102)
|
69
|
+
content_type :json
|
70
|
+
status response_code
|
71
|
+
File.open(File.dirname(__FILE__) + "/fixtures/icsp/v#{version}/" + file_name, 'rb').read
|
72
|
+
end
|
73
|
+
end
|