vagrant-openstack-provider 0.5.2 → 0.6.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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/lib/vagrant-openstack-provider.rb +2 -31
  4. data/lib/vagrant-openstack-provider/action.rb +21 -7
  5. data/lib/vagrant-openstack-provider/action/abstract_action.rb +22 -0
  6. data/lib/vagrant-openstack-provider/action/connect_openstack.rb +19 -40
  7. data/lib/vagrant-openstack-provider/action/create_server.rb +10 -6
  8. data/lib/vagrant-openstack-provider/action/create_stack.rb +67 -0
  9. data/lib/vagrant-openstack-provider/action/delete_server.rb +28 -3
  10. data/lib/vagrant-openstack-provider/action/delete_stack.rb +72 -0
  11. data/lib/vagrant-openstack-provider/action/message.rb +4 -2
  12. data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +4 -2
  13. data/lib/vagrant-openstack-provider/action/read_state.rb +9 -4
  14. data/lib/vagrant-openstack-provider/action/resume.rb +4 -2
  15. data/lib/vagrant-openstack-provider/action/start_server.rb +4 -2
  16. data/lib/vagrant-openstack-provider/action/stop_server.rb +4 -2
  17. data/lib/vagrant-openstack-provider/action/suspend.rb +4 -2
  18. data/lib/vagrant-openstack-provider/action/sync_folders.rb +17 -13
  19. data/lib/vagrant-openstack-provider/action/wait_accessible.rb +5 -2
  20. data/lib/vagrant-openstack-provider/action/wait_active.rb +5 -3
  21. data/lib/vagrant-openstack-provider/action/wait_stop.rb +5 -3
  22. data/lib/vagrant-openstack-provider/catalog/openstack_catalog.rb +66 -0
  23. data/lib/vagrant-openstack-provider/client/domain.rb +41 -1
  24. data/lib/vagrant-openstack-provider/client/glance.rb +63 -0
  25. data/lib/vagrant-openstack-provider/client/heat.rb +50 -0
  26. data/lib/vagrant-openstack-provider/client/http_utils.rb +18 -0
  27. data/lib/vagrant-openstack-provider/client/neutron.rb +9 -15
  28. data/lib/vagrant-openstack-provider/client/nova.rb +3 -3
  29. data/lib/vagrant-openstack-provider/client/openstack.rb +10 -0
  30. data/lib/vagrant-openstack-provider/command/abstract_command.rb +7 -0
  31. data/lib/vagrant-openstack-provider/command/image_list.rb +12 -2
  32. data/lib/vagrant-openstack-provider/command/main.rb +1 -0
  33. data/lib/vagrant-openstack-provider/command/network_list.rb +3 -3
  34. data/lib/vagrant-openstack-provider/command/subnet_list.rb +25 -0
  35. data/lib/vagrant-openstack-provider/config.rb +78 -7
  36. data/lib/vagrant-openstack-provider/config_resolver.rb +36 -5
  37. data/lib/vagrant-openstack-provider/errors.rb +30 -2
  38. data/lib/vagrant-openstack-provider/logging.rb +39 -0
  39. data/lib/vagrant-openstack-provider/version.rb +1 -1
  40. data/locales/en.yml +107 -4
  41. data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +255 -8
  42. data/spec/vagrant-openstack-provider/action/create_server_spec.rb +6 -1
  43. data/spec/vagrant-openstack-provider/action/create_stack_spec.rb +97 -0
  44. data/spec/vagrant-openstack-provider/action/delete_server_spec.rb +34 -6
  45. data/spec/vagrant-openstack-provider/action/delete_stack_spec.rb +64 -0
  46. data/spec/vagrant-openstack-provider/action/read_state_spec.rb +13 -1
  47. data/spec/vagrant-openstack-provider/action/sync_folders_spec.rb +1 -0
  48. data/spec/vagrant-openstack-provider/action/wait_active_spec.rb +1 -1
  49. data/spec/vagrant-openstack-provider/action/wait_stop_spec.rb +1 -1
  50. data/spec/vagrant-openstack-provider/client/glance_spec.rb +128 -0
  51. data/spec/vagrant-openstack-provider/client/heat_spec.rb +124 -0
  52. data/spec/vagrant-openstack-provider/client/neutron_spec.rb +33 -1
  53. data/spec/vagrant-openstack-provider/client/nova_spec.rb +2 -2
  54. data/spec/vagrant-openstack-provider/command/image_list_spec.rb +75 -23
  55. data/spec/vagrant-openstack-provider/command/subnet_list_spec.rb +46 -0
  56. data/spec/vagrant-openstack-provider/config_resolver_spec.rb +85 -19
  57. data/spec/vagrant-openstack-provider/config_spec.rb +177 -1
  58. data/spec/vagrant-openstack-provider/spec_helper.rb +3 -0
  59. metadata +20 -2
@@ -200,7 +200,12 @@ describe VagrantPlugins::Openstack::Action::CreateServer do
200
200
  it 'timeout before the server become active' do
201
201
  nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'BUILD' })
202
202
  nova.should_receive(:get_server_details).with(env, 'server-01').at_least(2).times
203
- expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Timeout::Error
203
+ expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Errors::Timeout
204
+ end
205
+ it 'raise an error after one retry' do
206
+ nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'ERROR' })
207
+ nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
208
+ expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Errors::ServerStatusError
204
209
  end
205
210
  end
206
211
  end
@@ -0,0 +1,97 @@
1
+ require 'vagrant-openstack-provider/spec_helper'
2
+ require 'ostruct'
3
+ require 'sshkey'
4
+
5
+ include VagrantPlugins::Openstack::Action
6
+ include VagrantPlugins::Openstack::HttpUtils
7
+ include VagrantPlugins::Openstack::Domain
8
+
9
+ describe VagrantPlugins::Openstack::Action::CreateStack do
10
+
11
+ let(:config) do
12
+ double('config').tap do |config|
13
+ config.stub(:stacks) do
14
+ [
15
+ {
16
+ name: 'stack1',
17
+ template: 'template.yml'
18
+ },
19
+ {
20
+ name: 'stack2',
21
+ template: 'template.yml'
22
+ }
23
+ ]
24
+ end
25
+ end
26
+ end
27
+
28
+ let(:heat) do
29
+ double('heat')
30
+ end
31
+
32
+ let(:env) do
33
+ Hash.new.tap do |env|
34
+ env[:ui] = double('ui')
35
+ env[:ui].stub(:info).with(anything)
36
+ env[:machine] = double('machine')
37
+ env[:machine] = OpenStruct.new.tap do |m|
38
+ m.provider_config = config
39
+ m.id = nil
40
+ end
41
+ env[:openstack_client] = double('openstack_client')
42
+ env[:openstack_client].stub(:heat) { heat }
43
+ end
44
+ end
45
+ before :each do
46
+ CreateStack.send(:public, *CreateStack.private_instance_methods)
47
+ app = double('app')
48
+ app.stub(:call).with(anything)
49
+ @action = CreateStack.new(app, nil)
50
+ YAML.stub(:load_file).with('template.yml').and_return(YAML.load('
51
+ heat_template_version: 2013-05-23
52
+
53
+ description: Simple template to deploy a single compute instance
54
+
55
+ resources:
56
+ my_instance:
57
+ type: OS::Nova::Server
58
+ properties:
59
+ key_name: julien-mac
60
+ image: CoreOS
61
+ flavor: 1_vCPU_RAM_512M_HD_10G
62
+ '))
63
+
64
+ end
65
+
66
+ describe 'call' do
67
+ it 'should create stacks on heat twice' do
68
+ heat.stub(:create_stack).and_return('idstack')
69
+ File.should_receive(:write).with('/stack_stack1_id', 'idstack')
70
+ File.should_receive(:write).with('/stack_stack2_id', 'idstack')
71
+ # TODO(julienvey) assert content of create call is correct
72
+ heat.should_receive(:create_stack).exactly(2).times
73
+ heat.stub(:get_stack_details).and_return('stack_status' => 'CREATE_COMPLETE')
74
+ @action.call(env)
75
+ end
76
+ end
77
+
78
+ describe 'waiting_for_server_to_be_built' do
79
+ context 'when server is not yet active' do
80
+ it 'become active after one retry' do
81
+ heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_COMPLETE' })
82
+ heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').exactly(2).times
83
+ @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 5)
84
+ end
85
+ it 'timeout before the server become active' do
86
+ heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_IN_PROGRESS' })
87
+ heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').at_least(2).times
88
+ expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 3) }.to raise_error Errors::Timeout
89
+ end
90
+ it 'raise an error after one retry' do
91
+ heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_FAILED' })
92
+ heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').exactly(2).times
93
+ expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 3) }.to raise_error Errors::StackStatusError
94
+ end
95
+ end
96
+ end
97
+ end
@@ -27,10 +27,11 @@ describe VagrantPlugins::Openstack::Action::DeleteServer do
27
27
  end
28
28
  end
29
29
 
30
- let(:app) do
31
- double('app').tap do |app|
32
- app.stub(:call).with(anything)
33
- end
30
+ before :each do
31
+ DeleteServer.send(:public, *DeleteServer.private_instance_methods)
32
+ app = double('app')
33
+ app.stub(:call).with(anything)
34
+ @action = DeleteServer.new(app, nil)
34
35
  end
35
36
 
36
37
  describe 'call' do
@@ -38,17 +39,44 @@ describe VagrantPlugins::Openstack::Action::DeleteServer do
38
39
  it 'delete server' do
39
40
  expect(nova).to receive(:delete_server).with(env, 'server_id')
40
41
  expect(nova).to receive(:delete_keypair_if_vagrant).with(env, 'server_id')
41
- @action = DeleteServer.new(app, nil)
42
+ expect(@action).to receive(:waiting_for_instance_to_be_deleted).with(env, 'server_id')
42
43
  @action.call(env)
43
44
  end
44
45
  end
45
46
  context 'when id is not present' do
46
47
  it 'delete server' do
48
+ env[:machine].id = nil
47
49
  expect(nova).should_not_receive(:delete_server)
48
50
  expect(nova).should_not_receive(:delete_keypair_if_vagrant)
49
- @action = DeleteServer.new(app, nil)
50
51
  @action.call(env)
51
52
  end
52
53
  end
53
54
  end
55
+
56
+ describe 'waiting_for_instance_to_be_deleted' do
57
+ context 'when server is not yet active' do
58
+ it 'become deleted after one retry' do
59
+ nova.stub(:get_server_details).once.and_return('status' => 'ACTIVE')
60
+ nova.stub(:get_server_details).once.and_raise(Errors::InstanceNotFound)
61
+ nova.should_receive(:get_server_details).with(env, 'server-01').exactly(1).times
62
+ @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 5)
63
+ end
64
+ it 'become deleted after one retry' do
65
+ nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'DELETED' })
66
+ nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
67
+ @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 5)
68
+ end
69
+ it 'timeout before the server become active' do
70
+ nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ACTIVE' })
71
+ nova.should_receive(:get_server_details).with(env, 'server-01').at_least(2).times
72
+ expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 3) }.to raise_error Errors::Timeout
73
+ end
74
+ it 'raise an error after one retry' do
75
+ nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ERROR' })
76
+ nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
77
+ expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 3) }.to raise_error Errors::ServerStatusError
78
+ end
79
+ end
80
+ end
81
+
54
82
  end
@@ -0,0 +1,64 @@
1
+ require 'vagrant-openstack-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::Action::DeleteStack do
4
+
5
+ let(:heat) do
6
+ double('heat').tap do |app|
7
+ app.stub(:delete_stack)
8
+ end
9
+ end
10
+
11
+ let(:openstack_client) do
12
+ double('openstack_client').tap do |os|
13
+ os.stub(:heat) { heat }
14
+ end
15
+ end
16
+
17
+ let(:env) do
18
+ Hash.new.tap do |env|
19
+ env[:ui] = double('ui')
20
+ env[:ui].stub(:info).with(anything)
21
+ env[:ui].stub(:error).with(anything)
22
+ env[:openstack_client] = openstack_client
23
+ env[:machine] = OpenStruct.new.tap do |m|
24
+ m.id = 'server_id'
25
+ m.data_dir = '/test'
26
+ end
27
+ end
28
+ end
29
+
30
+ before :each do
31
+ DeleteStack.send(:public, *DeleteStack.private_instance_methods)
32
+ app = double('app')
33
+ app.stub(:call).with(anything)
34
+ @action = DeleteStack.new(app, nil)
35
+ end
36
+
37
+ describe 'call' do
38
+ context 'when id is present' do
39
+ it 'delete stack' do
40
+ expect(heat).to receive(:delete_stack).with(env, 'test1', '1234')
41
+ expect(heat).to receive(:delete_stack).with(env, 'test2', '2345')
42
+ @action.stub(:list_stack_files).with(env).and_return([
43
+ {
44
+ name: 'test1',
45
+ id: '1234'
46
+ }, {
47
+ name: 'test2',
48
+ id: '2345'
49
+ }])
50
+ expect(@action).to receive(:waiting_for_stack_to_be_deleted).with(env, 'test1', '1234')
51
+ expect(@action).to receive(:waiting_for_stack_to_be_deleted).with(env, 'test2', '2345')
52
+ @action.call(env)
53
+ end
54
+ end
55
+ context 'when id is not present' do
56
+ it 'delete stack' do
57
+ @action.stub(:list_stack_files).with(env).and_return([])
58
+ expect(heat).should_not_receive(:delete_stack)
59
+ expect(heat).should_not_receive(:waiting_for_stack_to_be_deleted)
60
+ @action.call(env)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -27,7 +27,7 @@ describe VagrantPlugins::Openstack::Action::ReadState do
27
27
 
28
28
  describe 'call' do
29
29
  context 'when server id is present' do
30
- it 'set the state to the one returned by nova' do
30
+ it 'set the state to the vm_state returned by nova' do
31
31
  env[:machine].id = 'server_id'
32
32
  nova.stub(:get_server_details).and_return('status' => 'ACTIVE')
33
33
 
@@ -39,6 +39,18 @@ describe VagrantPlugins::Openstack::Action::ReadState do
39
39
 
40
40
  expect(env[:machine_state_id]).to eq(:active)
41
41
  end
42
+ it 'set the state to the task_state returned by nova extension' do
43
+ env[:machine].id = 'server_id'
44
+ nova.stub(:get_server_details).and_return('OS-EXT-STS:task_state' => 'SUSPENDING')
45
+
46
+ expect(nova).to receive(:get_server_details).with(env, 'server_id')
47
+ expect(app).to receive(:call)
48
+
49
+ @action = ReadState.new(app, nil)
50
+ @action.call(env)
51
+
52
+ expect(env[:machine_state_id]).to eq(:suspending)
53
+ end
42
54
  end
43
55
  context 'when server id is not present' do
44
56
  it 'set the state to :not_created' do
@@ -23,6 +23,7 @@ describe VagrantPlugins::Openstack::Action::SyncFolders do
23
23
  double('provider_config').tap do |c|
24
24
  c.stub(:rsync_includes) { nil }
25
25
  c.stub(:ssh_disabled) { false }
26
+ c.stub(:rsync_ignore_files) { ['.gitignore'] }
26
27
  end
27
28
  end
28
29
 
@@ -40,7 +40,7 @@ describe VagrantPlugins::Openstack::Action::WaitForServerToBeActive do
40
40
  nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'BUILD' })
41
41
  expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
42
42
  @action = WaitForServerToBeActive.new(app, nil, 1, 2)
43
- expect { @action.call(env) }.to raise_error Timeout::Error
43
+ expect { @action.call(env) }.to raise_error Errors::Timeout
44
44
  end
45
45
  end
46
46
  end
@@ -40,7 +40,7 @@ describe VagrantPlugins::Openstack::Action::WaitForServerToStop do
40
40
  nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ACTIVE' })
41
41
  expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
42
42
  @action = WaitForServerToStop.new(app, nil, 1, 2)
43
- expect { @action.call(env) }.to raise_error Timeout::Error
43
+ expect { @action.call(env) }.to raise_error Errors::Timeout
44
44
  end
45
45
  end
46
46
  end
@@ -0,0 +1,128 @@
1
+ require 'vagrant-openstack-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::GlanceClient do
4
+
5
+ let(:env) do
6
+ Hash.new
7
+ end
8
+
9
+ let(:session) do
10
+ VagrantPlugins::Openstack.session
11
+ end
12
+
13
+ before :each do
14
+ session.token = '123456'
15
+ session.project_id = 'a1b2c3'
16
+ session.endpoints = { image: 'http://glance' }
17
+ @glance_client = VagrantPlugins::Openstack.glance
18
+ end
19
+
20
+ describe 'get_all_images' do
21
+ context 'with token and project_id acquainted' do
22
+ context 'and api version is v2' do
23
+ it 'returns all images with details' do
24
+ stub_request(:get, 'http://glance/images')
25
+ .with(
26
+ headers:
27
+ {
28
+ 'Accept' => 'application/json',
29
+ 'X-Auth-Token' => '123456'
30
+ })
31
+ .to_return(
32
+ status: 200,
33
+ body: '
34
+ {
35
+ "images": [
36
+ { "id": "i1", "name": "image1", "visibility": "public", "size": "1024", "min_ram": "1", "min_disk": "10" },
37
+ { "id": "i2", "name": "image2", "visibility": "private", "size": "2048", "min_ram": "2", "min_disk": "20" }
38
+ ]
39
+ }')
40
+
41
+ images = @glance_client.get_all_images(env)
42
+
43
+ expect(images).to eq [Image.new('i1', 'image1', 'public', '1024', '1', '10'),
44
+ Image.new('i2', 'image2', 'private', '2048', '2', '20')]
45
+ end
46
+ end
47
+
48
+ context 'and api version is v1' do
49
+ it 'returns all images with details' do
50
+ stub_request(:get, 'http://glance/images')
51
+ .with(
52
+ headers:
53
+ {
54
+ 'Accept' => 'application/json',
55
+ 'X-Auth-Token' => '123456'
56
+ })
57
+ .to_return(
58
+ status: 200,
59
+ body: '
60
+ {
61
+ "images": [
62
+ { "id": "i1", "name": "image1", "is_public": true },
63
+ { "id": "i2", "name": "image2", "is_public": false }
64
+ ]
65
+ }')
66
+
67
+ stub_request(:get, 'http://glance/images/detail')
68
+ .with(
69
+ headers:
70
+ {
71
+ 'Accept' => 'application/json',
72
+ 'X-Auth-Token' => '123456'
73
+ })
74
+ .to_return(
75
+ status: 200,
76
+ body: '
77
+ {
78
+ "images": [
79
+ { "id": "i1", "name": "image1", "is_public": true, "size": "1024", "min_ram": "1", "min_disk": "10" },
80
+ { "id": "i2", "name": "image2", "is_public": false, "size": "2048", "min_ram": "2", "min_disk": "20" }
81
+ ]
82
+ }')
83
+
84
+ images = @glance_client.get_all_images(env)
85
+
86
+ expect(images).to eq [Image.new('i1', 'image1', 'public', '1024', '1', '10'),
87
+ Image.new('i2', 'image2', 'private', '2048', '2', '20')]
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ describe 'get_api_version_list' do
94
+ it 'returns version list' do
95
+ stub_request(:get, 'http://glance/')
96
+ .with(header: { 'Accept' => 'application/json' })
97
+ .to_return(
98
+ status: 200,
99
+ body: '{
100
+ "versions": [
101
+ {
102
+ "status": "...",
103
+ "id": "v1.0",
104
+ "links": [
105
+ {
106
+ "href": "http://glance/v1.0",
107
+ "rel": "self"
108
+ }
109
+ ]
110
+ },
111
+ {
112
+ "status": "CURRENT",
113
+ "id": "v2.0",
114
+ "links": [
115
+ {
116
+ "href": "http://glance/v2.0",
117
+ "rel": "self"
118
+ }
119
+ ]
120
+ }
121
+ ]}')
122
+
123
+ versions = @glance_client.get_api_version_list(:image)
124
+
125
+ expect(versions.size).to eq(2)
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,124 @@
1
+ require 'vagrant-openstack-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::NovaClient do
4
+ include FakeFS::SpecHelpers::All
5
+
6
+ let(:config) do
7
+ double('config').tap do |config|
8
+ config.stub(:openstack_auth_url) { 'http://heatAuthV2' }
9
+ config.stub(:openstack_orchestration_url) { nil }
10
+ config.stub(:tenant_name) { 'testTenant' }
11
+ config.stub(:username) { 'username' }
12
+ config.stub(:password) { 'password' }
13
+ end
14
+ end
15
+
16
+ let(:env) do
17
+ Hash.new.tap do |env|
18
+ env[:ui] = double('ui')
19
+ env[:ui].stub(:info).with(anything)
20
+ env[:machine] = double('machine')
21
+ env[:machine].stub(:provider_config) { config }
22
+ end
23
+ end
24
+
25
+ let(:session) do
26
+ VagrantPlugins::Openstack.session
27
+ end
28
+
29
+ before :each do
30
+ session.token = '123456'
31
+ session.project_id = 'a1b2c3'
32
+ session.endpoints = { orchestration: 'http://heat/a1b2c3' }
33
+ @heat_client = VagrantPlugins::Openstack.heat
34
+ end
35
+
36
+ describe 'stack_exists' do
37
+ context 'stack not found' do
38
+ it 'raise an StackNotFound error' do
39
+ stub_request(:get, 'http://heat/a1b2c3/stacks/stack_name/stack_id')
40
+ .with(
41
+ headers:
42
+ {
43
+ 'Accept' => 'application/json',
44
+ 'Accept-Encoding' => 'gzip, deflate',
45
+ 'X-Auth-Token' => '123456'
46
+ })
47
+ .to_return(
48
+ status: 404,
49
+ body: '{"itemNotFound": {"message": "Stack could not be found", "code": 404}}')
50
+
51
+ expect { @heat_client.get_stack_details(env, 'stack_name', 'stack_id') }.to raise_error(VagrantPlugins::Openstack::Errors::StackNotFound)
52
+
53
+ end
54
+ end
55
+ end
56
+
57
+ describe 'create_stack' do
58
+ context 'with token and project_id acquainted' do
59
+ it 'returns new stack id' do
60
+
61
+ stub_request(:post, 'http://heat/a1b2c3/stacks')
62
+ .with(
63
+ body: '{"stack_name":"stck","template":"toto"}',
64
+ headers:
65
+ {
66
+ 'Accept' => 'application/json',
67
+ 'Content-Type' => 'application/json',
68
+ 'X-Auth-Token' => '123456'
69
+ })
70
+ .to_return(status: 202, body: '{ "stack": { "id": "o1o2o3" } }')
71
+
72
+ stack_id = @heat_client.create_stack(env, name: 'stck', template: 'toto')
73
+
74
+ expect(stack_id).to eq('o1o2o3')
75
+ end
76
+ end
77
+ end
78
+
79
+ describe 'get_stack_details' do
80
+ context 'with token and project_id acquainted' do
81
+ it 'returns stack details' do
82
+
83
+ stub_request(:get, 'http://heat/a1b2c3/stacks/stack_id/stack_name')
84
+ .with(headers:
85
+ {
86
+ 'Accept' => 'application/json',
87
+ 'X-Auth-Token' => '123456'
88
+ })
89
+ .to_return(status: 200, body: '
90
+ {
91
+ "stack": {
92
+ "description": "sample stack",
93
+ "disable_rollback": "True",
94
+ "id": "stack_id",
95
+ "stack_name": "stack_name",
96
+ "stack_status": "CREATE_COMPLETE"
97
+ }
98
+ }')
99
+
100
+ stack = @heat_client.get_stack_details(env, 'stack_id', 'stack_name')
101
+
102
+ expect(stack['id']).to eq('stack_id')
103
+ expect(stack['stack_name']).to eq('stack_name')
104
+ end
105
+ end
106
+ end
107
+
108
+ describe 'delete_stack' do
109
+ context 'with token and project_id acquainted' do
110
+ it 'deletes the stack' do
111
+
112
+ stub_request(:delete, 'http://heat/a1b2c3/stacks/stack_id/stack_name')
113
+ .with(headers:
114
+ {
115
+ 'Accept' => 'application/json',
116
+ 'X-Auth-Token' => '123456'
117
+ })
118
+ .to_return(status: 204)
119
+
120
+ @heat_client.delete_stack(env, 'stack_id', 'stack_name')
121
+ end
122
+ end
123
+ end
124
+ end