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.
- 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
|