vagrant-cloudstack 1.3.0 → 1.4.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.
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