vagrant-openstack-provider 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +13 -5
  2. data/.rubocop.yml +28 -0
  3. data/Appraisals +3 -3
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +3 -0
  6. data/Rakefile +6 -2
  7. data/Vagrantfile +4 -15
  8. data/gemfiles/latest_stable.gemfile +2 -0
  9. data/gemfiles/oldest_current.gemfile +2 -0
  10. data/gemfiles/previous_release.gemfile +2 -0
  11. data/lib/vagrant-openstack-provider.rb +18 -13
  12. data/lib/vagrant-openstack-provider/action.rb +112 -46
  13. data/lib/vagrant-openstack-provider/action/connect_openstack.rb +9 -10
  14. data/lib/vagrant-openstack-provider/action/create_server.rb +86 -57
  15. data/lib/vagrant-openstack-provider/action/delete_server.rb +5 -6
  16. data/lib/vagrant-openstack-provider/action/{is_created.rb → message.rb} +4 -3
  17. data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +7 -27
  18. data/lib/vagrant-openstack-provider/action/read_state.rb +7 -9
  19. data/lib/vagrant-openstack-provider/action/resume.rb +20 -0
  20. data/lib/vagrant-openstack-provider/action/start_server.rb +22 -0
  21. data/lib/vagrant-openstack-provider/action/stop_server.rb +22 -0
  22. data/lib/vagrant-openstack-provider/action/suspend.rb +20 -0
  23. data/lib/vagrant-openstack-provider/action/sync_folders.rb +27 -38
  24. data/lib/vagrant-openstack-provider/action/wait_stop.rb +29 -0
  25. data/lib/vagrant-openstack-provider/client/keystone.rb +76 -0
  26. data/lib/vagrant-openstack-provider/client/neutron.rb +32 -0
  27. data/lib/vagrant-openstack-provider/client/nova.rb +166 -0
  28. data/lib/vagrant-openstack-provider/client/openstack.rb +41 -0
  29. data/lib/vagrant-openstack-provider/client/utils.rb +38 -0
  30. data/lib/vagrant-openstack-provider/config.rb +38 -110
  31. data/lib/vagrant-openstack-provider/errors.rb +7 -3
  32. data/lib/vagrant-openstack-provider/plugin.rb +8 -8
  33. data/lib/vagrant-openstack-provider/provider.rb +6 -6
  34. data/lib/vagrant-openstack-provider/version.rb +1 -1
  35. data/locales/en.yml +83 -5
  36. data/numergyrc +22 -0
  37. data/spec/vagrant-openstack-provider/action/create_server_spec.rb +89 -0
  38. data/spec/vagrant-openstack-provider/client/keystone_spec.rb +140 -0
  39. data/spec/vagrant-openstack-provider/client/neutron_spec.rb +53 -0
  40. data/spec/vagrant-openstack-provider/client/nova_spec.rb +373 -0
  41. data/spec/vagrant-openstack-provider/client/utils_spec.rb +125 -0
  42. data/spec/vagrant-openstack-provider/config_spec.rb +117 -0
  43. data/spec/vagrant-openstack-provider/provider_spec.rb +13 -0
  44. data/spec/vagrant-openstack-provider/spec_helper.rb +23 -0
  45. data/vagrant-openstack-provider.gemspec +13 -14
  46. metadata +40 -30
  47. data/features/provision.feature +0 -35
  48. data/features/steps/sdk_steps.rb +0 -13
  49. data/features/steps/server_steps.rb +0 -25
  50. data/features/support/env.rb +0 -37
  51. data/features/support/fog_mock.rb +0 -19
  52. data/features/vagrant-openstack-provider.feature +0 -70
  53. data/lib/vagrant-openstack-provider/action/message_already_created.rb +0 -16
  54. data/lib/vagrant-openstack-provider/action/message_not_created.rb +0 -16
  55. data/lib/vagrant-openstack-provider/openstack_client.rb +0 -98
  56. data/spec/vagrant-openstack/config_spec.rb +0 -184
  57. data/stackrc +0 -31
@@ -1,7 +1,8 @@
1
- require "log4r"
2
- require "restclient"
3
- require "json"
4
- require_relative "../openstack_client"
1
+ require 'log4r'
2
+ require 'restclient'
3
+ require 'json'
4
+
5
+ require 'vagrant-openstack-provider/client/openstack'
5
6
 
6
7
  module VagrantPlugins
7
8
  module Openstack
@@ -10,17 +11,15 @@ module VagrantPlugins
10
11
  # puts the Openstack connection object into the `:openstack_compute` key
11
12
  # in the environment.
12
13
  class ConnectOpenstack
13
- def initialize(app, env)
14
+ def initialize(app, _env)
14
15
  @app = app
15
- @logger = Log4r::Logger.new("vagrant_openstack::action::connect_openstack")
16
+ @logger = Log4r::Logger.new('vagrant_openstack::action::connect_openstack')
16
17
  end
17
18
 
18
19
  def call(env)
19
- # Get the configs
20
- config = env[:machine].provider_config
21
- client = OpenstackClient::new()
20
+ client = VagrantPlugins::Openstack
22
21
  env[:openstack_client] = client
23
- client.authenticate(env)
22
+ client.keystone.authenticate(env) if client.session.token.nil?
24
23
  @app.call(env)
25
24
  end
26
25
  end
@@ -1,6 +1,6 @@
1
- require "log4r"
1
+ require 'log4r'
2
2
  require 'socket'
3
- require "timeout"
3
+ require 'timeout'
4
4
 
5
5
  require 'vagrant/util/retryable'
6
6
 
@@ -10,108 +10,137 @@ module VagrantPlugins
10
10
  class CreateServer
11
11
  include Vagrant::Util::Retryable
12
12
 
13
- def initialize(app, env)
13
+ def initialize(app, _env)
14
14
  @app = app
15
- @logger = Log4r::Logger.new("vagrant_openstack::action::create_server")
15
+ @logger = Log4r::Logger.new('vagrant_openstack::action::create_server')
16
16
  end
17
17
 
18
18
  def call(env)
19
19
  config = env[:machine].provider_config
20
- client = env[:openstack_client]
20
+ nova = env[:openstack_client].nova
21
21
 
22
- # Find the flavor
23
- env[:ui].info(I18n.t("vagrant_openstack.finding_flavor"))
24
- flavors = client.get_all_flavors(env)
25
- flavor = find_matching(flavors, config.flavor)
26
- raise Errors::NoMatchingFlavor if !flavor
27
-
28
- # Find the image
29
- env[:ui].info(I18n.t("vagrant_openstack.finding_image"))
30
- images = client.get_all_images(env)
31
- image = find_matching(images, config.image)
32
- raise Errors::NoMatchingImage if !image
33
-
34
- # Figure out the name for the server
22
+ flavor = resolve_flavor(env)
23
+ image = resolve_image(env)
24
+ networks = resolve_networks(env)
35
25
  server_name = config.server_name || env[:machine].name
36
26
 
37
- # Output the settings we're going to use to the user
38
- env[:ui].info(I18n.t("vagrant_openstack.launching_server"))
39
- env[:ui].info(" -- Flavor : #{flavor.name}")
40
- env[:ui].info(" -- FlavorRef : #{flavor.id}")
41
- env[:ui].info(" -- Image : #{image.name}")
42
- env[:ui].info(" -- KeyPair : #{config.keypair_name}")
43
- env[:ui].info(" -- ImageRef : #{image.id}")
44
- env[:ui].info(" -- Disk Config : #{config.disk_config}") if config.disk_config
45
- env[:ui].info(" -- Network : #{config.network}") if config.network
46
- env[:ui].info(" -- Tenant : #{config.tenant_name}")
47
- env[:ui].info(" -- Name : #{server_name}")
48
-
49
- #TODO(julienvey) add metadata
50
- #TODO(julienvey) add availability_zone
51
- #TODO(julienvey) add disk_config
52
-
53
- server_id = client.create_server(env, server_name, image.id, flavor.id, config.keypair_name)
54
-
55
- #TODO(julienvey) Find a network if provided
56
- #if config.network
57
- # network = find_matching(env[:openstack_network].networks, config.network)
58
- # options[:nics] = [{"net_id" => network.id}] if network
59
- #end
27
+ env[:ui].info(I18n.t('vagrant_openstack.launching_server'))
28
+ env[:ui].info(" -- Tenant : #{config.tenant_name}")
29
+ env[:ui].info(" -- Name : #{server_name}")
30
+ env[:ui].info(" -- Flavor : #{flavor.name}")
31
+ env[:ui].info(" -- FlavorRef : #{flavor.id}")
32
+ env[:ui].info(" -- Image : #{image.name}")
33
+ env[:ui].info(" -- ImageRef : #{image.id}")
34
+ env[:ui].info(" -- KeyPair : #{config.keypair_name}")
35
+ unless networks.empty?
36
+ if networks.size == 1
37
+ env[:ui].info(" -- Network : #{config.networks[0]}")
38
+ else
39
+ env[:ui].info(" -- Networks : #{config.networks}")
40
+ end
41
+ end
42
+
43
+ server_id = nova.create_server(env, server_name, image.id, flavor.id, networks, config.keypair_name)
60
44
 
61
45
  # Store the ID right away so we can track it
62
46
  env[:machine].id = server_id
63
47
 
64
48
  # Wait for the server to finish building
65
- env[:ui].info(I18n.t("vagrant_openstack.waiting_for_build"))
49
+ env[:ui].info(I18n.t('vagrant_openstack.waiting_for_build'))
66
50
  timeout(200) do
67
- while client.get_server_details(env, server_id)['status'] != 'ACTIVE' do
51
+ while nova.get_server_details(env, server_id)['status'] != 'ACTIVE'
68
52
  sleep 3
69
- @logger.debug("Waiting for server to be ACTIVE")
53
+ @logger.debug('Waiting for server to be ACTIVE')
70
54
  end
71
55
  end
72
56
 
73
57
  if config.floating_ip
74
58
  env[:ui].info("Using floating IP #{config.floating_ip}")
75
- client.add_floating_ip(env, server_id, config.floating_ip)
59
+ nova.add_floating_ip(env, server_id, config.floating_ip)
76
60
  end
77
61
 
78
- if !env[:interrupted]
62
+ unless env[:interrupted]
79
63
  # Clear the line one more time so the progress is removed
80
64
  env[:ui].clear_line
81
65
 
82
66
  # Wait for SSH to become available
83
67
  host = env[:machine].provider_config.floating_ip
84
68
  ssh_timeout = env[:machine].provider_config.ssh_timeout
85
- sleep 240
86
- if !port_open?(env, host, 22, ssh_timeout)
87
- env[:ui].error(I18n.t("vagrant_openstack.timeout"))
88
- raise Errors::SshUnavailable,
89
- :host => host,
90
- :timeout => ssh_timeout
69
+ unless port_open?(env, host, 22, ssh_timeout)
70
+ env[:ui].error(I18n.t('vagrant_openstack.timeout'))
71
+ fail Errors::SshUnavailable, host: host, timeout: ssh_timeout
91
72
  end
92
73
 
93
- env[:ui].info(I18n.t("vagrant_openstack.ready"))
74
+ env[:ui].info(I18n.t('vagrant_openstack.ready'))
94
75
  end
95
76
 
96
77
  @app.call(env)
97
78
  end
98
79
 
99
- protected
80
+ private
81
+
82
+ def resolve_flavor(env)
83
+ config = env[:machine].provider_config
84
+ nova = env[:openstack_client].nova
85
+ env[:ui].info(I18n.t('vagrant_openstack.finding_flavor'))
86
+ flavors = nova.get_all_flavors(env)
87
+ flavor = find_matching(flavors, config.flavor)
88
+ fail Errors::NoMatchingFlavor unless flavor
89
+ flavor
90
+ end
91
+
92
+ def resolve_image(env)
93
+ config = env[:machine].provider_config
94
+ nova = env[:openstack_client].nova
95
+ env[:ui].info(I18n.t('vagrant_openstack.finding_image'))
96
+ images = nova.get_all_images(env)
97
+ image = find_matching(images, config.image)
98
+ fail Errors::NoMatchingImage unless image
99
+ image
100
+ end
101
+
102
+ def resolve_networks(env)
103
+ config = env[:machine].provider_config
104
+ return [] if config.networks.nil? || config.networks.empty?
105
+ env[:ui].info(I18n.t('vagrant_openstack.finding_networks'))
106
+
107
+ private_networks = env[:openstack_client].neutron.get_private_networks(env)
108
+ private_network_ids = private_networks.map { |n| n[:id] }
109
+
110
+ networks = []
111
+ config.networks.each do |network|
112
+ if private_network_ids.include?(network)
113
+ networks << network
114
+ next
115
+ end
116
+ net_id = nil
117
+ private_networks.each do |n| # Bad algorithm complexity, but here we don't care...
118
+ next unless n[:name].eql? network
119
+ fail "Multiple networks with name '#{n[:name]}'" unless net_id.nil?
120
+ net_id = n[:id]
121
+ end
122
+ fail "No matching network with name '#{network}'" if net_id.nil?
123
+ networks << net_id
124
+ end
125
+ networks
126
+ end
100
127
 
101
128
  def port_open?(env, ip, port, timeout)
102
129
  start_time = Time.now
103
130
  current_time = start_time
131
+ nb_retry = 0
104
132
  while (current_time - start_time) <= timeout
105
133
  begin
106
- env[:ui].info(I18n.t("vagrant_openstack.waiting_for_ssh"))
134
+ env[:ui].info(I18n.t('vagrant_openstack.waiting_for_ssh')) if nb_retry % 5 == 0
107
135
  TCPSocket.new(ip, port)
108
136
  return true
109
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
137
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ETIMEDOUT
138
+ nb_retry += 1
110
139
  sleep 1
111
140
  end
112
141
  current_time = Time.now
113
142
  end
114
- return false
143
+ false
115
144
  end
116
145
 
117
146
  # This method finds a matching _thing_ in a collection of
@@ -1,20 +1,19 @@
1
- require "log4r"
1
+ require 'log4r'
2
2
 
3
3
  module VagrantPlugins
4
4
  module Openstack
5
5
  module Action
6
6
  # This deletes the running server, if there is one.
7
7
  class DeleteServer
8
- def initialize(app, env)
8
+ def initialize(app, _env)
9
9
  @app = app
10
- @logger = Log4r::Logger.new("vagrant_openstack::action::delete_server")
10
+ @logger = Log4r::Logger.new('vagrant_openstack::action::delete_server')
11
11
  end
12
12
 
13
13
  def call(env)
14
14
  if env[:machine].id
15
- env[:ui].info(I18n.t("vagrant_openstack.deleting_server"))
16
- client = env[:openstack_client]
17
- client.delete_server(env, env[:machine].id)
15
+ env[:ui].info(I18n.t('vagrant_openstack.deleting_server'))
16
+ env[:openstack_client].nova.delete_server(env, env[:machine].id)
18
17
  env[:machine].id = nil
19
18
  end
20
19
 
@@ -1,13 +1,14 @@
1
1
  module VagrantPlugins
2
2
  module Openstack
3
3
  module Action
4
- class IsCreated
5
- def initialize(app, env)
4
+ class Message
5
+ def initialize(app, _env, message)
6
6
  @app = app
7
+ @message = message
7
8
  end
8
9
 
9
10
  def call(env)
10
- env[:result] = env[:machine].state.id != :not_created
11
+ env[:ui].info(@message)
11
12
  @app.call(env)
12
13
  end
13
14
  end
@@ -1,4 +1,4 @@
1
- require "log4r"
1
+ require 'log4r'
2
2
 
3
3
  module VagrantPlugins
4
4
  module Openstack
@@ -6,9 +6,9 @@ module VagrantPlugins
6
6
  # This action reads the SSH info for the machine and puts it into the
7
7
  # `:machine_ssh_info` key in the environment.
8
8
  class ReadSSHInfo
9
- def initialize(app, env)
9
+ def initialize(app, _env)
10
10
  @app = app
11
- @logger = Log4r::Logger.new("vagrant_openstack::action::read_ssh_info")
11
+ @logger = Log4r::Logger.new('vagrant_openstack::action::read_ssh_info')
12
12
  end
13
13
 
14
14
  def call(env)
@@ -18,32 +18,12 @@ module VagrantPlugins
18
18
  end
19
19
 
20
20
  def read_ssh_info(env)
21
- client = env[:openstack_client]
22
- machine = env[:machine]
23
21
  config = env[:machine].provider_config
24
- @logger.debug(config)
25
- return nil if machine.id.nil?
26
- begin
27
- details = client.get_server_details(env, machine.id)
28
- rescue Exception => e
29
- # The machine can't be found
30
- @logger.error(e)
31
- @logger.info("Machine couldn't be found, assuming it got destroyed.")
32
- machine.id = nil
33
- return nil
34
- end
35
-
36
- for addr in details['addresses']['private']
37
- if addr['OS-EXT-IPS:type'] == 'floating'
38
- host = addr['addr']
39
- end
40
- end
41
-
42
- return {
22
+ {
43
23
  # Usually there should only be one public IP
44
- :host => host,
45
- :port => 22,
46
- :username => config.ssh_username
24
+ host: config.floating_ip,
25
+ port: 22,
26
+ username: config.ssh_username
47
27
  }
48
28
  end
49
29
  end
@@ -1,4 +1,4 @@
1
- require "log4r"
1
+ require 'log4r'
2
2
 
3
3
  module VagrantPlugins
4
4
  module Openstack
@@ -6,33 +6,31 @@ module VagrantPlugins
6
6
  # This action reads the state of the machine and puts it in the
7
7
  # `:machine_state_id` key in the environment.
8
8
  class ReadState
9
- def initialize(app, env)
9
+ def initialize(app, _env)
10
10
  @app = app
11
- @logger = Log4r::Logger.new("vagrant_openstack::action::read_state")
11
+ @logger = Log4r::Logger.new('vagrant_openstack::action::read_state')
12
12
  end
13
13
 
14
14
  def call(env)
15
15
  env[:machine_state_id] = read_state(env)
16
-
17
16
  @app.call(env)
18
17
  end
19
18
 
20
19
  def read_state(env)
21
20
  machine = env[:machine]
22
- client = env[:openstack_client]
23
21
  return :not_created if machine.id.nil?
24
22
 
25
23
  # Find the machine
26
- server = client.get_server_details(env, machine.id)
27
- if server.nil? || server['status'] == "DELETED"
24
+ server = env[:openstack_client].nova.get_server_details(env, machine.id)
25
+ if server.nil? || server['status'] == 'DELETED'
28
26
  # The machine can't be found
29
- @logger.info("Machine not found or deleted, assuming it got destroyed.")
27
+ @logger.info('Machine not found or deleted, assuming it got destroyed.')
30
28
  machine.id = nil
31
29
  return :not_created
32
30
  end
33
31
 
34
32
  # Return the state
35
- return server['status'].downcase.to_sym
33
+ server['status'].downcase.to_sym
36
34
  end
37
35
  end
38
36
  end
@@ -0,0 +1,20 @@
1
+ module VagrantPlugins
2
+ module Openstack
3
+ module Action
4
+ class Resume
5
+ def initialize(app, _env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].id
11
+ env[:ui].info I18n.t('vagrant.actions.vm.resume.resuming')
12
+ env[:openstack_client].nova.resume_server(env, env[:machine].id)
13
+ end
14
+
15
+ @app.call(env)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class StartServer
7
+ def initialize(app, _env)
8
+ @app = app
9
+ @logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
10
+ end
11
+
12
+ def call(env)
13
+ if env[:machine].id
14
+ env[:ui].info(I18n.t('vagrant_openstack.starting_server'))
15
+ env[:openstack_client].nova.start_server(env, env[:machine].id)
16
+ end
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class StopServer
7
+ def initialize(app, _env)
8
+ @app = app
9
+ @logger = Log4r::Logger.new('vagrant_openstack::action::stop_server')
10
+ end
11
+
12
+ def call(env)
13
+ if env[:machine].id
14
+ env[:ui].info(I18n.t('vagrant_openstack.stopping_server'))
15
+ env[:openstack_client].nova.stop_server(env, env[:machine].id)
16
+ end
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end