vagrant-cloudstack 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -19
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +19 -19
  5. data/CHANGELOG.md +179 -171
  6. data/Docker/.dockerignore +2 -0
  7. data/Docker/Dockerfile +51 -0
  8. data/Docker/Dockerfile.chefdk_0_17 +49 -0
  9. data/Docker/Dockerfile.latest_dependencies +49 -0
  10. data/Docker/README.md +67 -0
  11. data/Docker/vac.ps1 +29 -0
  12. data/Docker/vac.sh +30 -0
  13. data/Gemfile +20 -20
  14. data/LICENSE +8 -8
  15. data/README.md +416 -416
  16. data/Rakefile +106 -99
  17. data/bootstrap.key +27 -0
  18. data/build_rpm.sh +7 -7
  19. data/functional-tests/basic/Vagrantfile.basic_networking +45 -45
  20. data/functional-tests/basic/basic_spec.rb +21 -21
  21. data/functional-tests/networking/Vagrantfile.advanced_networking +119 -102
  22. data/functional-tests/networking/networking_spec.rb +14 -0
  23. data/functional-tests/rsync/Vagrantfile.advanced_networking +39 -56
  24. data/functional-tests/rsync/rsync_spec.rb +9 -9
  25. data/functional-tests/vmlifecycle/Vagrantfile.advanced_networking +66 -82
  26. data/functional-tests/vmlifecycle/vmlifecycle_spec.rb +13 -13
  27. data/lib/vagrant-cloudstack/action/connect_cloudstack.rb +47 -47
  28. data/lib/vagrant-cloudstack/action/is_created.rb +18 -18
  29. data/lib/vagrant-cloudstack/action/is_stopped.rb +18 -18
  30. data/lib/vagrant-cloudstack/action/message_already_created.rb +16 -16
  31. data/lib/vagrant-cloudstack/action/message_not_created.rb +16 -16
  32. data/lib/vagrant-cloudstack/action/message_will_not_destroy.rb +16 -16
  33. data/lib/vagrant-cloudstack/action/read_rdp_info.rb +76 -76
  34. data/lib/vagrant-cloudstack/action/read_ssh_info.rb +104 -87
  35. data/lib/vagrant-cloudstack/action/read_state.rb +38 -38
  36. data/lib/vagrant-cloudstack/action/read_winrm_info.rb +103 -103
  37. data/lib/vagrant-cloudstack/action/run_instance.rb +798 -703
  38. data/lib/vagrant-cloudstack/action/start_instance.rb +81 -81
  39. data/lib/vagrant-cloudstack/action/stop_instance.rb +28 -28
  40. data/lib/vagrant-cloudstack/action/terminate_instance.rb +269 -224
  41. data/lib/vagrant-cloudstack/action/timed_provision.rb +21 -21
  42. data/lib/vagrant-cloudstack/action/wait_for_state.rb +41 -41
  43. data/lib/vagrant-cloudstack/action/warn_networks.rb +19 -19
  44. data/lib/vagrant-cloudstack/action.rb +210 -210
  45. data/lib/vagrant-cloudstack/capabilities/rdp.rb +12 -12
  46. data/lib/vagrant-cloudstack/capabilities/winrm.rb +12 -12
  47. data/lib/vagrant-cloudstack/config.rb +566 -548
  48. data/lib/vagrant-cloudstack/errors.rb +27 -27
  49. data/lib/vagrant-cloudstack/exceptions/exceptions.rb +10 -10
  50. data/lib/vagrant-cloudstack/model/cloudstack_resource.rb +51 -33
  51. data/lib/vagrant-cloudstack/plugin.rb +82 -82
  52. data/lib/vagrant-cloudstack/provider.rb +58 -58
  53. data/lib/vagrant-cloudstack/service/cloudstack_resource_service.rb +64 -58
  54. data/lib/vagrant-cloudstack/util/timer.rb +17 -17
  55. data/lib/vagrant-cloudstack/version.rb +5 -5
  56. data/lib/vagrant-cloudstack.rb +17 -17
  57. data/locales/en.yml +131 -123
  58. data/spec/spec_helper.rb +8 -6
  59. data/spec/vagrant-cloudstack/action/read_ssh_info_spec.rb +80 -0
  60. data/spec/vagrant-cloudstack/config_spec.rb +355 -355
  61. data/spec/vagrant-cloudstack/model/cloudstack_resource_spec.rb +95 -73
  62. data/spec/vagrant-cloudstack/service/cloudstack_resource_service_spec.rb +43 -43
  63. data/spec/vagrant-cloudstack/support/be_a_resource.rb +6 -0
  64. data/vagrant-cloudstack.gemspec +59 -59
  65. data/vagrant-cloudstack.spec +42 -42
  66. metadata +14 -7
  67. data/dummy.box +0 -0
  68. data/example_box/README.md +0 -13
  69. data/example_box/metadata.json +0 -3
  70. data/functional-tests/networking/rsync_spec.rb +0 -12
@@ -1,27 +1,27 @@
1
- require "vagrant"
2
-
3
- module VagrantPlugins
4
- module Cloudstack
5
- module Errors
6
- class VagrantCloudstackError < Vagrant::Errors::VagrantError
7
- error_namespace("vagrant_cloudstack.errors")
8
- end
9
-
10
- class FogError < VagrantCloudstackError
11
- error_key(:fog_error)
12
- end
13
-
14
- class InstanceReadyTimeout < VagrantCloudstackError
15
- error_key(:instance_ready_timeout)
16
- end
17
-
18
- class RsyncError < VagrantCloudstackError
19
- error_key(:rsync_error)
20
- end
21
-
22
- class UserdataError < VagrantCloudstackError
23
- error_key(:user_data_error)
24
- end
25
- end
26
- end
27
- end
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Cloudstack
5
+ module Errors
6
+ class VagrantCloudstackError < Vagrant::Errors::VagrantError
7
+ error_namespace("vagrant_cloudstack.errors")
8
+ end
9
+
10
+ class FogError < VagrantCloudstackError
11
+ error_key(:fog_error)
12
+ end
13
+
14
+ class InstanceReadyTimeout < VagrantCloudstackError
15
+ error_key(:instance_ready_timeout)
16
+ end
17
+
18
+ class RsyncError < VagrantCloudstackError
19
+ error_key(:rsync_error)
20
+ end
21
+
22
+ class UserdataError < VagrantCloudstackError
23
+ error_key(:user_data_error)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,10 +1,10 @@
1
- module VagrantPlugins
2
- module Cloudstack
3
- module Exceptions
4
- class IpNotFoundException < Exception
5
- end
6
- class DuplicatePFRule < Exception
7
- end
8
- end
9
- end
10
- end
1
+ module VagrantPlugins
2
+ module Cloudstack
3
+ module Exceptions
4
+ class IpNotFoundException < Exception
5
+ end
6
+ class DuplicatePFRule < Exception
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,33 +1,51 @@
1
- module VagrantPlugins
2
- module Cloudstack
3
- module Model
4
- class CloudstackResource
5
- attr_accessor :id, :name
6
- attr_reader :kind
7
-
8
- def initialize(id, name, kind)
9
- raise 'Resource must have a kind' if kind.nil? || kind.empty?
10
- @id = id
11
- @name = name
12
- @kind = kind
13
- end
14
-
15
- def is_undefined?
16
- is_id_undefined? and is_name_undefined?
17
- end
18
-
19
- def is_id_undefined?
20
- id.nil? || id.empty?
21
- end
22
-
23
- def is_name_undefined?
24
- name.nil? || name.empty?
25
- end
26
-
27
- def to_s
28
- "#{kind} - #{id || '<unknown id>'}:#{name || '<unknown name>'}"
29
- end
30
- end
31
- end
32
- end
33
- end
1
+ module VagrantPlugins
2
+ module Cloudstack
3
+ module Model
4
+ class CloudstackResource
5
+ attr_accessor :id, :name, :details
6
+ attr_reader :kind
7
+
8
+ def initialize(id, name, kind)
9
+ raise 'Resource must have a kind' if kind.nil? || kind.empty?
10
+ @id = id
11
+ @name = name
12
+ @kind = kind
13
+ end
14
+
15
+ def is_undefined?
16
+ is_id_undefined? and is_name_undefined?
17
+ end
18
+
19
+ def is_id_undefined?
20
+ id.nil? || id.empty?
21
+ end
22
+
23
+ def is_name_undefined?
24
+ name.nil? || name.empty?
25
+ end
26
+
27
+ def to_s
28
+ "#{kind} - #{id || '<unknown id>'}:#{name || '<unknown name>'}"
29
+ end
30
+
31
+ def self.create_list(ids, names, kind)
32
+ return create_id_list(ids, kind) unless ids.empty?
33
+ return create_name_list(names, kind) unless names.empty?
34
+ []
35
+ end
36
+
37
+ def self.create_id_list(ids, kind)
38
+ ids.each_with_object([]) do |id, resources|
39
+ resources << CloudstackResource.new(id, nil, kind)
40
+ end
41
+ end
42
+
43
+ def self.create_name_list(names, kind)
44
+ names.each_with_object([]) do |name, resources|
45
+ resources << CloudstackResource.new(nil, name, kind)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,82 +1,82 @@
1
- begin
2
- require "vagrant"
3
- rescue LoadError
4
- raise "The Vagrant Cloudstack plugin must be run within Vagrant."
5
- end
6
-
7
- # This is a sanity check to make sure no one is attempting to install
8
- # this into an early Vagrant version.
9
- if Vagrant::VERSION < "1.5.0"
10
- raise "The Vagrant Cloudstack plugin is only compatible with Vagrant 1.5+"
11
- end
12
-
13
- module VagrantPlugins
14
- module Cloudstack
15
- class Plugin < Vagrant.plugin("2")
16
- name "Cloudstack"
17
- description <<-DESC
18
- This plugin installs a provider that allows Vagrant to manage
19
- machines in Cloudstack.
20
- DESC
21
-
22
- config(:cloudstack, :provider) do
23
- require_relative "config"
24
- Config
25
- end
26
-
27
- provider(:cloudstack, { parallel: true, box_optional: true}) do # Setup logging and i18n
28
- setup_logging
29
- setup_i18n
30
-
31
- # Return the provider
32
- require_relative "provider"
33
- Provider
34
- end
35
-
36
- provider_capability(:cloudstack, :winrm_info) do
37
- require_relative 'capabilities/winrm'
38
- VagrantPlugins::Cloudstack::Cap::WinRM
39
- end
40
-
41
- provider_capability(:cloudstack, :rdp_info) do
42
- require_relative 'capabilities/rdp'
43
- VagrantPlugins::Cloudstack::Cap::Rdp
44
- end
45
-
46
- # This initializes the internationalization strings.
47
- def self.setup_i18n
48
- I18n.load_path << File.expand_path("locales/en.yml", Cloudstack.source_root)
49
- I18n.reload!
50
- end
51
-
52
- # This sets up our log level to be whatever VAGRANT_LOG is.
53
- def self.setup_logging
54
- require "log4r"
55
-
56
- level = nil
57
- begin
58
- level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
59
- rescue NameError
60
- # This means that the logging constant wasn't found,
61
- # which is fine. We just keep `level` as `nil`. But
62
- # we tell the user.
63
- level = nil
64
- end
65
-
66
- # Some constants, such as "true" resolve to booleans, so the
67
- # above error checking doesn't catch it. This will check to make
68
- # sure that the log level is an integer, as Log4r requires.
69
- level = nil if !level.is_a?(Integer)
70
-
71
- # Set the logging level on all "vagrant" namespaced
72
- # logs as long as we have a valid level.
73
- if level
74
- logger = Log4r::Logger.new("vagrant_cloudstack")
75
- logger.outputters = Log4r::Outputter.stderr
76
- logger.level = level
77
- logger = nil
78
- end
79
- end
80
- end
81
- end
82
- end
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant Cloudstack plugin must be run within Vagrant."
5
+ end
6
+
7
+ # This is a sanity check to make sure no one is attempting to install
8
+ # this into an early Vagrant version.
9
+ if Vagrant::VERSION < "1.5.0"
10
+ raise "The Vagrant Cloudstack plugin is only compatible with Vagrant 1.5+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module Cloudstack
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "Cloudstack"
17
+ description <<-DESC
18
+ This plugin installs a provider that allows Vagrant to manage
19
+ machines in Cloudstack.
20
+ DESC
21
+
22
+ config(:cloudstack, :provider) do
23
+ require_relative "config"
24
+ Config
25
+ end
26
+
27
+ provider(:cloudstack, { parallel: true, box_optional: true}) do # Setup logging and i18n
28
+ setup_logging
29
+ setup_i18n
30
+
31
+ # Return the provider
32
+ require_relative "provider"
33
+ Provider
34
+ end
35
+
36
+ provider_capability(:cloudstack, :winrm_info) do
37
+ require_relative 'capabilities/winrm'
38
+ VagrantPlugins::Cloudstack::Cap::WinRM
39
+ end
40
+
41
+ provider_capability(:cloudstack, :rdp_info) do
42
+ require_relative 'capabilities/rdp'
43
+ VagrantPlugins::Cloudstack::Cap::Rdp
44
+ end
45
+
46
+ # This initializes the internationalization strings.
47
+ def self.setup_i18n
48
+ I18n.load_path << File.expand_path("locales/en.yml", Cloudstack.source_root)
49
+ I18n.reload!
50
+ end
51
+
52
+ # This sets up our log level to be whatever VAGRANT_LOG is.
53
+ def self.setup_logging
54
+ require "log4r"
55
+
56
+ level = nil
57
+ begin
58
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
59
+ rescue NameError
60
+ # This means that the logging constant wasn't found,
61
+ # which is fine. We just keep `level` as `nil`. But
62
+ # we tell the user.
63
+ level = nil
64
+ end
65
+
66
+ # Some constants, such as "true" resolve to booleans, so the
67
+ # above error checking doesn't catch it. This will check to make
68
+ # sure that the log level is an integer, as Log4r requires.
69
+ level = nil if !level.is_a?(Integer)
70
+
71
+ # Set the logging level on all "vagrant" namespaced
72
+ # logs as long as we have a valid level.
73
+ if level
74
+ logger = Log4r::Logger.new("vagrant_cloudstack")
75
+ logger.outputters = Log4r::Outputter.stderr
76
+ logger.level = level
77
+ logger = nil
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,58 +1,58 @@
1
- require "log4r"
2
- require "vagrant"
3
-
4
- module VagrantPlugins
5
- module Cloudstack
6
- class Provider < Vagrant.plugin("2", :provider)
7
- def initialize(machine)
8
- @machine = machine
9
- end
10
-
11
- def action(name)
12
- # Attempt to get the action method from the Action class if it
13
- # exists, otherwise return nil to show that we don't support the
14
- # given action.
15
- action_method = "action_#{name}"
16
- return Action.send(action_method) if Action.respond_to?(action_method)
17
- nil
18
- end
19
-
20
- def ssh_info
21
- # Run a custom action called "read_ssh_info" which does what it
22
- # says and puts the resulting SSH info into the `:machine_ssh_info`
23
- # key in the environment.
24
- env = @machine.action("read_ssh_info")
25
- env[:machine_ssh_info]
26
- end
27
-
28
- def winrm_info
29
- # Run a custom action called "read_winrm_info" which does what it
30
- # says and puts the resulting WinRM info into the `:machine_winrm_info`
31
- # key in the environment.
32
- env = @machine.action("read_winrm_info")
33
- env[:machine_winrm_info]
34
- end
35
-
36
- def state
37
- # Run a custom action we define called "read_state" which does
38
- # what it says. It puts the state in the `:machine_state_id`
39
- # key in the environment.
40
- env = @machine.action("read_state")
41
-
42
- state_id = env[:machine_state_id]
43
-
44
- # Get the short and long description
45
- short = I18n.t("vagrant_cloudstack.states.short_#{state_id}")
46
- long = I18n.t("vagrant_cloudstack.states.long_#{state_id}")
47
-
48
- # Return the MachineState object
49
- Vagrant::MachineState.new(state_id, short, long)
50
- end
51
-
52
- def to_s
53
- id = @machine.id.nil? ? "new" : @machine.id
54
- "Cloudstack (#{id})"
55
- end
56
- end
57
- end
58
- end
1
+ require "log4r"
2
+ require "vagrant"
3
+
4
+ module VagrantPlugins
5
+ module Cloudstack
6
+ class Provider < Vagrant.plugin("2", :provider)
7
+ def initialize(machine)
8
+ @machine = machine
9
+ end
10
+
11
+ def action(name)
12
+ # Attempt to get the action method from the Action class if it
13
+ # exists, otherwise return nil to show that we don't support the
14
+ # given action.
15
+ action_method = "action_#{name}"
16
+ return Action.send(action_method) if Action.respond_to?(action_method)
17
+ nil
18
+ end
19
+
20
+ def ssh_info
21
+ # Run a custom action called "read_ssh_info" which does what it
22
+ # says and puts the resulting SSH info into the `:machine_ssh_info`
23
+ # key in the environment.
24
+ env = @machine.action("read_ssh_info")
25
+ env[:machine_ssh_info]
26
+ end
27
+
28
+ def winrm_info
29
+ # Run a custom action called "read_winrm_info" which does what it
30
+ # says and puts the resulting WinRM info into the `:machine_winrm_info`
31
+ # key in the environment.
32
+ env = @machine.action("read_winrm_info")
33
+ env[:machine_winrm_info]
34
+ end
35
+
36
+ def state
37
+ # Run a custom action we define called "read_state" which does
38
+ # what it says. It puts the state in the `:machine_state_id`
39
+ # key in the environment.
40
+ env = @machine.action("read_state")
41
+
42
+ state_id = env[:machine_state_id]
43
+
44
+ # Get the short and long description
45
+ short = I18n.t("vagrant_cloudstack.states.short_#{state_id}")
46
+ long = I18n.t("vagrant_cloudstack.states.long_#{state_id}")
47
+
48
+ # Return the MachineState object
49
+ Vagrant::MachineState.new(state_id, short, long)
50
+ end
51
+
52
+ def to_s
53
+ id = @machine.id.nil? ? "new" : @machine.id
54
+ "Cloudstack (#{id})"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,58 +1,64 @@
1
- module VagrantPlugins
2
- module Cloudstack
3
- module Service
4
- class CloudstackResourceService
5
- def initialize(cloudstack_compute, ui)
6
- @cloudstack_compute = cloudstack_compute
7
- @ui = ui
8
- end
9
-
10
- def sync_resource(resource, api_parameters = {})
11
- if resource.id.nil? and resource.name
12
- resource.id = name_to_id(resource.name, resource.kind, api_parameters)
13
- elsif resource.id
14
- resource.name = id_to_name(resource.id, resource.kind, api_parameters)
15
- end
16
- @ui.detail("Syncronized resource: #{resource}")
17
- end
18
-
19
- private
20
-
21
- def translate_from_to(resource_type, options)
22
- if resource_type == 'public_ip_address'
23
- pluralised_type = 'public_ip_addresses'
24
- else
25
- pluralised_type = "#{resource_type}s"
26
- end
27
-
28
- full_response = @cloudstack_compute.send("list_#{pluralised_type}".to_sym, options)
29
- full_response["list#{pluralised_type.tr('_', '')}response"][resource_type.tr('_', '')]
30
- end
31
-
32
- def resourcefield_to_id(resource_type, resource_field, resource_field_value, options={})
33
- @ui.info("Fetching UUID for #{resource_type} with #{resource_field} '#{resource_field_value}'")
34
- full_response = translate_from_to(resource_type, options)
35
- result = full_response.find {|type| type[resource_field] == resource_field_value }
36
- result['id']
37
- end
38
-
39
- def id_to_resourcefield(resource_id, resource_type, resource_field, options={})
40
- @ui.info("Fetching #{resource_field} for #{resource_type} with UUID '#{resource_id}'")
41
- options = options.merge({'id' => resource_id})
42
- full_response = translate_from_to(resource_type, options)
43
- full_response[0][resource_field]
44
- end
45
-
46
- def name_to_id(resource_name, resource_type, options={})
47
- resource_field = resource_type == 'public_ip_address' ? 'ipaddress' : 'name'
48
- resourcefield_to_id(resource_type, resource_field, resource_name, options)
49
- end
50
-
51
- def id_to_name(resource_id, resource_type, options={})
52
- resource_field = resource_type == 'public_ip_address' ? 'ipaddress' : 'name'
53
- id_to_resourcefield(resource_id, resource_type, resource_field, options)
54
- end
55
- end
56
- end
57
- end
58
- end
1
+ module VagrantPlugins
2
+ module Cloudstack
3
+ module Service
4
+ class CloudstackResourceService
5
+ def initialize(cloudstack_compute, ui)
6
+ @cloudstack_compute = cloudstack_compute
7
+ @ui = ui
8
+ end
9
+
10
+ def sync_resource(resource, api_parameters = {})
11
+ @resource_details = nil
12
+ if resource.id.nil? and resource.name
13
+ resource.id = name_to_id(resource.name, resource.kind, api_parameters)
14
+ elsif resource.id
15
+ resource.name = id_to_name(resource.id, resource.kind, api_parameters)
16
+ end
17
+
18
+ unless resource.is_undefined?
19
+ resource.details = @resource_details
20
+ @ui.detail("Syncronized resource: #{resource}")
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def translate_from_to(resource_type, options)
27
+ if resource_type == 'public_ip_address'
28
+ pluralised_type = 'public_ip_addresses'
29
+ else
30
+ pluralised_type = "#{resource_type}s"
31
+ end
32
+
33
+ full_response = @cloudstack_compute.send("list_#{pluralised_type}".to_sym, options)
34
+ full_response["list#{pluralised_type.tr('_', '')}response"][resource_type.tr('_', '')]
35
+ end
36
+
37
+ def resourcefield_to_id(resource_type, resource_field, resource_field_value, options={})
38
+ @ui.info("Fetching UUID for #{resource_type} with #{resource_field} '#{resource_field_value}'")
39
+ full_response = translate_from_to(resource_type, options)
40
+ @resource_details = full_response.find {|type| type[resource_field] == resource_field_value }
41
+ @resource_details['id']
42
+ end
43
+
44
+ def id_to_resourcefield(resource_id, resource_type, resource_field, options={})
45
+ @ui.info("Fetching #{resource_field} for #{resource_type} with UUID '#{resource_id}'")
46
+ options = options.merge({'id' => resource_id})
47
+ full_response = translate_from_to(resource_type, options)
48
+ @resource_details = full_response[0]
49
+ @resource_details[resource_field]
50
+ end
51
+
52
+ def name_to_id(resource_name, resource_type, options={})
53
+ resource_field = resource_type == 'public_ip_address' ? 'ipaddress' : 'name'
54
+ resourcefield_to_id(resource_type, resource_field, resource_name, options)
55
+ end
56
+
57
+ def id_to_name(resource_id, resource_type, options={})
58
+ resource_field = resource_type == 'public_ip_address' ? 'ipaddress' : 'name'
59
+ id_to_resourcefield(resource_id, resource_type, resource_field, options)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end