vagrant-openstack-provider 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|