vagrant-openstack-provider 0.2.0 → 0.3.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 +8 -8
- data/Appraisals +6 -6
- data/CHANGELOG.md +44 -1
- data/Gemfile +10 -6
- data/Vagrantfile +7 -15
- data/functional_tests/Vagrantfile +58 -0
- data/functional_tests/keys/vagrant-openstack +27 -0
- data/functional_tests/keys/vagrant-openstack.pub +1 -0
- data/functional_tests/run_tests.sh +142 -0
- data/gemfiles/latest_stable.gemfile +5 -0
- data/gemfiles/oldest_current.gemfile +5 -0
- data/gemfiles/previous_release.gemfile +5 -0
- data/lib/vagrant-openstack-provider/action.rb +17 -2
- data/lib/vagrant-openstack-provider/action/connect_openstack.rb +60 -8
- data/lib/vagrant-openstack-provider/action/create_server.rb +131 -43
- data/lib/vagrant-openstack-provider/action/delete_server.rb +2 -0
- data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +22 -3
- data/lib/vagrant-openstack-provider/action/resume.rb +2 -0
- data/lib/vagrant-openstack-provider/action/stop_server.rb +1 -0
- data/lib/vagrant-openstack-provider/action/suspend.rb +2 -0
- data/lib/vagrant-openstack-provider/action/sync_folders.rb +3 -2
- data/lib/vagrant-openstack-provider/action/wait_active.rb +29 -0
- data/lib/vagrant-openstack-provider/action/wait_stop.rb +1 -1
- data/lib/vagrant-openstack-provider/client/domain.rb +26 -0
- data/lib/vagrant-openstack-provider/client/http_utils.rb +96 -0
- data/lib/vagrant-openstack-provider/client/keystone.rb +30 -41
- data/lib/vagrant-openstack-provider/client/neutron.rb +24 -11
- data/lib/vagrant-openstack-provider/client/nova.rb +99 -104
- data/lib/vagrant-openstack-provider/client/openstack.rb +4 -0
- data/lib/vagrant-openstack-provider/client/request_logger.rb +24 -0
- data/lib/vagrant-openstack-provider/command/abstract_command.rb +31 -0
- data/lib/vagrant-openstack-provider/command/flavor_list.rb +21 -0
- data/lib/vagrant-openstack-provider/command/floatingip_list.rb +34 -0
- data/lib/vagrant-openstack-provider/command/image_list.rb +21 -0
- data/lib/vagrant-openstack-provider/command/main.rb +51 -0
- data/lib/vagrant-openstack-provider/command/network_list.rb +21 -0
- data/lib/vagrant-openstack-provider/command/utils.rb +22 -0
- data/lib/vagrant-openstack-provider/config.rb +31 -3
- data/lib/vagrant-openstack-provider/errors.rb +28 -0
- data/lib/vagrant-openstack-provider/plugin.rb +5 -0
- data/lib/vagrant-openstack-provider/version.rb +1 -1
- data/locales/en.yml +45 -1
- data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +190 -0
- data/spec/vagrant-openstack-provider/action/create_server_spec.rb +166 -1
- data/spec/vagrant-openstack-provider/action/read_ssh_info_spec.rb +109 -0
- data/spec/vagrant-openstack-provider/client/keystone_spec.rb +32 -48
- data/spec/vagrant-openstack-provider/client/neutron_spec.rb +42 -4
- data/spec/vagrant-openstack-provider/client/nova_spec.rb +247 -6
- data/spec/vagrant-openstack-provider/client/utils_spec.rb +58 -5
- data/spec/vagrant-openstack-provider/command/floatingip_list_spec.rb +67 -0
- data/spec/vagrant-openstack-provider/config_spec.rb +21 -6
- data/spec/vagrant-openstack-provider/spec_helper.rb +7 -0
- data/{numergyrc → stackrc} +4 -1
- metadata +24 -4
- data/lib/vagrant-openstack-provider/client/utils.rb +0 -38
@@ -4,10 +4,12 @@ module VagrantPlugins
|
|
4
4
|
class Resume
|
5
5
|
def initialize(app, _env)
|
6
6
|
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::resume_server')
|
7
8
|
end
|
8
9
|
|
9
10
|
def call(env)
|
10
11
|
if env[:machine].id
|
12
|
+
@logger.info "Resuming suspended VM #{env[:machine].id}..."
|
11
13
|
env[:ui].info I18n.t('vagrant.actions.vm.resume.resuming')
|
12
14
|
env[:openstack_client].nova.resume_server(env, env[:machine].id)
|
13
15
|
end
|
@@ -4,10 +4,12 @@ module VagrantPlugins
|
|
4
4
|
class Suspend
|
5
5
|
def initialize(app, _env)
|
6
6
|
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::suspend_server')
|
7
8
|
end
|
8
9
|
|
9
10
|
def call(env)
|
10
11
|
if env[:machine].id
|
12
|
+
@logger.info "Saving VM #{env[:machine].id} state and suspending execution..."
|
11
13
|
env[:ui].info I18n.t('vagrant.actions.vm.suspend.suspending')
|
12
14
|
env[:openstack_client].nova.suspend_server(env, env[:machine].id)
|
13
15
|
end
|
@@ -97,8 +97,9 @@ module VagrantPlugins
|
|
97
97
|
command += ['--exclude-from', abs_ignore_file] if File.exist?(abs_ignore_file)
|
98
98
|
end
|
99
99
|
|
100
|
-
|
101
|
-
|
100
|
+
r = Vagrant::Util::Subprocess.execute(*command)
|
101
|
+
next if r.exit_code == 0
|
102
|
+
fail Errors::RsyncError, guestpath: guestpath, hostpath: hostpath, stderr: r.stderr
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Openstack
|
6
|
+
module Action
|
7
|
+
class WaitForServerToBeActive
|
8
|
+
def initialize(app, _env)
|
9
|
+
@app = app
|
10
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
if env[:machine].id
|
15
|
+
env[:ui].info(I18n.t('vagrant_openstack.waiting_start'))
|
16
|
+
client = env[:openstack_client].nova
|
17
|
+
timeout(200) do
|
18
|
+
while client.get_server_details(env, env[:machine].id)['status'] != 'ACTIVE'
|
19
|
+
sleep 3
|
20
|
+
@logger.info('Waiting for server to be active')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
@app.call(env)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'restclient'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Openstack
|
7
|
+
module Domain
|
8
|
+
class Item
|
9
|
+
attr_accessor :id, :name
|
10
|
+
def initialize(id, name)
|
11
|
+
@id = id
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class FloatingIP
|
17
|
+
attr_accessor :ip, :pool, :instance_id
|
18
|
+
def initialize(ip, pool, instance_id)
|
19
|
+
@ip = ip
|
20
|
+
@pool = pool
|
21
|
+
@instance_id = instance_id
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'restclient'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'vagrant-openstack-provider/client/keystone'
|
6
|
+
require 'vagrant-openstack-provider/client/request_logger'
|
7
|
+
|
8
|
+
module VagrantPlugins
|
9
|
+
module Openstack
|
10
|
+
module HttpUtils
|
11
|
+
include VagrantPlugins::Openstack::HttpUtils::RequestLogger
|
12
|
+
|
13
|
+
def get(env, url, headers = {})
|
14
|
+
calling_method = caller[0][/`.*'/][1..-2]
|
15
|
+
@logger.debug("#{calling_method} - start")
|
16
|
+
|
17
|
+
headers.merge!('X-Auth-Token' => @session.token, :accept => :json)
|
18
|
+
|
19
|
+
log_request(:GET, url, headers)
|
20
|
+
|
21
|
+
authenticated(env) do
|
22
|
+
RestClient.get(url, headers) { |res| handle_response(res) }.tap do
|
23
|
+
@logger.debug("#{calling_method} - end")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def post(env, url, body = nil, headers = {})
|
29
|
+
calling_method = caller[0][/`.*'/][1..-2]
|
30
|
+
@logger.debug("#{calling_method} - start")
|
31
|
+
|
32
|
+
headers.merge!('X-Auth-Token' => @session.token, :accept => :json, :content_type => :json)
|
33
|
+
|
34
|
+
log_request(:POST, url, body, headers)
|
35
|
+
|
36
|
+
authenticated(env) do
|
37
|
+
RestClient.post(url, body, headers) { |res| handle_response(res) }.tap do
|
38
|
+
@logger.debug("#{calling_method} - end")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(env, url, headers = {})
|
44
|
+
calling_method = caller[0][/`.*'/][1..-2]
|
45
|
+
@logger.debug("#{calling_method} - start")
|
46
|
+
|
47
|
+
headers.merge!('X-Auth-Token' => @session.token, :accept => :json, :content_type => :json)
|
48
|
+
|
49
|
+
log_request(:DELETE, url, headers)
|
50
|
+
|
51
|
+
authenticated(env) do
|
52
|
+
RestClient.delete(url, headers) { |res| handle_response(res) }.tap do
|
53
|
+
@logger.debug("#{calling_method} - end")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
ERRORS =
|
61
|
+
{
|
62
|
+
'400' => 'badRequest',
|
63
|
+
'404' => 'itemNotFound',
|
64
|
+
'409' => 'conflictingRequest'
|
65
|
+
}
|
66
|
+
|
67
|
+
def handle_response(response)
|
68
|
+
log_response(response)
|
69
|
+
case response.code
|
70
|
+
when 200, 201, 202, 204
|
71
|
+
response
|
72
|
+
when 401
|
73
|
+
fail Errors::AuthenticationRequired
|
74
|
+
when 400, 404, 409
|
75
|
+
fail Errors::VagrantOpenstackError, message: JSON.parse(response.to_s)[ERRORS[response.code.to_s]]['message']
|
76
|
+
else
|
77
|
+
fail Errors::VagrantOpenstackError, message: response.to_s
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def authenticated(env)
|
82
|
+
nb_retry = 0
|
83
|
+
begin
|
84
|
+
return yield
|
85
|
+
rescue Errors::AuthenticationRequired => e
|
86
|
+
nb_retry += 1
|
87
|
+
env[:ui].warn(e)
|
88
|
+
env[:ui].warn(I18n.t('vagrant_openstack.trying_authentication'))
|
89
|
+
env[:openstack_client].keystone.authenticate(env)
|
90
|
+
retry if nb_retry < 3
|
91
|
+
raise e
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -2,10 +2,13 @@ require 'log4r'
|
|
2
2
|
require 'restclient'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
+
require 'vagrant-openstack-provider/client/request_logger'
|
6
|
+
|
5
7
|
module VagrantPlugins
|
6
8
|
module Openstack
|
7
9
|
class KeystoneClient
|
8
10
|
include Singleton
|
11
|
+
include VagrantPlugins::Openstack::HttpUtils::RequestLogger
|
9
12
|
|
10
13
|
def initialize
|
11
14
|
@logger = Log4r::Logger.new('vagrant_openstack::keystone')
|
@@ -13,63 +16,49 @@ module VagrantPlugins
|
|
13
16
|
end
|
14
17
|
|
15
18
|
def authenticate(env)
|
16
|
-
@logger.
|
19
|
+
@logger.info('Authenticating on Keystone')
|
17
20
|
config = env[:machine].provider_config
|
18
|
-
|
21
|
+
@logger.info(I18n.t('vagrant_openstack.client.authentication', project: config.tenant_name, user: config.username))
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
auth:
|
23
|
+
post_body =
|
24
|
+
{
|
25
|
+
auth:
|
24
26
|
{
|
25
27
|
tenantName: config.tenant_name,
|
26
28
|
passwordCredentials:
|
27
29
|
{
|
28
30
|
username: config.username,
|
29
|
-
password:
|
31
|
+
password: '****'
|
30
32
|
}
|
31
33
|
}
|
32
|
-
|
33
|
-
content_type: :json,
|
34
|
-
accept: :json)
|
35
|
-
|
36
|
-
access = JSON.parse(authentication)['access']
|
37
|
-
|
38
|
-
read_endpoint_catalog(env, access['serviceCatalog'])
|
39
|
-
override_endpoint_catalog_with_user_config(env)
|
40
|
-
print_endpoint_catalog(env)
|
41
|
-
|
42
|
-
response_token = access['token']
|
43
|
-
@session.token = response_token['id']
|
44
|
-
@session.project_id = response_token['tenant']['id']
|
45
|
-
end
|
34
|
+
}
|
46
35
|
|
47
|
-
|
36
|
+
log_request(:POST, config.openstack_auth_url, post_body.to_json)
|
48
37
|
|
49
|
-
|
50
|
-
env[:ui].info(I18n.t('vagrant_openstack.client.looking_for_available_endpoints'))
|
38
|
+
post_body[:auth][:passwordCredentials][:password] = config.password
|
51
39
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
40
|
+
authentication = RestClient.post(config.openstack_auth_url, post_body.to_json,
|
41
|
+
content_type: :json,
|
42
|
+
accept: :json) do |response|
|
43
|
+
log_response(response)
|
44
|
+
case response.code
|
45
|
+
when 200
|
46
|
+
response
|
47
|
+
when 401
|
48
|
+
fail Errors::AuthenticationFailed
|
49
|
+
when 404
|
50
|
+
fail Errors::BadAuthenticationEndpoint
|
51
|
+
else
|
52
|
+
fail Errors::VagrantOpenstackError, message: response.to_s
|
57
53
|
end
|
58
|
-
url = se[0]['publicURL'].strip
|
59
|
-
@session.endpoints[service['type'].to_sym] = url unless url.empty?
|
60
54
|
end
|
61
|
-
end
|
62
55
|
|
63
|
-
|
64
|
-
|
65
|
-
@session.
|
66
|
-
@session.
|
67
|
-
end
|
56
|
+
access = JSON.parse(authentication)['access']
|
57
|
+
response_token = access['token']
|
58
|
+
@session.token = response_token['id']
|
59
|
+
@session.project_id = response_token['tenant']['id']
|
68
60
|
|
69
|
-
|
70
|
-
@session.endpoints.each do |key, value|
|
71
|
-
env[:ui].info(" -- #{key.to_s.ljust 15}: #{value}")
|
72
|
-
end
|
61
|
+
access['serviceCatalog']
|
73
62
|
end
|
74
63
|
end
|
75
64
|
end
|
@@ -2,30 +2,43 @@ require 'log4r'
|
|
2
2
|
require 'restclient'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
-
require 'vagrant-openstack-provider/client/
|
5
|
+
require 'vagrant-openstack-provider/client/http_utils'
|
6
|
+
require 'vagrant-openstack-provider/client/domain'
|
6
7
|
|
7
8
|
module VagrantPlugins
|
8
9
|
module Openstack
|
9
10
|
class NeutronClient
|
10
11
|
include Singleton
|
11
|
-
include VagrantPlugins::Openstack::
|
12
|
+
include VagrantPlugins::Openstack::HttpUtils
|
13
|
+
include VagrantPlugins::Openstack::Domain
|
12
14
|
|
13
15
|
def initialize
|
14
16
|
@logger = Log4r::Logger.new('vagrant_openstack::neutron')
|
15
17
|
@session = VagrantPlugins::Openstack.session
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
def get_api_version_list(_env)
|
21
|
+
json = RestClient.get(@session.endpoints[:network], 'X-Auth-Token' => @session.token, :accept => :json) do |response|
|
22
|
+
log_response(response)
|
23
|
+
case response.code
|
24
|
+
when 200, 300
|
25
|
+
response
|
26
|
+
when 401
|
27
|
+
fail Errors::AuthenticationFailed
|
28
|
+
else
|
29
|
+
fail Errors::VagrantOpenstackError, message: response.to_s
|
26
30
|
end
|
27
|
-
networks
|
28
31
|
end
|
32
|
+
JSON.parse(json)['versions']
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_private_networks(env)
|
36
|
+
networks_json = get(env, "#{@session.endpoints[:network]}/networks")
|
37
|
+
networks = []
|
38
|
+
JSON.parse(networks_json)['networks'].each do |n|
|
39
|
+
networks << Item.new(n['id'], n['name']) if n['tenant_id'].eql? @session.project_id
|
40
|
+
end
|
41
|
+
networks
|
29
42
|
end
|
30
43
|
end
|
31
44
|
end
|
@@ -2,13 +2,15 @@ require 'log4r'
|
|
2
2
|
require 'restclient'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
-
require 'vagrant-openstack-provider/client/
|
5
|
+
require 'vagrant-openstack-provider/client/http_utils'
|
6
|
+
require 'vagrant-openstack-provider/client/domain'
|
6
7
|
|
7
8
|
module VagrantPlugins
|
8
9
|
module Openstack
|
9
10
|
class NovaClient
|
10
11
|
include Singleton
|
11
|
-
include VagrantPlugins::Openstack::
|
12
|
+
include VagrantPlugins::Openstack::HttpUtils
|
13
|
+
include VagrantPlugins::Openstack::Domain
|
12
14
|
|
13
15
|
def initialize
|
14
16
|
@logger = Log4r::Logger.new('vagrant_openstack::nova')
|
@@ -16,135 +18,136 @@ module VagrantPlugins
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def get_all_flavors(env)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
:accept => :json) { |res| handle_response(res) }
|
21
|
+
flavors_json = get(env, "#{@session.endpoints[:compute]}/flavors")
|
22
|
+
JSON.parse(flavors_json)['flavors'].map { |fl| Item.new(fl['id'], fl['name']) }
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
def get_all_floating_ips(env)
|
26
|
+
ips_json = get(env, "#{@session.endpoints[:compute]}/os-floating-ips",
|
27
|
+
'X-Auth-Token' => @session.token,
|
28
|
+
:accept => :json) { |res| handle_response(res) }
|
29
|
+
JSON.parse(ips_json)['floating_ips'].map { |n| FloatingIP.new(n['ip'], n['pool'], n['instance_id']) }
|
26
30
|
end
|
27
31
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
def allocate_floating_ip(env, pool)
|
33
|
+
ips_json = post(env, "#{@session.endpoints[:compute]}/os-floating-ips",
|
34
|
+
{
|
35
|
+
pool: pool
|
36
|
+
}.to_json,
|
37
|
+
'X-Auth-Token' => @session.token,
|
38
|
+
:accept => :json,
|
39
|
+
:content_type => :json) { |res| handle_response(res) }
|
40
|
+
floating_ip = JSON.parse(ips_json)['floating_ip']
|
41
|
+
FloatingIP.new(floating_ip['ip'], floating_ip['pool'], floating_ip['instance_id'])
|
42
|
+
end
|
33
43
|
|
34
|
-
|
35
|
-
|
44
|
+
def get_all_images(env)
|
45
|
+
images_json = get(env, "#{@session.endpoints[:compute]}/images")
|
46
|
+
JSON.parse(images_json)['images'].map { |fl| Item.new(fl['id'], fl['name']) }
|
36
47
|
end
|
37
48
|
|
38
|
-
def create_server(env,
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
49
|
+
def create_server(env, options)
|
50
|
+
server = {}.tap do |s|
|
51
|
+
s['name'] = options[:name]
|
52
|
+
s['imageRef'] = options[:image_ref]
|
53
|
+
s['flavorRef'] = options[:flavor_ref]
|
54
|
+
s['key_name'] = options[:keypair]
|
55
|
+
s['availability_zone'] = options[:availability_zone] unless options[:availability_zone].nil?
|
56
|
+
unless options[:networks].nil? || options[:networks].empty?
|
57
|
+
s['networks'] = []
|
58
|
+
options[:networks].each do |uuid|
|
59
|
+
s['networks'] << { uuid: uuid }
|
50
60
|
end
|
51
61
|
end
|
52
|
-
|
53
|
-
server = RestClient.post(
|
54
|
-
"#{@session.endpoints[:compute]}/servers", { server: server }.to_json,
|
55
|
-
'X-Auth-Token' => @session.token,
|
56
|
-
:accept => :json,
|
57
|
-
:content_type => :json) { |res| handle_response(res) }
|
58
|
-
|
59
|
-
JSON.parse(server)['server']['id']
|
60
62
|
end
|
63
|
+
server = post(env, "#{@session.endpoints[:compute]}/servers", { server: server }.to_json)
|
64
|
+
JSON.parse(server)['server']['id']
|
61
65
|
end
|
62
66
|
|
63
67
|
def delete_server(env, server_id)
|
64
|
-
|
65
|
-
RestClient.delete(
|
66
|
-
"#{@session.endpoints[:compute]}/servers/#{server_id}",
|
67
|
-
'X-Auth-Token' => @session.token,
|
68
|
-
:accept => :json) { |res| handle_response(res) }
|
69
|
-
end
|
68
|
+
delete(env, "#{@session.endpoints[:compute]}/servers/#{server_id}")
|
70
69
|
end
|
71
70
|
|
72
71
|
def suspend_server(env, server_id)
|
73
|
-
|
74
|
-
RestClient.post(
|
75
|
-
"#{@session.endpoints[:compute]}/servers/#{server_id}/action", '{ "suspend": null }',
|
76
|
-
'X-Auth-Token' => @session.token,
|
77
|
-
:accept => :json,
|
78
|
-
:content_type => :json) { |res| handle_response(res) }
|
79
|
-
end
|
72
|
+
change_server_state(env, server_id, :suspend)
|
80
73
|
end
|
81
74
|
|
82
75
|
def resume_server(env, server_id)
|
83
76
|
# TODO(julienvey) check status before (if pause->unpause, if suspend->resume...)
|
84
|
-
|
85
|
-
RestClient.post(
|
86
|
-
"#{@session.endpoints[:compute]}/servers/#{server_id}/action", '{ "resume": null }',
|
87
|
-
'X-Auth-Token' => @session.token,
|
88
|
-
:accept => :json,
|
89
|
-
:content_type => :json) { |res| handle_response(res) }
|
90
|
-
end
|
77
|
+
change_server_state(env, server_id, :resume)
|
91
78
|
end
|
92
79
|
|
93
80
|
def stop_server(env, server_id)
|
94
|
-
|
95
|
-
RestClient.post(
|
96
|
-
"#{@session.endpoints[:compute]}/servers/#{server_id}/action", '{ "os-stop": null }',
|
97
|
-
'X-Auth-Token' => @session.token,
|
98
|
-
:accept => :json,
|
99
|
-
:content_type => :json) { |res| handle_response(res) }
|
100
|
-
end
|
81
|
+
change_server_state(env, server_id, :stop)
|
101
82
|
end
|
102
83
|
|
103
84
|
def start_server(env, server_id)
|
104
|
-
|
105
|
-
RestClient.post(
|
106
|
-
"#{@session.endpoints[:compute]}/servers/#{server_id}/action", '{ "os-start": null }',
|
107
|
-
'X-Auth-Token' => @session.token,
|
108
|
-
:accept => :json,
|
109
|
-
:content_type => :json) { |res| handle_response(res) }
|
110
|
-
end
|
85
|
+
change_server_state(env, server_id, :start)
|
111
86
|
end
|
112
87
|
|
113
88
|
def get_server_details(env, server_id)
|
114
|
-
|
115
|
-
|
116
|
-
"#{@session.endpoints[:compute]}/servers/#{server_id}",
|
117
|
-
'X-Auth-Token' => @session.token,
|
118
|
-
:accept => :json) { |res| handle_response(res) }
|
119
|
-
|
120
|
-
return JSON.parse(server_details)['server']
|
121
|
-
end
|
89
|
+
server_details = get(env, "#{@session.endpoints[:compute]}/servers/#{server_id}")
|
90
|
+
JSON.parse(server_details)['server']
|
122
91
|
end
|
123
92
|
|
124
93
|
def add_floating_ip(env, server_id, floating_ip)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
94
|
+
check_floating_ip(env, floating_ip)
|
95
|
+
|
96
|
+
post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
|
97
|
+
{ addFloatingIp: { address: floating_ip } }.to_json)
|
98
|
+
end
|
99
|
+
|
100
|
+
def import_keypair(env, public_key)
|
101
|
+
keyname = "vagrant-generated-#{Kernel.rand(36**8).to_s(36)}"
|
102
|
+
|
103
|
+
key_details = post(env, "#{@session.endpoints[:compute]}/os-keypairs",
|
104
|
+
{ keypair:
|
105
|
+
{
|
106
|
+
name: keyname,
|
107
|
+
public_key: public_key
|
108
|
+
}
|
109
|
+
}.to_json)
|
110
|
+
JSON.parse(key_details)['keypair']['name']
|
111
|
+
end
|
112
|
+
|
113
|
+
def import_keypair_from_file(env, public_key_path)
|
114
|
+
fail "File specified in public_key_path #{public_key_path} doesn't exist" unless File.exist?(public_key_path)
|
115
|
+
file = File.open(public_key_path)
|
116
|
+
import_keypair(env, file.read)
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_keypair_if_vagrant(env, server_id)
|
120
|
+
keyname = get_server_details(env, server_id)['key_name']
|
121
|
+
delete(env, "#{@session.endpoints[:compute]}/os-keypairs/#{keyname}") if keyname.start_with?('vagrant-generated-')
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_floating_ip_pools(env)
|
125
|
+
floating_ips = get(env, "#{@session.endpoints[:compute]}/os-floating-ip-pools")
|
126
|
+
JSON.parse(floating_ips)['floating_ip_pools']
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_floating_ips(env)
|
130
|
+
floating_ips = get(env, "#{@session.endpoints[:compute]}/os-floating-ips")
|
131
|
+
JSON.parse(floating_ips)['floating_ips']
|
139
132
|
end
|
140
133
|
|
141
134
|
private
|
142
135
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
136
|
+
VM_STATES =
|
137
|
+
{
|
138
|
+
suspend: 'suspend',
|
139
|
+
resume: 'resume',
|
140
|
+
start: 'os-start',
|
141
|
+
stop: 'os-stop'
|
142
|
+
}
|
143
|
+
|
144
|
+
def change_server_state(env, server_id, new_state)
|
145
|
+
post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
|
146
|
+
{ :"#{VM_STATES[new_state.to_sym]}" => nil }.to_json)
|
147
|
+
end
|
148
|
+
|
149
|
+
def check_floating_ip(env, floating_ip)
|
150
|
+
ip_details = get(env, "#{@session.endpoints[:compute]}/os-floating-ips")
|
148
151
|
|
149
152
|
JSON.parse(ip_details)['floating_ips'].each do |ip|
|
150
153
|
next unless ip['ip'] == floating_ip
|
@@ -154,13 +157,5 @@ module VagrantPlugins
|
|
154
157
|
fail "Floating IP #{floating_ip} not available for this tenant"
|
155
158
|
end
|
156
159
|
end
|
157
|
-
|
158
|
-
class Item
|
159
|
-
attr_accessor :id, :name
|
160
|
-
def initialize(id, name)
|
161
|
-
@id = id
|
162
|
-
@name = name
|
163
|
-
end
|
164
|
-
end
|
165
160
|
end
|
166
161
|
end
|