vagrant-openstack-provider 0.7.2 → 0.8.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/CHANGELOG.md +14 -0
- data/Gemfile +8 -1
- data/lib/vagrant-openstack-provider/action.rb +18 -2
- data/lib/vagrant-openstack-provider/action/create_server.rb +2 -2
- data/lib/vagrant-openstack-provider/action/create_stack.rb +1 -1
- data/lib/vagrant-openstack-provider/action/delete_server.rb +1 -1
- data/lib/vagrant-openstack-provider/action/delete_stack.rb +1 -1
- data/lib/vagrant-openstack-provider/action/wait_active.rb +1 -1
- data/lib/vagrant-openstack-provider/action/wait_stop.rb +1 -1
- data/lib/vagrant-openstack-provider/catalog/openstack_catalog.rb +35 -12
- data/lib/vagrant-openstack-provider/client/keystone.rb +73 -22
- data/lib/vagrant-openstack-provider/config.rb +85 -7
- data/lib/vagrant-openstack-provider/utils.rb +6 -1
- data/lib/vagrant-openstack-provider/version.rb +1 -1
- data/lib/vagrant-openstack-provider/version_checker.rb +1 -1
- data/locales/en.yml +13 -0
- data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +75 -0
- data/spec/vagrant-openstack-provider/client/keystone_spec.rb +74 -0
- data/spec/vagrant-openstack-provider/config_spec.rb +29 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 609b227799e2765e0d6f7bb5277e7e8602cb424f
|
4
|
+
data.tar.gz: d92034eb5c24737dc80912e983e35443e8929550
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34905aff4b10744c0c2402b01d801d76adff1c4be7107c46d55e85be80455dc44046dccf6d46fd7df3694695ceef9eaabbc603fb3eff217438648ad6473a0763
|
7
|
+
data.tar.gz: e4cdb6940e49072f44bd79829981dce5b6fbc4b385e7f59528ff8c9a22663e86137f03b1999389168dc888b9aa90b21ec05e2738b114968b9cc4ce024b47afce
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# 0.8.0 (November 19, 2016)
|
2
|
+
|
3
|
+
IMPROVEMENTS:
|
4
|
+
|
5
|
+
- Move to standard Vagrant synced folders middleware #295
|
6
|
+
|
7
|
+
FEATURES:
|
8
|
+
|
9
|
+
- Support Keystone v3 API #4
|
10
|
+
|
11
|
+
BUG FIXES:
|
12
|
+
|
13
|
+
- Bugfix on IP address resolution #285
|
14
|
+
|
1
15
|
# 0.7.2 (May 1, 2016)
|
2
16
|
|
3
17
|
IMPROVEMENTS:
|
data/Gemfile
CHANGED
@@ -3,7 +3,14 @@ source 'https://rubygems.org'
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
group :development do
|
6
|
-
gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git', tag: 'v1.8.
|
6
|
+
gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git', tag: 'v1.8.5'
|
7
|
+
# FIXME: Hack to allow Vagrant v1.6.5 to install for tests. Remove when
|
8
|
+
# support for 1.6.5 is dropped.
|
9
|
+
gem 'rack', '< 2'
|
10
|
+
# FIXME: Version 1.4.0 of the ruby_dep gem added a constraint on the Ruby
|
11
|
+
# version being >=2.2.5. This pin to ruby_dep 1.3.1 can be removed when the
|
12
|
+
# next Vagrant version after 1.8.5 is released.
|
13
|
+
gem 'ruby_dep', '~> 1.3.1'
|
7
14
|
gem 'appraisal', '1.0.0'
|
8
15
|
gem 'rubocop', '0.29.0', require: false
|
9
16
|
gem 'coveralls', require: false
|
@@ -39,7 +39,13 @@ module VagrantPlugins
|
|
39
39
|
else
|
40
40
|
b2.use Provision
|
41
41
|
end
|
42
|
-
|
42
|
+
if env[:machine].provider_config.use_legacy_synced_folders
|
43
|
+
env[:machine].ui.warn I18n.t('vagrant_openstack.config.sync_folders_deprecated')
|
44
|
+
b2.use SyncFolders
|
45
|
+
else
|
46
|
+
# Standard Vagrant implementation.
|
47
|
+
b2.use SyncedFolders
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
45
51
|
end
|
@@ -61,6 +67,7 @@ module VagrantPlugins
|
|
61
67
|
# key.
|
62
68
|
def self.action_read_state
|
63
69
|
new_builder.tap do |b|
|
70
|
+
b.use HandleBox
|
64
71
|
b.use ConfigValidate
|
65
72
|
b.use ConnectOpenstack
|
66
73
|
b.use ReadState
|
@@ -97,6 +104,7 @@ module VagrantPlugins
|
|
97
104
|
|
98
105
|
def self.action_up
|
99
106
|
new_builder.tap do |b|
|
107
|
+
b.use HandleBox
|
100
108
|
b.use ConfigValidate
|
101
109
|
b.use ConnectOpenstack
|
102
110
|
|
@@ -111,7 +119,15 @@ module VagrantPlugins
|
|
111
119
|
b2.use Provision
|
112
120
|
end
|
113
121
|
end
|
114
|
-
|
122
|
+
|
123
|
+
if env[:machine].provider_config.use_legacy_synced_folders
|
124
|
+
env[:machine].ui.warn I18n.t('vagrant_openstack.config.sync_folders_deprecated')
|
125
|
+
b2.use SyncFolders
|
126
|
+
else
|
127
|
+
# Standard Vagrant implementation.
|
128
|
+
b2.use SyncedFolders
|
129
|
+
end
|
130
|
+
|
115
131
|
b2.use CreateStack
|
116
132
|
b2.use CreateServer
|
117
133
|
b2.use Message, I18n.t('vagrant_openstack.ssh_disabled_provisioning') if ssh_disabled
|
@@ -99,7 +99,7 @@ module VagrantPlugins
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
log = "
|
102
|
+
log = "Launching server '#{server_name}' in project '#{config.tenant_name}' "
|
103
103
|
log << "with flavor '#{options[:flavor].name}' (#{options[:flavor].id}), "
|
104
104
|
unless options[:image].nil?
|
105
105
|
log << "image '#{options[:image].name}' (#{options[:image].id}) "
|
@@ -131,7 +131,7 @@ module VagrantPlugins
|
|
131
131
|
@logger.info "Waiting for the server with id #{server_id} to be built..."
|
132
132
|
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_build'))
|
133
133
|
config = env[:machine].provider_config
|
134
|
-
timeout(config.server_create_timeout, Errors::Timeout) do
|
134
|
+
Timeout.timeout(config.server_create_timeout, Errors::Timeout) do
|
135
135
|
server_status = 'WAITING'
|
136
136
|
until server_status == 'ACTIVE'
|
137
137
|
@logger.debug('Waiting for server to be ACTIVE')
|
@@ -60,7 +60,7 @@ module VagrantPlugins
|
|
60
60
|
@logger.info "Waiting for the stack with id #{stack_id} to be built..."
|
61
61
|
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_stack'))
|
62
62
|
config = env[:machine].provider_config
|
63
|
-
timeout(config.stack_create_timeout, Errors::Timeout) do
|
63
|
+
Timeout.timeout(config.stack_create_timeout, Errors::Timeout) do
|
64
64
|
stack_status = 'CREATE_IN_PROGRESS'
|
65
65
|
until stack_status == 'CREATE_COMPLETE'
|
66
66
|
@logger.debug('Waiting for stack to be CREATED')
|
@@ -32,7 +32,7 @@ module VagrantPlugins
|
|
32
32
|
@logger.info "Waiting for the instance with id #{instance_id} to be deleted..."
|
33
33
|
env[:ui].info(I18n.t('vagrant_openstack.waiting_deleted'))
|
34
34
|
config = env[:machine].provider_config
|
35
|
-
timeout(config.server_delete_timeout, Errors::Timeout) do
|
35
|
+
Timeout.timeout(config.server_delete_timeout, Errors::Timeout) do
|
36
36
|
delete_ok = false
|
37
37
|
until delete_ok
|
38
38
|
begin
|
@@ -57,7 +57,7 @@ module VagrantPlugins
|
|
57
57
|
@logger.info "Waiting for the stack with id #{stack_id} to be deleted..."
|
58
58
|
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_stack_deleted'))
|
59
59
|
config = env[:machine].provider_config
|
60
|
-
timeout(config.stack_delete_timeout, Errors::Timeout) do
|
60
|
+
Timeout.timeout(config.stack_delete_timeout, Errors::Timeout) do
|
61
61
|
stack_status = 'DELETE_IN_PROGRESS'
|
62
62
|
until stack_status == 'DELETE_COMPLETE'
|
63
63
|
@logger.debug('Waiting for stack to be DELETED')
|
@@ -18,7 +18,7 @@ module VagrantPlugins
|
|
18
18
|
env[:ui].info(I18n.t('vagrant_openstack.waiting_start'))
|
19
19
|
client = env[:openstack_client].nova
|
20
20
|
config = env[:machine].provider_config
|
21
|
-
timeout(config.server_active_timeout, Errors::Timeout) do
|
21
|
+
Timeout.timeout(config.server_active_timeout, Errors::Timeout) do
|
22
22
|
while client.get_server_details(env, env[:machine].id)['status'] != 'ACTIVE'
|
23
23
|
sleep @retry_interval
|
24
24
|
@logger.info('Waiting for server to be active')
|
@@ -18,7 +18,7 @@ module VagrantPlugins
|
|
18
18
|
env[:ui].info(I18n.t('vagrant_openstack.waiting_stop'))
|
19
19
|
client = env[:openstack_client].nova
|
20
20
|
config = env[:machine].provider_config
|
21
|
-
timeout(config.server_stop_timeout, Errors::Timeout) do
|
21
|
+
Timeout.timeout(config.server_stop_timeout, Errors::Timeout) do
|
22
22
|
while client.get_server_details(env, env[:machine].id)['status'] != 'SHUTOFF'
|
23
23
|
sleep @retry_interval
|
24
24
|
@logger.info('Waiting for server to stop')
|
@@ -10,24 +10,16 @@ module VagrantPlugins
|
|
10
10
|
config = env[:machine].provider_config
|
11
11
|
client = env[:openstack_client]
|
12
12
|
endpoints = client.session.endpoints
|
13
|
-
endpoint_type = config.endpoint_type
|
14
13
|
@logger.info(I18n.t('vagrant_openstack.client.looking_for_available_endpoints'))
|
15
14
|
@logger.info("Selecting endpoints matching region '#{config.region}'") unless config.region.nil?
|
16
15
|
|
17
16
|
catalog.each do |service|
|
18
17
|
se = service['endpoints']
|
19
|
-
if config.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
url = se[0][endpoint_type].strip
|
25
|
-
else
|
26
|
-
se.each do |endpoint|
|
27
|
-
url = endpoint[endpoint_type].strip if endpoint['region'].eql? config.region
|
28
|
-
end
|
18
|
+
if config.identity_api_version == '2'
|
19
|
+
get_endpoints_2(env, se, service, config, endpoints)
|
20
|
+
elsif config.identity_api_version == '3'
|
21
|
+
get_interfaces_3(se, service, config, endpoints)
|
29
22
|
end
|
30
|
-
endpoints[service['type'].to_sym] = url unless url.nil? || url.empty?
|
31
23
|
end
|
32
24
|
|
33
25
|
endpoints[:network] = choose_api_version('Neutron', 'openstack_network_url', 'v2') do
|
@@ -41,6 +33,37 @@ module VagrantPlugins
|
|
41
33
|
|
42
34
|
private
|
43
35
|
|
36
|
+
def get_endpoints_2(env, se, service, config, endpoints)
|
37
|
+
endpoint_type = config.endpoint_type
|
38
|
+
if config.region.nil?
|
39
|
+
if se.size > 1
|
40
|
+
env[:ui].warn I18n.t('vagrant_openstack.client.multiple_endpoint', size: se.size, type: service['type'])
|
41
|
+
env[:ui].warn " => #{service['endpoints'][0][endpoint_type]}"
|
42
|
+
end
|
43
|
+
url = se[0][endpoint_type].strip
|
44
|
+
else
|
45
|
+
se.each do |endpoint|
|
46
|
+
url = endpoint[endpoint_type].strip if endpoint['region'].eql? config.region
|
47
|
+
end
|
48
|
+
end
|
49
|
+
endpoints[service['type'].to_sym] = url unless url.nil? || url.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_interfaces_3(se, service, config, endpoints)
|
53
|
+
url = nil
|
54
|
+
se.each do |endpoint|
|
55
|
+
next if endpoint['interface'] != config.interface_type
|
56
|
+
if config.region.nil?
|
57
|
+
url = endpoint['url']
|
58
|
+
break
|
59
|
+
elsif endpoint['region'] == config.region
|
60
|
+
url = endpoint['url']
|
61
|
+
break
|
62
|
+
end
|
63
|
+
end
|
64
|
+
endpoints[service['type'].to_sym] = url unless url.nil? || url.empty?
|
65
|
+
end
|
66
|
+
|
44
67
|
def choose_api_version(service_name, url_property, version_prefix = nil, fail_if_not_found = true)
|
45
68
|
versions = yield
|
46
69
|
|
@@ -19,20 +19,13 @@ module VagrantPlugins
|
|
19
19
|
config = env[:machine].provider_config
|
20
20
|
@logger.info(I18n.t('vagrant_openstack.client.authentication', project: config.tenant_name, user: config.username))
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
username: config.username,
|
30
|
-
password: '****'
|
31
|
-
}
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
auth_url = get_auth_url_v2 env
|
22
|
+
if config.identity_api_version == '2'
|
23
|
+
post_body = get_body_2 config
|
24
|
+
auth_url = get_auth_url_2 env
|
25
|
+
elsif config.identity_api_version == '3'
|
26
|
+
post_body = get_body_3 config
|
27
|
+
auth_url = get_auth_url_3 env
|
28
|
+
end
|
36
29
|
|
37
30
|
headers = {
|
38
31
|
content_type: :json,
|
@@ -41,13 +34,19 @@ module VagrantPlugins
|
|
41
34
|
|
42
35
|
log_request(:POST, auth_url, post_body.to_json, headers)
|
43
36
|
|
44
|
-
|
37
|
+
if config.identity_api_version == '2'
|
38
|
+
post_body[:auth][:passwordCredentials][:password] = config.password
|
39
|
+
elsif config.identity_api_version == '3'
|
40
|
+
post_body[:auth][:identity][:password][:user][:password] = config.password
|
41
|
+
end
|
45
42
|
|
46
43
|
authentication = RestUtils.post(env, auth_url, post_body.to_json, headers) do |response|
|
47
44
|
log_response(response)
|
48
45
|
case response.code
|
49
46
|
when 200
|
50
47
|
response
|
48
|
+
when 201
|
49
|
+
response
|
51
50
|
when 401
|
52
51
|
fail Errors::AuthenticationFailed
|
53
52
|
when 404
|
@@ -57,17 +56,69 @@ module VagrantPlugins
|
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
59
|
+
if config.identity_api_version == '2'
|
60
|
+
access = JSON.parse(authentication)['access']
|
61
|
+
response_token = access['token']
|
62
|
+
@session.token = response_token['id']
|
63
|
+
@session.project_id = response_token['tenant']['id']
|
64
|
+
return access['serviceCatalog']
|
65
|
+
elsif config.identity_api_version == '3'
|
66
|
+
body = JSON.parse(authentication)
|
67
|
+
@session.token = authentication.headers[:x_subject_token]
|
68
|
+
@session.project_id = body['token']['project']['id']
|
69
|
+
return body['token']['catalog']
|
70
|
+
end
|
66
71
|
end
|
67
72
|
|
68
73
|
private
|
69
74
|
|
70
|
-
def
|
75
|
+
def get_body_2(config)
|
76
|
+
{
|
77
|
+
auth:
|
78
|
+
{
|
79
|
+
tenantName: config.tenant_name,
|
80
|
+
passwordCredentials:
|
81
|
+
{
|
82
|
+
username: config.username,
|
83
|
+
password: '****'
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_body_3(config)
|
90
|
+
{
|
91
|
+
auth:
|
92
|
+
{
|
93
|
+
identity: {
|
94
|
+
methods: ['password'],
|
95
|
+
password: {
|
96
|
+
user: {
|
97
|
+
name: config.username,
|
98
|
+
domain: {
|
99
|
+
name: config.domain_name
|
100
|
+
},
|
101
|
+
password: '****'
|
102
|
+
}
|
103
|
+
}
|
104
|
+
},
|
105
|
+
scope: {
|
106
|
+
project: {
|
107
|
+
name: config.project_name,
|
108
|
+
domain: { name: config.domain_name }
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_auth_url_3(env)
|
116
|
+
url = env[:machine].provider_config.openstack_auth_url
|
117
|
+
return url if url.match(%r{/tokens/*$})
|
118
|
+
"#{url}/auth/tokens"
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_auth_url_2(env)
|
71
122
|
url = env[:machine].provider_config.openstack_auth_url
|
72
123
|
return url if url.match(%r{/tokens/*$})
|
73
124
|
"#{url}/tokens"
|
@@ -52,6 +52,11 @@ module VagrantPlugins
|
|
52
52
|
#
|
53
53
|
attr_accessor :tenant_name
|
54
54
|
|
55
|
+
#
|
56
|
+
# The name of the openstack project on witch the vm will be created, changed name in v3 identity API.
|
57
|
+
#
|
58
|
+
attr_accessor :project_name
|
59
|
+
|
55
60
|
# The name of the server. This defaults to the name of the machine
|
56
61
|
# defined by Vagrant (via `config.vm.define`), but can be overriden
|
57
62
|
# here.
|
@@ -62,6 +67,11 @@ module VagrantPlugins
|
|
62
67
|
# @return [String]
|
63
68
|
attr_accessor :username
|
64
69
|
|
70
|
+
# The domain name to access Openstack, this defaults to Default.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
attr_accessor :domain_name
|
74
|
+
|
65
75
|
# The name of the keypair to use.
|
66
76
|
#
|
67
77
|
# @return [String]
|
@@ -82,6 +92,8 @@ module VagrantPlugins
|
|
82
92
|
|
83
93
|
# Opt files/directories in to the rsync operation performed by this provider
|
84
94
|
#
|
95
|
+
# @deprecated Use standard Vagrant synced folders instead.
|
96
|
+
#
|
85
97
|
# @return [Array]
|
86
98
|
attr_accessor :rsync_includes
|
87
99
|
|
@@ -103,12 +115,16 @@ module VagrantPlugins
|
|
103
115
|
|
104
116
|
# Sync folder method. Can be either "rsync" or "none"
|
105
117
|
#
|
118
|
+
# @deprecated Use standard Vagrant synced folders instead.
|
119
|
+
#
|
106
120
|
# @return [String]
|
107
121
|
attr_accessor :sync_method
|
108
122
|
|
109
123
|
# Sync folder ignore files. A list of files containing exclude patterns to ignore in the rsync operation
|
110
124
|
# performed by this provider
|
111
125
|
#
|
126
|
+
# @deprecated Use standard Vagrant synced folders instead.
|
127
|
+
#
|
112
128
|
# @return [Array]
|
113
129
|
attr_accessor :rsync_ignore_files
|
114
130
|
|
@@ -167,6 +183,16 @@ module VagrantPlugins
|
|
167
183
|
# @return [String]
|
168
184
|
attr_accessor :endpoint_type
|
169
185
|
|
186
|
+
# Specify the endpoint_type to use : publicL, admin, or internal (default is public)
|
187
|
+
#
|
188
|
+
# @return [String]
|
189
|
+
attr_accessor :interface_type
|
190
|
+
|
191
|
+
# Specify the authentication version to use : 2 or 3 (ddefault is 2()
|
192
|
+
#
|
193
|
+
# @return [String]
|
194
|
+
attr_accessor :identity_api_version
|
195
|
+
|
170
196
|
#
|
171
197
|
# @return [Integer]
|
172
198
|
attr_accessor :server_create_timeout
|
@@ -199,6 +225,20 @@ module VagrantPlugins
|
|
199
225
|
# @return [Boolean]
|
200
226
|
attr_accessor :meta_args_support
|
201
227
|
|
228
|
+
# A switch for enabling the legacy synced folders implementation.
|
229
|
+
#
|
230
|
+
# This defaults to false, but is automatically set to true if any of the
|
231
|
+
# legacy synced folder options are used:
|
232
|
+
#
|
233
|
+
# - {#rsync_includes}
|
234
|
+
# - {#rsync_ignore_files}
|
235
|
+
# - {#sync_method}
|
236
|
+
#
|
237
|
+
# @deprecated Use standard Vagrant synced folders instead.
|
238
|
+
#
|
239
|
+
# @return [Boolean]
|
240
|
+
attr_accessor :use_legacy_synced_folders
|
241
|
+
|
202
242
|
def initialize
|
203
243
|
@password = UNSET_VALUE
|
204
244
|
@openstack_compute_url = UNSET_VALUE
|
@@ -208,6 +248,8 @@ module VagrantPlugins
|
|
208
248
|
@openstack_image_url = UNSET_VALUE
|
209
249
|
@openstack_auth_url = UNSET_VALUE
|
210
250
|
@endpoint_type = UNSET_VALUE
|
251
|
+
@interface_type = UNSET_VALUE
|
252
|
+
@identity_api_version = UNSET_VALUE
|
211
253
|
@region = UNSET_VALUE
|
212
254
|
@flavor = UNSET_VALUE
|
213
255
|
@image = UNSET_VALUE
|
@@ -242,6 +284,7 @@ module VagrantPlugins
|
|
242
284
|
@stack_delete_timeout = UNSET_VALUE
|
243
285
|
@meta_args_support = UNSET_VALUE
|
244
286
|
@http = HttpConfig.new
|
287
|
+
@use_legacy_synced_folders = UNSET_VALUE
|
245
288
|
end
|
246
289
|
|
247
290
|
def merge(other)
|
@@ -282,7 +325,7 @@ module VagrantPlugins
|
|
282
325
|
result
|
283
326
|
end
|
284
327
|
|
285
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
328
|
+
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
286
329
|
def finalize!
|
287
330
|
@password = nil if @password == UNSET_VALUE
|
288
331
|
@openstack_compute_url = nil if @openstack_compute_url == UNSET_VALUE
|
@@ -292,19 +335,20 @@ module VagrantPlugins
|
|
292
335
|
@openstack_image_url = nil if @openstack_image_url == UNSET_VALUE
|
293
336
|
@openstack_auth_url = nil if @openstack_auth_url == UNSET_VALUE
|
294
337
|
@endpoint_type = 'publicURL' if @endpoint_type == UNSET_VALUE
|
338
|
+
@interface_type = 'public' if @interface_type == UNSET_VALUE
|
339
|
+
@identity_api_version = '2' if @identity_api_version == UNSET_VALUE
|
295
340
|
@region = nil if @region == UNSET_VALUE
|
296
341
|
@flavor = nil if @flavor == UNSET_VALUE
|
297
342
|
@image = nil if @image == UNSET_VALUE
|
298
343
|
@volume_boot = nil if @volume_boot == UNSET_VALUE
|
299
344
|
@tenant_name = nil if @tenant_name == UNSET_VALUE
|
345
|
+
@project_name = nil if @project_name == UNSET_VALUE
|
300
346
|
@server_name = nil if @server_name == UNSET_VALUE
|
301
347
|
@username = nil if @username == UNSET_VALUE
|
302
|
-
@
|
303
|
-
@rsync_ignore_files = nil if @rsync_ignore_files.empty?
|
348
|
+
@domain_name = 'Default' if @domain_name == UNSET_VALUE
|
304
349
|
@floating_ip = nil if @floating_ip == UNSET_VALUE
|
305
350
|
@floating_ip_pool = nil if @floating_ip_pool == UNSET_VALUE
|
306
351
|
@floating_ip_pool_always_allocate = false if floating_ip_pool_always_allocate == UNSET_VALUE
|
307
|
-
@sync_method = 'rsync' if @sync_method == UNSET_VALUE
|
308
352
|
@keypair_name = nil if @keypair_name == UNSET_VALUE
|
309
353
|
@public_key_path = nil if @public_key_path == UNSET_VALUE
|
310
354
|
@availability_zone = nil if @availability_zone == UNSET_VALUE
|
@@ -314,6 +358,27 @@ module VagrantPlugins
|
|
314
358
|
@metadata = nil if @metadata == UNSET_VALUE
|
315
359
|
@ssh_disabled = false if @ssh_disabled == UNSET_VALUE
|
316
360
|
|
361
|
+
# The value of use_legacy_synced_folders is used by action chains
|
362
|
+
# to determine which synced folder implementation to run.
|
363
|
+
if @use_legacy_synced_folders == UNSET_VALUE
|
364
|
+
@use_legacy_synced_folders = !(
|
365
|
+
(@rsync_includes.nil? || @rsync_includes.empty?) &&
|
366
|
+
(@rsync_ignore_files.nil? || @rsync_ignore_files.empty?) &&
|
367
|
+
(@sync_method.nil? || @sync_method == UNSET_VALUE))
|
368
|
+
end
|
369
|
+
|
370
|
+
if @use_legacy_synced_folders
|
371
|
+
# Original defaults.
|
372
|
+
@rsync_includes = nil if @rsync_includes.empty?
|
373
|
+
@rsync_ignore_files = nil if @rsync_ignore_files.empty?
|
374
|
+
@sync_method = 'rsync' if @sync_method == UNSET_VALUE
|
375
|
+
else
|
376
|
+
# Disable all sync settings.
|
377
|
+
@rsync_includes = nil
|
378
|
+
@rsync_ignore_files = nil
|
379
|
+
@sync_method = nil
|
380
|
+
end
|
381
|
+
|
317
382
|
# The SSH values by default are nil, and the top-level config
|
318
383
|
# `config.ssh` and `config.vm.boot_timeout` values are used.
|
319
384
|
@ssh_username = nil if @ssh_username == UNSET_VALUE
|
@@ -331,8 +396,10 @@ module VagrantPlugins
|
|
331
396
|
@stacks = nil if @stacks.empty?
|
332
397
|
@http.finalize!
|
333
398
|
end
|
334
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
399
|
+
# rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
335
400
|
|
401
|
+
#
|
402
|
+
# @deprecated Use standard Vagrant synced folders instead.
|
336
403
|
def rsync_include(inc)
|
337
404
|
@rsync_includes << inc
|
338
405
|
end
|
@@ -342,9 +409,9 @@ module VagrantPlugins
|
|
342
409
|
|
343
410
|
errors << I18n.t('vagrant_openstack.config.password_required') if @password.nil? || @password.empty?
|
344
411
|
errors << I18n.t('vagrant_openstack.config.username_required') if @username.nil? || @username.empty?
|
345
|
-
errors << I18n.t('vagrant_openstack.config.
|
346
|
-
errors << I18n.t('vagrant_openstack.config.invalid_endpoint_type') unless %w(publicURL adminURL internalURL).include?(@endpoint_type)
|
412
|
+
errors << I18n.t('vagrant_openstack.config.invalid_api_version') unless %w(2 3).include?(@identity_api_version)
|
347
413
|
|
414
|
+
validate_api_version(errors)
|
348
415
|
validate_ssh_username(machine, errors)
|
349
416
|
validate_stack_config(errors)
|
350
417
|
validate_ssh_timeout(errors)
|
@@ -371,6 +438,17 @@ module VagrantPlugins
|
|
371
438
|
|
372
439
|
private
|
373
440
|
|
441
|
+
def validate_api_version(errors)
|
442
|
+
if @identity_api_version == '2'
|
443
|
+
errors << I18n.t('vagrant_openstack.config.tenant_name_required') if @tenant_name.nil? || @tenant_name.empty?
|
444
|
+
errors << I18n.t('vagrant_openstack.config.invalid_endpoint_type') unless %w(publicURL adminURL internalURL).include?(@endpoint_type)
|
445
|
+
elsif @identity_api_version == '3'
|
446
|
+
errors << I18n.t('vagrant_openstack.config.domain_required') if @domain_name.nil? || @domain_name.empty?
|
447
|
+
errors << I18n.t('vagrant_openstack.config.project_name_required') if @project_name.nil? || @project_name.empty?
|
448
|
+
errors << I18n.t('vagrant_openstack.config.invalid_interface_type') unless %w(public admin internal).include?(@interface_type)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
374
452
|
def validate_stack_config(errors)
|
375
453
|
@stacks.each do |stack|
|
376
454
|
errors << I18n.t('vagrant_openstack.config.invalid_stack') unless stack[:name] && stack[:template]
|
@@ -16,7 +16,12 @@ module VagrantPlugins
|
|
16
16
|
if addresses.size == 1
|
17
17
|
net_addresses = addresses.first[1]
|
18
18
|
else
|
19
|
-
|
19
|
+
first_network = env[:machine].provider_config.networks[0]
|
20
|
+
if first_network.is_a? String
|
21
|
+
net_addresses = addresses[first_network]
|
22
|
+
else
|
23
|
+
net_addresses = addresses[first_network[:name]]
|
24
|
+
end
|
20
25
|
end
|
21
26
|
fail Errors::UnableToResolveIP if net_addresses.size == 0
|
22
27
|
net_addresses[0]['addr']
|
data/locales/en.yml
CHANGED
@@ -138,6 +138,19 @@ en:
|
|
138
138
|
to the standard vagrant configuration option `config.vm.boot_timeout`.
|
139
139
|
invalid_value_for_parameter: |-
|
140
140
|
Invalid value '%{value}' for parameter '%{parameter}'
|
141
|
+
sync_folders_deprecated: |-
|
142
|
+
The following configuration settings are deprecated and should be
|
143
|
+
removed: rsync_includes, rsync_ignore_files, sync_method. Using these
|
144
|
+
settings causes the OpenStack provider to fall back to an old synced
|
145
|
+
folder implementation instead of using standard Vagrant synced folders.
|
146
|
+
domain_required: |-
|
147
|
+
A domain is required when using identity API version 3
|
148
|
+
project_name_required: |-
|
149
|
+
A project name is required when using identity API version 3
|
150
|
+
invalid_interface_type: |-
|
151
|
+
Interface type must be public, admin or internal (if not provided, default is public)
|
152
|
+
invalid_api_version: |-
|
153
|
+
identity API verison must be 2 or 3 (if nto provided, default is 2)
|
141
154
|
|
142
155
|
errors:
|
143
156
|
default: |-
|
@@ -18,10 +18,13 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
18
18
|
config.stub(:openstack_volume_url) { nil }
|
19
19
|
config.stub(:openstack_image_url) { nil }
|
20
20
|
config.stub(:tenant_name) { 'testTenant' }
|
21
|
+
config.stub(:project_name) { 'testTenant' }
|
21
22
|
config.stub(:username) { 'username' }
|
22
23
|
config.stub(:password) { 'password' }
|
23
24
|
config.stub(:region) { nil }
|
24
25
|
config.stub(:endpoint_type) { 'publicURL' }
|
26
|
+
config.stub(:interface_type) { 'public' }
|
27
|
+
config.stub(:identity_api_version) { '2' }
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -243,6 +246,78 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
243
246
|
end
|
244
247
|
end
|
245
248
|
|
249
|
+
context 'with one endpoint by service v3' do
|
250
|
+
it 'read service catalog and stores endpoints URL in session v3' do
|
251
|
+
catalog = [
|
252
|
+
{
|
253
|
+
'endpoints' => [
|
254
|
+
{
|
255
|
+
'url' => 'http://nova/v2/projectId',
|
256
|
+
'interface' => 'public',
|
257
|
+
'region' => 'RegionOne',
|
258
|
+
'id' => '1'
|
259
|
+
}
|
260
|
+
],
|
261
|
+
'type' => 'compute',
|
262
|
+
'name' => 'nova'
|
263
|
+
},
|
264
|
+
{
|
265
|
+
'endpoints' => [
|
266
|
+
{
|
267
|
+
'url' => 'http://neutron',
|
268
|
+
'interface' => 'public',
|
269
|
+
'region' => 'RegionOne',
|
270
|
+
'id' => '2'
|
271
|
+
}
|
272
|
+
],
|
273
|
+
'type' => 'network',
|
274
|
+
'name' => 'neutron'
|
275
|
+
},
|
276
|
+
{
|
277
|
+
'endpoints' => [
|
278
|
+
{
|
279
|
+
'url' => 'http://cinder/v2/projectId',
|
280
|
+
'interface' => 'public',
|
281
|
+
'region' => 'RegionOne',
|
282
|
+
'id' => '2'
|
283
|
+
}
|
284
|
+
],
|
285
|
+
'type' => 'volume',
|
286
|
+
'name' => 'cinder'
|
287
|
+
},
|
288
|
+
{
|
289
|
+
'endpoints' => [
|
290
|
+
{
|
291
|
+
'url' => 'http://glance',
|
292
|
+
'interface' => 'public',
|
293
|
+
'region' => 'RegionOne',
|
294
|
+
'id' => '2'
|
295
|
+
}
|
296
|
+
],
|
297
|
+
'type' => 'image',
|
298
|
+
'name' => 'glance'
|
299
|
+
}
|
300
|
+
]
|
301
|
+
|
302
|
+
double.tap do |keystone|
|
303
|
+
keystone.stub(:authenticate).with(anything) { catalog }
|
304
|
+
env[:openstack_client].stub(:keystone) { keystone }
|
305
|
+
end
|
306
|
+
env[:openstack_client].stub(:neutron) { neutron }
|
307
|
+
env[:openstack_client].stub(:glance) { glance }
|
308
|
+
config.stub(:domain_name) { 'dummy' }
|
309
|
+
config.stub(:identity_api_version) { '3' }
|
310
|
+
|
311
|
+
@action.call(env)
|
312
|
+
|
313
|
+
expect(env[:openstack_client].session.endpoints)
|
314
|
+
.to eq(compute: 'http://nova/v2/projectId',
|
315
|
+
network: 'http://neutron/v2.0',
|
316
|
+
volume: 'http://cinder/v2/projectId',
|
317
|
+
image: 'http://glance/v2.0')
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
246
321
|
context 'with multiple regions' do
|
247
322
|
it 'read service catalog and stores endpoints URL for desired regions in session' do
|
248
323
|
catalog = [
|
@@ -17,6 +17,9 @@ describe VagrantPlugins::Openstack::KeystoneClient do
|
|
17
17
|
config.stub(:username) { 'username' }
|
18
18
|
config.stub(:password) { 'password' }
|
19
19
|
config.stub(:http) { http }
|
20
|
+
config.stub(:interface_type) { 'public' }
|
21
|
+
config.stub(:identity_api_version) { '2' }
|
22
|
+
config.stub(:project_name) { 'testTenant' }
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
@@ -52,6 +55,29 @@ describe VagrantPlugins::Openstack::KeystoneClient do
|
|
52
55
|
]}}'
|
53
56
|
end
|
54
57
|
|
58
|
+
let(:keystone_response_headers_v3) do
|
59
|
+
{
|
60
|
+
'Accept' => 'application/json',
|
61
|
+
'Content-Type' => 'application/json',
|
62
|
+
'x_subject_token' => '0123456789'
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:keystone_request_body_v3) do
|
67
|
+
'{"auth":{"identity":{"methods":["password"],"password":{"user":{"name":"username","domain":'\
|
68
|
+
'{"name":"dummy"},"password":"password"}}},"scope":{"project":{"name":"testTenant","domain":'\
|
69
|
+
'{"name":"dummy"}}}}}'
|
70
|
+
end
|
71
|
+
|
72
|
+
let(:keystone_response_body_v3) do
|
73
|
+
'{"token":{"is_domain":false,"methods":["password"],"roles":[{"id":"1234","name":"_member_"}],
|
74
|
+
"is_admin_project":false,"project":{"domain":{"id":"1234","name":"dummy"},"id":"012345678910",
|
75
|
+
"name":"testTenantId"},"catalog":[
|
76
|
+
{"endpoints":[{"id":"eid1","interface":"public","url":"http://nova"}],"type":"compute"},
|
77
|
+
{"endpoints":[{"id":"eid2","interface":"public","url":"http://neutron"}],"type":"network"}
|
78
|
+
]}}'
|
79
|
+
end
|
80
|
+
|
55
81
|
before :each do
|
56
82
|
@keystone_client = VagrantPlugins::Openstack.keystone
|
57
83
|
end
|
@@ -146,5 +172,53 @@ describe VagrantPlugins::Openstack::KeystoneClient do
|
|
146
172
|
end
|
147
173
|
end
|
148
174
|
end
|
175
|
+
|
176
|
+
# V3
|
177
|
+
context 'with good credentials v3' do
|
178
|
+
it 'store token and tenant id' do
|
179
|
+
config.stub(:domain_name) { 'dummy' }
|
180
|
+
config.stub(:identity_api_version) { '3' }
|
181
|
+
config.stub(:openstack_auth_url) { 'http://keystoneAuthV3' }
|
182
|
+
|
183
|
+
stub_request(:post, 'http://keystoneAuthV3/auth/tokens')
|
184
|
+
.with(
|
185
|
+
body: keystone_request_body_v3,
|
186
|
+
headers: keystone_request_headers)
|
187
|
+
.to_return(
|
188
|
+
status: 200,
|
189
|
+
body: keystone_response_body_v3,
|
190
|
+
headers: keystone_response_headers_v3)
|
191
|
+
|
192
|
+
@keystone_client.authenticate(env)
|
193
|
+
|
194
|
+
session.token.should eq('0123456789')
|
195
|
+
session.project_id.should eq('012345678910')
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'with wrong credentials v3' do
|
200
|
+
it 'raise an unauthorized error ' do
|
201
|
+
config.stub(:domain_name) { 'dummy' }
|
202
|
+
config.stub(:identity_api_version) { '3' }
|
203
|
+
config.stub(:openstack_auth_url) { 'http://keystoneAuthV3' }
|
204
|
+
|
205
|
+
stub_request(:post, 'http://keystoneAuthV3/auth/tokens')
|
206
|
+
.with(
|
207
|
+
body: keystone_request_body_v3,
|
208
|
+
headers: keystone_request_headers)
|
209
|
+
.to_return(
|
210
|
+
status: 401,
|
211
|
+
body: '{
|
212
|
+
"error": {
|
213
|
+
"message": "The request you have made requires authentication.",
|
214
|
+
"code": 401,
|
215
|
+
"title": "Unauthorized"
|
216
|
+
}
|
217
|
+
}',
|
218
|
+
headers: keystone_response_headers_v3)
|
219
|
+
|
220
|
+
expect { @keystone_client.authenticate(env) }.to raise_error(Errors::AuthenticationFailed)
|
221
|
+
end
|
222
|
+
end
|
149
223
|
end
|
150
224
|
end
|
@@ -16,7 +16,10 @@ describe VagrantPlugins::Openstack::Config do
|
|
16
16
|
its(:image) { should be_nil }
|
17
17
|
its(:server_name) { should be_nil }
|
18
18
|
its(:username) { should be_nil }
|
19
|
+
its(:use_legacy_synced_folders) { should eq(false) }
|
19
20
|
its(:rsync_includes) { should be_nil }
|
21
|
+
its(:rsync_ignore_files) { should be_nil }
|
22
|
+
its(:sync_method) { should be_nil }
|
20
23
|
its(:keypair_name) { should be_nil }
|
21
24
|
its(:public_key_path) { should be_nil }
|
22
25
|
its(:availability_zone) { should be_nil }
|
@@ -55,11 +58,36 @@ describe VagrantPlugins::Openstack::Config do
|
|
55
58
|
end
|
56
59
|
end
|
57
60
|
|
61
|
+
describe 'use_legacy_synced_folders' do
|
62
|
+
it 'should default to true if sync_method is set' do
|
63
|
+
subject.sync_method = 'rsync'
|
64
|
+
subject.finalize!
|
65
|
+
|
66
|
+
expect(subject.use_legacy_synced_folders).to eq(true)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should default to true if rsync_includes is non-empty' do
|
70
|
+
subject.rsync_includes = ['some/file']
|
71
|
+
subject.finalize!
|
72
|
+
|
73
|
+
expect(subject.use_legacy_synced_folders).to eq(true)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should default to true if rsync_ignore_files is non-empty' do
|
77
|
+
subject.rsync_ignore_files = ['some/file']
|
78
|
+
subject.finalize!
|
79
|
+
|
80
|
+
expect(subject.use_legacy_synced_folders).to eq(true)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
58
84
|
it 'should not default rsync_includes if overridden' do
|
59
85
|
inc = 'core'
|
60
86
|
subject.send(:rsync_include, inc)
|
61
87
|
subject.finalize!
|
62
|
-
|
88
|
+
|
89
|
+
expect(subject.rsync_includes).to include(inc)
|
90
|
+
expect(subject.use_legacy_synced_folders).to eq(true)
|
63
91
|
end
|
64
92
|
end
|
65
93
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-openstack-provider
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Giamarchi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|