vagrant-openstack-illuin-provider 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +40 -0
  4. data/CHANGELOG.md +282 -0
  5. data/Gemfile +18 -0
  6. data/RELEASE.md +15 -0
  7. data/Rakefile +25 -0
  8. data/Vagrantfile +20 -0
  9. data/dummy.box +0 -0
  10. data/example_box/README.md +13 -0
  11. data/example_box/metadata.json +3 -0
  12. data/functional_tests/Vagrantfile +58 -0
  13. data/functional_tests/keys/vagrant-openstack +27 -0
  14. data/functional_tests/keys/vagrant-openstack.pub +1 -0
  15. data/functional_tests/run_tests.sh +142 -0
  16. data/lib/vagrant-openstack-illuin-provider.rb +29 -0
  17. data/lib/vagrant-openstack-illuin-provider/action.rb +344 -0
  18. data/lib/vagrant-openstack-illuin-provider/action/abstract_action.rb +22 -0
  19. data/lib/vagrant-openstack-illuin-provider/action/connect_openstack.rb +60 -0
  20. data/lib/vagrant-openstack-illuin-provider/action/create_server.rb +187 -0
  21. data/lib/vagrant-openstack-illuin-provider/action/create_stack.rb +76 -0
  22. data/lib/vagrant-openstack-illuin-provider/action/delete_server.rb +53 -0
  23. data/lib/vagrant-openstack-illuin-provider/action/delete_stack.rb +73 -0
  24. data/lib/vagrant-openstack-illuin-provider/action/message.rb +19 -0
  25. data/lib/vagrant-openstack-illuin-provider/action/provision.rb +60 -0
  26. data/lib/vagrant-openstack-illuin-provider/action/read_ssh_info.rb +74 -0
  27. data/lib/vagrant-openstack-illuin-provider/action/read_state.rb +43 -0
  28. data/lib/vagrant-openstack-illuin-provider/action/resume.rb +24 -0
  29. data/lib/vagrant-openstack-illuin-provider/action/snapshot_cleanup.rb +32 -0
  30. data/lib/vagrant-openstack-illuin-provider/action/snapshot_delete.rb +32 -0
  31. data/lib/vagrant-openstack-illuin-provider/action/snapshot_list.rb +22 -0
  32. data/lib/vagrant-openstack-illuin-provider/action/snapshot_restore.rb +29 -0
  33. data/lib/vagrant-openstack-illuin-provider/action/snapshot_save.rb +51 -0
  34. data/lib/vagrant-openstack-illuin-provider/action/start_server.rb +24 -0
  35. data/lib/vagrant-openstack-illuin-provider/action/stop_server.rb +25 -0
  36. data/lib/vagrant-openstack-illuin-provider/action/suspend.rb +24 -0
  37. data/lib/vagrant-openstack-illuin-provider/action/sync_folders.rb +138 -0
  38. data/lib/vagrant-openstack-illuin-provider/action/wait_active.rb +33 -0
  39. data/lib/vagrant-openstack-illuin-provider/action/wait_stop.rb +33 -0
  40. data/lib/vagrant-openstack-illuin-provider/cap/snapshot_list.rb +15 -0
  41. data/lib/vagrant-openstack-illuin-provider/catalog/openstack_catalog.rb +90 -0
  42. data/lib/vagrant-openstack-illuin-provider/client/cinder.rb +39 -0
  43. data/lib/vagrant-openstack-illuin-provider/client/domain.rb +163 -0
  44. data/lib/vagrant-openstack-illuin-provider/client/glance.rb +65 -0
  45. data/lib/vagrant-openstack-illuin-provider/client/heat.rb +49 -0
  46. data/lib/vagrant-openstack-illuin-provider/client/http_utils.rb +116 -0
  47. data/lib/vagrant-openstack-illuin-provider/client/keystone.rb +128 -0
  48. data/lib/vagrant-openstack-illuin-provider/client/neutron.rb +48 -0
  49. data/lib/vagrant-openstack-illuin-provider/client/nova.rb +303 -0
  50. data/lib/vagrant-openstack-illuin-provider/client/openstack.rb +59 -0
  51. data/lib/vagrant-openstack-illuin-provider/client/request_logger.rb +23 -0
  52. data/lib/vagrant-openstack-illuin-provider/client/rest_utils.rb +28 -0
  53. data/lib/vagrant-openstack-illuin-provider/command/abstract_command.rb +51 -0
  54. data/lib/vagrant-openstack-illuin-provider/command/flavor_list.rb +24 -0
  55. data/lib/vagrant-openstack-illuin-provider/command/floatingip_list.rb +32 -0
  56. data/lib/vagrant-openstack-illuin-provider/command/image_list.rb +29 -0
  57. data/lib/vagrant-openstack-illuin-provider/command/main.rb +52 -0
  58. data/lib/vagrant-openstack-illuin-provider/command/network_list.rb +25 -0
  59. data/lib/vagrant-openstack-illuin-provider/command/openstack_command.rb +16 -0
  60. data/lib/vagrant-openstack-illuin-provider/command/reset.rb +20 -0
  61. data/lib/vagrant-openstack-illuin-provider/command/subnet_list.rb +22 -0
  62. data/lib/vagrant-openstack-illuin-provider/command/utils.rb +22 -0
  63. data/lib/vagrant-openstack-illuin-provider/command/volume_list.rb +25 -0
  64. data/lib/vagrant-openstack-illuin-provider/config.rb +505 -0
  65. data/lib/vagrant-openstack-illuin-provider/config/http.rb +39 -0
  66. data/lib/vagrant-openstack-illuin-provider/config_resolver.rb +334 -0
  67. data/lib/vagrant-openstack-illuin-provider/errors.rb +187 -0
  68. data/lib/vagrant-openstack-illuin-provider/logging.rb +39 -0
  69. data/lib/vagrant-openstack-illuin-provider/plugin.rb +58 -0
  70. data/lib/vagrant-openstack-illuin-provider/provider.rb +50 -0
  71. data/lib/vagrant-openstack-illuin-provider/utils.rb +81 -0
  72. data/lib/vagrant-openstack-illuin-provider/version.rb +15 -0
  73. data/lib/vagrant-openstack-illuin-provider/version_checker.rb +76 -0
  74. data/locales/en.yml +412 -0
  75. data/spec/vagrant-openstack-illuin-provider/action/connect_openstack_spec.rb +770 -0
  76. data/spec/vagrant-openstack-illuin-provider/action/create_server_spec.rb +260 -0
  77. data/spec/vagrant-openstack-illuin-provider/action/create_stack_spec.rb +99 -0
  78. data/spec/vagrant-openstack-illuin-provider/action/delete_server_spec.rb +89 -0
  79. data/spec/vagrant-openstack-illuin-provider/action/delete_stack_spec.rb +63 -0
  80. data/spec/vagrant-openstack-illuin-provider/action/message_spec.rb +33 -0
  81. data/spec/vagrant-openstack-illuin-provider/action/provision_spec.rb +97 -0
  82. data/spec/vagrant-openstack-illuin-provider/action/read_ssh_info_spec.rb +202 -0
  83. data/spec/vagrant-openstack-illuin-provider/action/read_state_spec.rb +81 -0
  84. data/spec/vagrant-openstack-illuin-provider/action/resume_server_spec.rb +49 -0
  85. data/spec/vagrant-openstack-illuin-provider/action/start_server_spec.rb +49 -0
  86. data/spec/vagrant-openstack-illuin-provider/action/stop_server_spec.rb +49 -0
  87. data/spec/vagrant-openstack-illuin-provider/action/suspend_server_spec.rb +49 -0
  88. data/spec/vagrant-openstack-illuin-provider/action/sync_folders_spec.rb +155 -0
  89. data/spec/vagrant-openstack-illuin-provider/action/wait_active_spec.rb +53 -0
  90. data/spec/vagrant-openstack-illuin-provider/action/wait_stop_spec.rb +53 -0
  91. data/spec/vagrant-openstack-illuin-provider/action_spec.rb +120 -0
  92. data/spec/vagrant-openstack-illuin-provider/client/cinder_spec.rb +129 -0
  93. data/spec/vagrant-openstack-illuin-provider/client/glance_spec.rb +145 -0
  94. data/spec/vagrant-openstack-illuin-provider/client/heat_spec.rb +130 -0
  95. data/spec/vagrant-openstack-illuin-provider/client/keystone_spec.rb +226 -0
  96. data/spec/vagrant-openstack-illuin-provider/client/neutron_spec.rb +173 -0
  97. data/spec/vagrant-openstack-illuin-provider/client/nova_spec.rb +760 -0
  98. data/spec/vagrant-openstack-illuin-provider/client/utils_spec.rb +176 -0
  99. data/spec/vagrant-openstack-illuin-provider/command/flavor_list_spec.rb +43 -0
  100. data/spec/vagrant-openstack-illuin-provider/command/floatingip_list_spec.rb +74 -0
  101. data/spec/vagrant-openstack-illuin-provider/command/image_list_spec.rb +95 -0
  102. data/spec/vagrant-openstack-illuin-provider/command/network_list_spec.rb +65 -0
  103. data/spec/vagrant-openstack-illuin-provider/command/reset_spec.rb +24 -0
  104. data/spec/vagrant-openstack-illuin-provider/command/subnet_list_spec.rb +45 -0
  105. data/spec/vagrant-openstack-illuin-provider/command/volume_list_spec.rb +40 -0
  106. data/spec/vagrant-openstack-illuin-provider/config_resolver_spec.rb +879 -0
  107. data/spec/vagrant-openstack-illuin-provider/config_spec.rb +416 -0
  108. data/spec/vagrant-openstack-illuin-provider/e2e_spec.rb.save +27 -0
  109. data/spec/vagrant-openstack-illuin-provider/provider_spec.rb +13 -0
  110. data/spec/vagrant-openstack-illuin-provider/spec_helper.rb +37 -0
  111. data/spec/vagrant-openstack-illuin-provider/utils_spec.rb +197 -0
  112. data/spec/vagrant-openstack-illuin-provider/version_checker_spec.rb +39 -0
  113. data/stackrc +25 -0
  114. data/vagrant-openstack-illuin-provider.gemspec +35 -0
  115. metadata +379 -0
@@ -0,0 +1,129 @@
1
+ require 'vagrant-openstack-illuin-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::CinderClient do
4
+ let(:http) do
5
+ double('http').tap do |http|
6
+ http.stub(:read_timeout) { 42 }
7
+ http.stub(:open_timeout) { 43 }
8
+ end
9
+ end
10
+
11
+ let(:config) do
12
+ double('config').tap do |config|
13
+ config.stub(:http) { http }
14
+ config.stub(:ssl_ca_file) { nil }
15
+ config.stub(:ssl_verify_peer) { true }
16
+ end
17
+ end
18
+
19
+ let(:env) do
20
+ {}.tap do |env|
21
+ env[:machine] = double('machine')
22
+ env[:machine].stub(:provider_config) { config }
23
+ end
24
+ end
25
+
26
+ let(:session) do
27
+ VagrantPlugins::Openstack.session
28
+ end
29
+
30
+ before :each do
31
+ session.token = '123456'
32
+ session.project_id = 'a1b2c3'
33
+ session.endpoints = { volume: 'http://cinder' }
34
+ @cinder_client = VagrantPlugins::Openstack.cinder
35
+ end
36
+
37
+ describe 'get_all_volumes' do
38
+ context 'on api v1' do
39
+ it 'returns volumes with details' do
40
+ stub_request(:get, 'http://cinder/volumes/detail')
41
+ .with(
42
+ headers:
43
+ {
44
+ 'Accept' => 'application/json',
45
+ 'X-Auth-Token' => '123456'
46
+ })
47
+ .to_return(
48
+ status: 200,
49
+ body: '
50
+ {
51
+ "volumes": [
52
+ {
53
+ "id": "987",
54
+ "display_name": "vol-01",
55
+ "size": "2",
56
+ "status": "available",
57
+ "bootable": "true",
58
+ "attachments": []
59
+ },
60
+ {
61
+ "id": "654",
62
+ "display_name": "vol-02",
63
+ "size": "4",
64
+ "status": "in-use",
65
+ "bootable": "false",
66
+ "attachments": [
67
+ {
68
+ "server_id": "inst-01",
69
+ "device": "/dev/vdc"
70
+ }
71
+ ]
72
+ }
73
+ ]
74
+ }
75
+ ')
76
+
77
+ volumes = @cinder_client.get_all_volumes(env)
78
+
79
+ expect(volumes).to eq [Volume.new('987', 'vol-01', '2', 'available', 'true', nil, nil),
80
+ Volume.new('654', 'vol-02', '4', 'in-use', 'false', 'inst-01', '/dev/vdc')]
81
+ end
82
+ end
83
+
84
+ context 'on api v2' do
85
+ it 'returns volumes with details' do
86
+ stub_request(:get, 'http://cinder/volumes/detail')
87
+ .with(
88
+ headers:
89
+ {
90
+ 'Accept' => 'application/json',
91
+ 'X-Auth-Token' => '123456'
92
+ })
93
+ .to_return(
94
+ status: 200,
95
+ body: '
96
+ {
97
+ "volumes": [
98
+ {
99
+ "id": "987",
100
+ "name": "vol-01",
101
+ "size": "2",
102
+ "status": "available",
103
+ "bootable": "true",
104
+ "attachments": []
105
+ },
106
+ {
107
+ "id": "654",
108
+ "name": "vol-02",
109
+ "size": "4",
110
+ "status": "in-use",
111
+ "bootable": "false",
112
+ "attachments": [
113
+ {
114
+ "server_id": "inst-01",
115
+ "device": "/dev/vdc"
116
+ }
117
+ ]
118
+ }
119
+ ]
120
+ }')
121
+
122
+ volumes = @cinder_client.get_all_volumes(env)
123
+
124
+ expect(volumes).to eq [Volume.new('987', 'vol-01', '2', 'available', 'true', nil, nil),
125
+ Volume.new('654', 'vol-02', '4', 'in-use', 'false', 'inst-01', '/dev/vdc')]
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,145 @@
1
+ require 'vagrant-openstack-illuin-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::GlanceClient do
4
+ let(:http) do
5
+ double('http').tap do |http|
6
+ http.stub(:read_timeout) { 42 }
7
+ http.stub(:open_timeout) { 43 }
8
+ end
9
+ end
10
+
11
+ let(:config) do
12
+ double('config').tap do |config|
13
+ config.stub(:http) { http }
14
+ config.stub(:ssl_ca_file) { nil }
15
+ config.stub(:ssl_verify_peer) { true }
16
+ end
17
+ end
18
+
19
+ let(:env) do
20
+ {}.tap do |env|
21
+ env[:machine] = double('machine')
22
+ env[:machine].stub(:provider_config) { config }
23
+ end
24
+ end
25
+
26
+ let(:session) do
27
+ VagrantPlugins::Openstack.session
28
+ end
29
+
30
+ before :each do
31
+ session.token = '123456'
32
+ session.project_id = 'a1b2c3'
33
+ session.endpoints = { image: 'http://glance' }
34
+ @glance_client = VagrantPlugins::Openstack.glance
35
+ end
36
+
37
+ describe 'get_all_images' do
38
+ context 'with token and project_id acquainted' do
39
+ context 'and api version is v2' do
40
+ it 'returns all images with details' do
41
+ stub_request(:get, 'http://glance/images')
42
+ .with(
43
+ headers:
44
+ {
45
+ 'Accept' => 'application/json',
46
+ 'X-Auth-Token' => '123456'
47
+ })
48
+ .to_return(
49
+ status: 200,
50
+ body: '
51
+ {
52
+ "images": [
53
+ { "id": "i1", "name": "image1", "visibility": "public", "size": "1024", "min_ram": "1", "min_disk": "10" },
54
+ { "id": "i2", "name": "image2", "visibility": "private", "size": "2048", "min_ram": "2", "min_disk": "20" }
55
+ ]
56
+ }')
57
+
58
+ images = @glance_client.get_all_images(env)
59
+
60
+ expect(images).to eq [Image.new('i1', 'image1', 'public', '1024', '1', '10'),
61
+ Image.new('i2', 'image2', 'private', '2048', '2', '20')]
62
+ end
63
+ end
64
+
65
+ context 'and api version is v1' do
66
+ it 'returns all images with details' do
67
+ stub_request(:get, 'http://glance/images')
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 },
80
+ { "id": "i2", "name": "image2", "is_public": false }
81
+ ]
82
+ }')
83
+
84
+ stub_request(:get, 'http://glance/images/detail')
85
+ .with(
86
+ headers:
87
+ {
88
+ 'Accept' => 'application/json',
89
+ 'X-Auth-Token' => '123456'
90
+ })
91
+ .to_return(
92
+ status: 200,
93
+ body: '
94
+ {
95
+ "images": [
96
+ { "id": "i1", "name": "image1", "is_public": true, "size": "1024", "min_ram": "1", "min_disk": "10" },
97
+ { "id": "i2", "name": "image2", "is_public": false, "size": "2048", "min_ram": "2", "min_disk": "20" }
98
+ ]
99
+ }')
100
+
101
+ images = @glance_client.get_all_images(env)
102
+
103
+ expect(images).to eq [Image.new('i1', 'image1', 'public', '1024', '1', '10'),
104
+ Image.new('i2', 'image2', 'private', '2048', '2', '20')]
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ describe 'get_api_version_list' do
111
+ it 'returns version list' do
112
+ stub_request(:get, 'http://glance/')
113
+ .with(header: { 'Accept' => 'application/json' })
114
+ .to_return(
115
+ status: 200,
116
+ body: '{
117
+ "versions": [
118
+ {
119
+ "status": "...",
120
+ "id": "v1.0",
121
+ "links": [
122
+ {
123
+ "href": "http://glance/v1.0",
124
+ "rel": "self"
125
+ }
126
+ ]
127
+ },
128
+ {
129
+ "status": "CURRENT",
130
+ "id": "v2.0",
131
+ "links": [
132
+ {
133
+ "href": "http://glance/v2.0",
134
+ "rel": "self"
135
+ }
136
+ ]
137
+ }
138
+ ]}')
139
+
140
+ versions = @glance_client.get_api_version_list(env)
141
+
142
+ expect(versions.size).to eq(2)
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,130 @@
1
+ require 'vagrant-openstack-illuin-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::NovaClient do
4
+ include FakeFS::SpecHelpers::All
5
+
6
+ let(:http) do
7
+ double('http').tap do |http|
8
+ http.stub(:read_timeout) { 42 }
9
+ http.stub(:open_timeout) { 43 }
10
+ end
11
+ end
12
+
13
+ let(:config) do
14
+ double('config').tap do |config|
15
+ config.stub(:openstack_auth_url) { 'http://heatAuthV2' }
16
+ config.stub(:openstack_orchestration_url) { nil }
17
+ config.stub(:tenant_name) { 'testTenant' }
18
+ config.stub(:username) { 'username' }
19
+ config.stub(:password) { 'password' }
20
+ config.stub(:http) { http }
21
+ config.stub(:ssl_ca_file) { nil }
22
+ config.stub(:ssl_verify_peer) { true }
23
+ end
24
+ end
25
+
26
+ let(:env) do
27
+ {}.tap do |env|
28
+ env[:ui] = double('ui')
29
+ env[:ui].stub(:info).with(anything)
30
+ env[:machine] = double('machine')
31
+ env[:machine].stub(:provider_config) { config }
32
+ end
33
+ end
34
+
35
+ let(:session) do
36
+ VagrantPlugins::Openstack.session
37
+ end
38
+
39
+ before :each do
40
+ session.token = '123456'
41
+ session.project_id = 'a1b2c3'
42
+ session.endpoints = { orchestration: 'http://heat/a1b2c3' }
43
+ @heat_client = VagrantPlugins::Openstack.heat
44
+ end
45
+
46
+ describe 'stack_exists' do
47
+ context 'stack not found' do
48
+ it 'raise an StackNotFound error' do
49
+ stub_request(:get, 'http://heat/a1b2c3/stacks/stack_name/stack_id')
50
+ .with(
51
+ headers:
52
+ {
53
+ 'Accept' => 'application/json',
54
+ 'Accept-Encoding' => 'gzip, deflate',
55
+ 'X-Auth-Token' => '123456'
56
+ })
57
+ .to_return(
58
+ status: 404,
59
+ body: '{"itemNotFound": {"message": "Stack could not be found", "code": 404}}')
60
+
61
+ expect { @heat_client.get_stack_details(env, 'stack_name', 'stack_id') }.to raise_error(VagrantPlugins::Openstack::Errors::StackNotFound)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe 'create_stack' do
67
+ context 'with token and project_id acquainted' do
68
+ it 'returns new stack id' do
69
+ stub_request(:post, 'http://heat/a1b2c3/stacks')
70
+ .with(
71
+ body: '{"stack_name":"stck","template":"toto"}',
72
+ headers:
73
+ {
74
+ 'Accept' => 'application/json',
75
+ 'Content-Type' => 'application/json',
76
+ 'X-Auth-Token' => '123456'
77
+ })
78
+ .to_return(status: 202, body: '{ "stack": { "id": "o1o2o3" } }')
79
+
80
+ stack_id = @heat_client.create_stack(env, name: 'stck', template: 'toto')
81
+
82
+ expect(stack_id).to eq('o1o2o3')
83
+ end
84
+ end
85
+ end
86
+
87
+ describe 'get_stack_details' do
88
+ context 'with token and project_id acquainted' do
89
+ it 'returns stack details' do
90
+ stub_request(:get, 'http://heat/a1b2c3/stacks/stack_id/stack_name')
91
+ .with(headers:
92
+ {
93
+ 'Accept' => 'application/json',
94
+ 'X-Auth-Token' => '123456'
95
+ })
96
+ .to_return(status: 200, body: '
97
+ {
98
+ "stack": {
99
+ "description": "sample stack",
100
+ "disable_rollback": "True",
101
+ "id": "stack_id",
102
+ "stack_name": "stack_name",
103
+ "stack_status": "CREATE_COMPLETE"
104
+ }
105
+ }')
106
+
107
+ stack = @heat_client.get_stack_details(env, 'stack_id', 'stack_name')
108
+
109
+ expect(stack['id']).to eq('stack_id')
110
+ expect(stack['stack_name']).to eq('stack_name')
111
+ end
112
+ end
113
+ end
114
+
115
+ describe 'delete_stack' do
116
+ context 'with token and project_id acquainted' do
117
+ it 'deletes the stack' do
118
+ stub_request(:delete, 'http://heat/a1b2c3/stacks/stack_id/stack_name')
119
+ .with(headers:
120
+ {
121
+ 'Accept' => 'application/json',
122
+ 'X-Auth-Token' => '123456'
123
+ })
124
+ .to_return(status: 204)
125
+
126
+ @heat_client.delete_stack(env, 'stack_id', 'stack_name')
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,226 @@
1
+ require 'vagrant-openstack-illuin-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::KeystoneClient do
4
+ let(:http) do
5
+ double('http').tap do |http|
6
+ http.stub(:read_timeout) { 42 }
7
+ http.stub(:open_timeout) { 43 }
8
+ end
9
+ end
10
+
11
+ let(:config) do
12
+ double('config').tap do |config|
13
+ config.stub(:openstack_auth_url) { 'http://keystoneAuthV2/tokens' }
14
+ config.stub(:openstack_compute_url) { nil }
15
+ config.stub(:openstack_network_url) { nil }
16
+ config.stub(:tenant_name) { 'testTenant' }
17
+ config.stub(:username) { 'username' }
18
+ config.stub(:password) { 'password' }
19
+ config.stub(:http) { http }
20
+ config.stub(:interface_type) { 'public' }
21
+ config.stub(:identity_api_version) { '2' }
22
+ config.stub(:project_name) { 'testTenant' }
23
+ config.stub(:ssl_ca_file) { nil }
24
+ config.stub(:ssl_verify_peer) { true }
25
+ end
26
+ end
27
+
28
+ let(:env) do
29
+ {}.tap do |env|
30
+ env[:ui] = double('ui')
31
+ env[:ui].stub(:info).with(anything)
32
+ env[:machine] = double('machine')
33
+ env[:machine].stub(:provider_config) { config }
34
+ end
35
+ end
36
+
37
+ let(:session) do
38
+ VagrantPlugins::Openstack.session
39
+ end
40
+
41
+ describe 'authenticate' do
42
+ let(:keystone_request_headers) do
43
+ {
44
+ 'Accept' => 'application/json',
45
+ 'Content-Type' => 'application/json'
46
+ }
47
+ end
48
+
49
+ let(:keystone_request_body) do
50
+ '{"auth":{"tenantName":"testTenant","passwordCredentials":{"username":"username","password":"password"}}}'
51
+ end
52
+
53
+ let(:keystone_response_body) do
54
+ '{"access":{"token":{"id":"0123456789","tenant":{"id":"testTenantId"}},"serviceCatalog":[
55
+ {"endpoints":[{"id":"eid1","publicURL":"http://nova"}],"type":"compute"},
56
+ {"endpoints":[{"id":"eid2","publicURL":"http://neutron"}],"type":"network"}
57
+ ]}}'
58
+ end
59
+
60
+ let(:keystone_response_headers_v3) do
61
+ {
62
+ 'Accept' => 'application/json',
63
+ 'Content-Type' => 'application/json',
64
+ 'x_subject_token' => '0123456789'
65
+ }
66
+ end
67
+
68
+ let(:keystone_request_body_v3) do
69
+ '{"auth":{"identity":{"methods":["password"],"password":{"user":{"name":"username","domain":'\
70
+ '{"name":"dummy"},"password":"password"}}},"scope":{"project":{"name":"testTenant","domain":'\
71
+ '{"name":"dummy"}}}}}'
72
+ end
73
+
74
+ let(:keystone_response_body_v3) do
75
+ '{"token":{"is_domain":false,"methods":["password"],"roles":[{"id":"1234","name":"_member_"}],
76
+ "is_admin_project":false,"project":{"domain":{"id":"1234","name":"dummy"},"id":"012345678910",
77
+ "name":"testTenantId"},"catalog":[
78
+ {"endpoints":[{"id":"eid1","interface":"public","url":"http://nova"}],"type":"compute"},
79
+ {"endpoints":[{"id":"eid2","interface":"public","url":"http://neutron"}],"type":"network"}
80
+ ]}}'
81
+ end
82
+
83
+ before :each do
84
+ @keystone_client = VagrantPlugins::Openstack.keystone
85
+ end
86
+
87
+ context 'with good credentials' do
88
+ it 'store token and tenant id' do
89
+ stub_request(:post, 'http://keystoneAuthV2/tokens')
90
+ .with(
91
+ body: keystone_request_body,
92
+ headers: keystone_request_headers)
93
+ .to_return(
94
+ status: 200,
95
+ body: keystone_response_body,
96
+ headers: keystone_request_headers)
97
+
98
+ @keystone_client.authenticate(env)
99
+
100
+ session.token.should eq('0123456789')
101
+ session.project_id.should eq('testTenantId')
102
+ end
103
+ end
104
+
105
+ context 'with wrong credentials' do
106
+ it 'raise an unauthorized error' do
107
+ stub_request(:post, 'http://keystoneAuthV2/tokens')
108
+ .with(
109
+ body: keystone_request_body,
110
+ headers: keystone_request_headers)
111
+ .to_return(
112
+ status: 401,
113
+ body: '{
114
+ "error": {
115
+ "message": "The request you have made requires authentication.",
116
+ "code": 401,
117
+ "title": "Unauthorized"
118
+ }
119
+ }',
120
+ headers: keystone_request_headers)
121
+
122
+ expect { @keystone_client.authenticate(env) }.to raise_error(Errors::AuthenticationFailed)
123
+ end
124
+ end
125
+
126
+ context 'with bad endpoint' do
127
+ it 'raise a BadAuthenticationEndpoint error' do
128
+ stub_request(:post, 'http://keystoneAuthV2/tokens')
129
+ .with(
130
+ body: keystone_request_body,
131
+ headers: keystone_request_headers)
132
+ .to_return(
133
+ status: 404)
134
+
135
+ expect { @keystone_client.authenticate(env) }.to raise_error(Errors::BadAuthenticationEndpoint)
136
+ end
137
+ end
138
+
139
+ context 'with /tokens suffix missing in URL' do
140
+ it 'raise add the suffix' do
141
+ config.stub(:openstack_auth_url) { 'http://keystoneAuthV2' }
142
+
143
+ stub_request(:post, 'http://keystoneAuthV2/tokens')
144
+ .with(
145
+ body: keystone_request_body,
146
+ headers: keystone_request_headers)
147
+ .to_return(
148
+ status: 200,
149
+ body: keystone_response_body,
150
+ headers: keystone_request_headers)
151
+
152
+ @keystone_client.authenticate(env)
153
+
154
+ session.token.should eq('0123456789')
155
+ session.project_id.should eq('testTenantId')
156
+ end
157
+ end
158
+
159
+ context 'with internal server error' do
160
+ it 'raise a VagrantOpenstackError error with response body as message' do
161
+ stub_request(:post, 'http://keystoneAuthV2/tokens')
162
+ .with(
163
+ body: keystone_request_body,
164
+ headers: keystone_request_headers)
165
+ .to_return(
166
+ status: 500,
167
+ body: 'Internal server error')
168
+
169
+ begin
170
+ @keystone_client.authenticate(env)
171
+ fail 'Expected Errors::VagrantOpenstackError'
172
+ rescue Errors::VagrantOpenstackError => e
173
+ e.message.should eq('Internal server error')
174
+ end
175
+ end
176
+ end
177
+
178
+ # V3
179
+ context 'with good credentials v3' do
180
+ it 'store token and tenant id' do
181
+ config.stub(:domain_name) { 'dummy' }
182
+ config.stub(:identity_api_version) { '3' }
183
+ config.stub(:openstack_auth_url) { 'http://keystoneAuthV3' }
184
+
185
+ stub_request(:post, 'http://keystoneAuthV3/auth/tokens')
186
+ .with(
187
+ body: keystone_request_body_v3,
188
+ headers: keystone_request_headers)
189
+ .to_return(
190
+ status: 200,
191
+ body: keystone_response_body_v3,
192
+ headers: keystone_response_headers_v3)
193
+
194
+ @keystone_client.authenticate(env)
195
+
196
+ session.token.should eq('0123456789')
197
+ session.project_id.should eq('012345678910')
198
+ end
199
+ end
200
+
201
+ context 'with wrong credentials v3' do
202
+ it 'raise an unauthorized error ' do
203
+ config.stub(:domain_name) { 'dummy' }
204
+ config.stub(:identity_api_version) { '3' }
205
+ config.stub(:openstack_auth_url) { 'http://keystoneAuthV3' }
206
+
207
+ stub_request(:post, 'http://keystoneAuthV3/auth/tokens')
208
+ .with(
209
+ body: keystone_request_body_v3,
210
+ headers: keystone_request_headers)
211
+ .to_return(
212
+ status: 401,
213
+ body: '{
214
+ "error": {
215
+ "message": "The request you have made requires authentication.",
216
+ "code": 401,
217
+ "title": "Unauthorized"
218
+ }
219
+ }',
220
+ headers: keystone_response_headers_v3)
221
+
222
+ expect { @keystone_client.authenticate(env) }.to raise_error(Errors::AuthenticationFailed)
223
+ end
224
+ end
225
+ end
226
+ end