vagrant-vcloud 0.1.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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE +20 -0
  5. data/README.md +80 -0
  6. data/Rakefile +17 -0
  7. data/example_box/README.md +13 -0
  8. data/example_box/Vagrantfile +6 -0
  9. data/example_box/metadata.json +1 -0
  10. data/lib/vagrant-vcloud.rb +65 -0
  11. data/lib/vagrant-vcloud/action.rb +226 -0
  12. data/lib/vagrant-vcloud/action/announce_ssh_exec.rb +17 -0
  13. data/lib/vagrant-vcloud/action/build_vapp.rb +197 -0
  14. data/lib/vagrant-vcloud/action/connect_vcloud.rb +68 -0
  15. data/lib/vagrant-vcloud/action/destroy.rb +69 -0
  16. data/lib/vagrant-vcloud/action/disconnect_vcloud.rb +33 -0
  17. data/lib/vagrant-vcloud/action/forward_ports.rb +127 -0
  18. data/lib/vagrant-vcloud/action/handle_nat_port_collisions.rb +129 -0
  19. data/lib/vagrant-vcloud/action/inventory_check.rb +156 -0
  20. data/lib/vagrant-vcloud/action/is_created.rb +36 -0
  21. data/lib/vagrant-vcloud/action/is_paused.rb +22 -0
  22. data/lib/vagrant-vcloud/action/is_running.rb +22 -0
  23. data/lib/vagrant-vcloud/action/message_already_running.rb +17 -0
  24. data/lib/vagrant-vcloud/action/message_cannot_suspend.rb +17 -0
  25. data/lib/vagrant-vcloud/action/message_not_created.rb +17 -0
  26. data/lib/vagrant-vcloud/action/message_will_not_destroy.rb +17 -0
  27. data/lib/vagrant-vcloud/action/power_off.rb +33 -0
  28. data/lib/vagrant-vcloud/action/power_on.rb +46 -0
  29. data/lib/vagrant-vcloud/action/read_ssh_info.rb +69 -0
  30. data/lib/vagrant-vcloud/action/read_state.rb +59 -0
  31. data/lib/vagrant-vcloud/action/resume.rb +33 -0
  32. data/lib/vagrant-vcloud/action/suspend.rb +33 -0
  33. data/lib/vagrant-vcloud/action/sync_folders.rb +82 -0
  34. data/lib/vagrant-vcloud/action/unmap_port_forwardings.rb +75 -0
  35. data/lib/vagrant-vcloud/config.rb +132 -0
  36. data/lib/vagrant-vcloud/driver/base.rb +459 -0
  37. data/lib/vagrant-vcloud/driver/meta.rb +151 -0
  38. data/lib/vagrant-vcloud/driver/version_5_1.rb +1669 -0
  39. data/lib/vagrant-vcloud/errors.rb +62 -0
  40. data/lib/vagrant-vcloud/model/forwarded_port.rb +64 -0
  41. data/lib/vagrant-vcloud/plugin.rb +78 -0
  42. data/lib/vagrant-vcloud/provider.rb +41 -0
  43. data/lib/vagrant-vcloud/util/compile_forwarded_ports.rb +31 -0
  44. data/lib/vagrant-vcloud/version.rb +5 -0
  45. data/locales/en.yml +55 -0
  46. data/vagrant-vcloud.gemspec +34 -0
  47. metadata +273 -0
@@ -0,0 +1,33 @@
1
+ require "i18n"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ module Action
6
+ class PowerOff
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::poweroff")
11
+ end
12
+
13
+ def call(env)
14
+
15
+ cfg = env[:machine].provider_config
16
+ cnx = cfg.vcloud_cnx.driver
17
+
18
+ vAppId = env[:machine].get_vapp_id
19
+ vmId = env[:machine].id
20
+ vmName = env[:machine].name
21
+
22
+ env[:ui].info("Powering off VM...")
23
+ task_id = cnx.poweroff_vm(vmId)
24
+ wait = cnx.wait_task_completion(task_id)
25
+
26
+ true
27
+
28
+ @app.call env
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ require "i18n"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ module Action
6
+ class PowerOn
7
+ def initialize(app, env)
8
+ @app = app
9
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::power_on")
10
+ end
11
+
12
+ def call(env)
13
+ @env = env
14
+
15
+
16
+ cfg = env[:machine].provider_config
17
+ cnx = cfg.vcloud_cnx.driver
18
+ vmName = env[:machine].name
19
+ vAppId = env[:machine].get_vapp_id
20
+
21
+ env[:ui].info("Booting VM...")
22
+
23
+ testIp = cnx.get_vapp_edge_public_ip(vAppId)
24
+
25
+ poweronVM = cnx.poweron_vm(env[:machine].id)
26
+ cnx.wait_task_completion(poweronVM)
27
+
28
+ if testIp.nil? && cfg.vdc_edge_gateway_ip && cfg.vdc_edge_gateway
29
+ @logger.debug("This is our first boot, we should map ports on org edge!")
30
+ env[:ui].info("Mapping ip #{cfg.vdc_edge_gateway_ip} on Edge #{cfg.vdc_edge_gateway} as our entry point.")
31
+ edgeMap = cnx.set_edge_gateway_rules(cfg.vdc_edge_gateway, cfg.vdc_id, cfg.vdc_edge_gateway_ip, vAppId)
32
+ cnx.wait_task_completion(edgeMap)
33
+ end
34
+
35
+
36
+
37
+
38
+ @app.call(env)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+
46
+
@@ -0,0 +1,69 @@
1
+ require "awesome_print"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ module Action
6
+ class ReadSSHInfo
7
+
8
+ # FIXME: More work needed here for vCloud logic (vApp, VM IPs, etc.)
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::read_ssh_info")
13
+ end
14
+
15
+ def call(env)
16
+ env[:machine_ssh_info] = read_ssh_info(env)
17
+
18
+ @app.call env
19
+ end
20
+
21
+
22
+ def read_ssh_info(env)
23
+ return nil if env[:machine].id.nil?
24
+
25
+ cfg = env[:machine].provider_config
26
+ cnx = cfg.vcloud_cnx.driver
27
+ vmName = env[:machine].name
28
+ vAppId = env[:machine].get_vapp_id
29
+
30
+ @logger.debug("Getting vapp info...")
31
+ vm = cnx.get_vapp(vAppId)
32
+ myhash = vm[:vms_hash][vmName.to_sym]
33
+
34
+ if vm.nil?
35
+ # The machine can't be found
36
+ @logger.info("Machine couldn't be found, assuming it got destroyed.")
37
+ machine.id = nil
38
+ return nil
39
+ end
40
+
41
+ @logger.debug("Getting port forwarding rules...")
42
+ rules = cnx.get_vapp_port_forwarding_rules(vAppId)
43
+
44
+ rules.each do |rule|
45
+ if rule[:vapp_scoped_local_id] == myhash[:vapp_scoped_local_id] && rule[:nat_internal_port] == "22"
46
+
47
+ @logger.debug("Our variables: IP #{rule[:nat_external_ip]} and Port #{rule[:nat_external_port]}")
48
+
49
+ @externalIP = rule[:nat_external_ip]
50
+ @externalPort = rule[:nat_external_port]
51
+ break
52
+ end
53
+ end
54
+
55
+ if cfg.vdc_edge_gateway_ip && cfg.vdc_edge_gateway
56
+ @logger.debug("We're running vagrant behind an org edge")
57
+ @externalIP = cfg.vdc_edge_gateway_ip
58
+ end
59
+
60
+ return {
61
+ # FIXME: these shouldn't be self
62
+ :host => @externalIP,
63
+ :port => @externalPort
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,59 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ module Action
6
+ class ReadState
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::read_state")
11
+ end
12
+
13
+ def call(env)
14
+ #env = read_state(env)
15
+
16
+ env[:machine_state_id] = read_state(env)
17
+
18
+ @app.call env
19
+ end
20
+
21
+ def read_state(env)
22
+
23
+ # FIXME: this part needs some cleanup
24
+
25
+ begin
26
+ cfg = env[:machine].provider_config
27
+ cnx = cfg.vcloud_cnx.driver
28
+ vAppId = env[:machine].get_vapp_id
29
+ vmName = env[:machine].name
30
+
31
+ if env[:machine].id.nil?
32
+ @logger.info("VM [#{vmName}] is not created yet")
33
+ return :not_created
34
+ end
35
+
36
+ vApp = cnx.get_vapp(vAppId)
37
+ vmStatus = vApp[:vms_hash][vmName][:status]
38
+
39
+ if vmStatus == "stopped"
40
+ @logger.info("VM [#{vmName}] is stopped")
41
+ return :stopped
42
+ elsif vmStatus == "running"
43
+ @logger.info("VM [#{vmName}] is running")
44
+ return :running
45
+ elsif vmStatus == "paused"
46
+ @logger.info("VM [#{vmName}] is suspended")
47
+ return :suspended
48
+ end
49
+ rescue Exception => e
50
+ ### When bad credentials, we get here.
51
+ @logger.debug("Couldn't Read VM State: #{e.message}")
52
+ raise VagrantPlugins::VCloud::Errors::VCloudError, :message => e.message
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,33 @@
1
+ require "i18n"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ module Action
6
+ class Resume
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::resume")
11
+ end
12
+
13
+ def call(env)
14
+
15
+ cfg = env[:machine].provider_config
16
+ cnx = cfg.vcloud_cnx.driver
17
+
18
+ vAppId = env[:machine].get_vapp_id
19
+ vmId = env[:machine].id
20
+ vmName = env[:machine].name
21
+
22
+ env[:ui].info("Powering on VM...")
23
+ task_id = cnx.poweron_vm(vmId)
24
+ wait = cnx.wait_task_completion(task_id)
25
+
26
+ true
27
+
28
+ @app.call env
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require "i18n"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ module Action
6
+ class Suspend
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::suspend")
11
+ end
12
+
13
+ def call(env)
14
+
15
+ cfg = env[:machine].provider_config
16
+ cnx = cfg.vcloud_cnx.driver
17
+
18
+ vAppId = env[:machine].get_vapp_id
19
+ vmId = env[:machine].id
20
+ vmName = env[:machine].name
21
+
22
+ env[:ui].info("Suspending VM...")
23
+ task_id = cnx.suspend_vm(vmId)
24
+ wait = cnx.wait_task_completion(task_id)
25
+
26
+ true
27
+
28
+ @app.call env
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,82 @@
1
+ require "log4r"
2
+ require "vagrant/util/subprocess"
3
+ require "vagrant/util/scoped_hash_override"
4
+ require "unison"
5
+
6
+ module VagrantPlugins
7
+ module VCloud
8
+ module Action
9
+ class SyncFolders
10
+ include Vagrant::Util::ScopedHashOverride
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::sync_folders")
15
+ end
16
+
17
+ def call(env)
18
+ @app.call(env)
19
+
20
+ ### COMPLETELY REDO USING UNISON!!!!
21
+
22
+ ssh_info = env[:machine].ssh_info
23
+
24
+ env[:machine].config.vm.synced_folders.each do |id, data|
25
+ data = scoped_hash_override(data, :vcloud)
26
+
27
+ # Ignore disabled shared folders
28
+ next if data[:disabled]
29
+
30
+ hostpath = File.expand_path(data[:hostpath], env[:root_path])
31
+ guestpath = data[:guestpath]
32
+
33
+ # Make sure there is a trailing slash on the host path to
34
+ # avoid creating an additional directory with rsync
35
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
36
+
37
+ @logger.debug("RSYNCING OVER #{hostpath} to #{guestpath}")
38
+
39
+ # env[:ui].info(I18n.t("vagrant_aws.rsync_folder",
40
+ # :hostpath => hostpath,
41
+ # :guestpath => guestpath))
42
+
43
+ # Create the host path if it doesn't exist and option flag is set
44
+ if data[:create]
45
+ begin
46
+ FileUtils::mkdir_p(hostpath)
47
+ rescue => err
48
+ raise Errors::MkdirError,
49
+ :hostpath => hostpath,
50
+ :err => err
51
+ end
52
+ end
53
+
54
+ # Create the guest path
55
+ env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
56
+ env[:machine].communicate.sudo(
57
+ "chown #{ssh_info[:username]} '#{guestpath}'")
58
+
59
+ # Rsync over to the guest path using the SSH info
60
+ command = [
61
+ "rsync", "--verbose", "--archive", "-z",
62
+ "--exclude", ".vagrant/",
63
+ "-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path]}'",
64
+ hostpath,
65
+ "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
66
+
67
+ r = Vagrant::Util::Subprocess.execute(*command)
68
+ if r.exit_code != 0
69
+ raise Errors::RsyncError,
70
+ :guestpath => guestpath,
71
+ :hostpath => hostpath,
72
+ :stderr => r.stderr
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+
@@ -0,0 +1,75 @@
1
+ require "set"
2
+
3
+ require "log4r"
4
+
5
+ module VagrantPlugins
6
+ module VCloud
7
+ module Action
8
+ # This middleware class will detect and handle collisions with
9
+ # forwarded ports, whether that means raising an error or repairing
10
+ # them automatically.
11
+ #
12
+ # Parameters it takes from the environment hash:
13
+ #
14
+ # * `:port_collision_repair` - If true, it will attempt to repair
15
+ # port collisions. If false, it will raise an exception when
16
+ # there is a collision.
17
+ #
18
+ # * `:port_collision_extra_in_use` - An array of ports that are
19
+ # considered in use.
20
+ #
21
+ # * `:port_collision_remap` - A hash remapping certain host ports
22
+ # to other host ports.
23
+ #
24
+ class UnmapPortForwardings
25
+
26
+
27
+ def initialize(app, env)
28
+ @app = app
29
+ @logger = Log4r::Logger.new("vagrant_vcloud::action::unmap_port_forwardings")
30
+ end
31
+
32
+ def call(env)
33
+
34
+ cfg = env[:machine].provider_config
35
+ cnx = cfg.vcloud_cnx.driver
36
+ vmName = env[:machine].name
37
+ vAppId = env[:machine].get_vapp_id
38
+
39
+ cfg.org = cnx.get_organization_by_name(cfg.org_name)
40
+ cfg.vdc_network_id = cfg.org[:networks][cfg.vdc_network_name]
41
+
42
+ @logger.debug("Getting vapp info...")
43
+ vm = cnx.get_vapp(vAppId)
44
+ myhash = vm[:vms_hash][vmName.to_sym]
45
+
46
+ @logger.debug("Getting port forwarding rules...")
47
+ rules = cnx.get_vapp_port_forwarding_rules(vAppId)
48
+
49
+ newRuleSet = rules.select { |h| !myhash[:vapp_scoped_local_id].include? h[:vapp_scoped_local_id] }
50
+
51
+ @logger.debug("OUR NEW RULE SET, PURGED: #{newRuleSet}")
52
+
53
+ removePorts = cnx.set_vapp_port_forwarding_rules(
54
+ vAppId,
55
+ "Vagrant-vApp-Net",
56
+ {
57
+ :fence_mode => "natRouted",
58
+ :parent_network => cfg.vdc_network_id,
59
+ :nat_policy_type => "allowTraffic",
60
+ :nat_rules => newRuleSet
61
+ })
62
+
63
+ wait = cnx.wait_task_completion(removePorts)
64
+
65
+ if !wait[:errormsg].nil?
66
+ raise Errors::ComposeVAppError, :message => wait[:errormsg]
67
+ end
68
+
69
+
70
+ @app.call(env)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,132 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module VCloud
5
+ class Config < Vagrant.plugin('2', :config)
6
+
7
+ # login attributes
8
+
9
+ # The vCloud Director hostname
10
+ #
11
+ # @return [String]
12
+ attr_accessor :hostname
13
+
14
+ # The Organization Name to log in to
15
+ #
16
+ # @return [String]
17
+ attr_accessor :org_name
18
+
19
+ # The username used to log in
20
+ #
21
+ # @return [String]
22
+ attr_accessor :username
23
+
24
+ # The password used to log in
25
+ #
26
+ # @return [String]
27
+ attr_accessor :password
28
+
29
+ # WIP on these
30
+
31
+ # Catalog Name where the item resides
32
+ #
33
+ # @return [String]
34
+ attr_accessor :catalog_name
35
+
36
+ # Catalog Item to be used as a template
37
+ #
38
+ # @return [String]
39
+ attr_accessor :catalog_item_name
40
+
41
+ # Virtual Data Center to be used
42
+ #
43
+ # @return [String]
44
+ attr_accessor :vdc_name
45
+
46
+ # Virtual Data Center Network to be used
47
+ #
48
+ # @return [String]
49
+ attr_accessor :vdc_network_name
50
+
51
+ # Virtual Data Center Network Id to be used
52
+ #
53
+ # @return [String]
54
+ attr_accessor :vdc_network_id
55
+
56
+ # IP allocation type
57
+ #
58
+ # @return [String]
59
+ attr_accessor :ip_allocation_type
60
+
61
+ # IP subnet
62
+ #
63
+ # @return [String]
64
+ attr_accessor :ip_subnet
65
+
66
+ # Port forwarding rules
67
+ #
68
+ # @return [Hash]
69
+ attr_reader :port_forwarding_rules
70
+
71
+ # Name of the edge gateway [optional]
72
+ #
73
+ # @return [String]
74
+ attr_accessor :vdc_edge_gateway
75
+
76
+ # Public IP of the edge gateway [optional, required if :vdc_edge_gateway is specified]
77
+ #
78
+ # @return [String]
79
+ attr_accessor :vdc_edge_gateway_ip
80
+
81
+ ##
82
+ ## vCloud Director config runtime values
83
+ ##
84
+
85
+ # connection handle
86
+ attr_accessor :vcloud_cnx
87
+
88
+ # org object (Hash)
89
+ attr_accessor :org
90
+
91
+ # org id (String)
92
+ attr_accessor :org_id
93
+
94
+ # vdc object (Hash)
95
+ attr_accessor :vdc
96
+
97
+ # vdc id (String)
98
+ attr_accessor :vdc_id
99
+
100
+ # catalog object (Hash)
101
+ attr_accessor :catalog
102
+
103
+ # catalog id (String)
104
+ attr_accessor :catalog_id
105
+
106
+ # catalog item object (Hash)
107
+ attr_accessor :catalog_item
108
+
109
+ # vApp Name (String)
110
+ attr_accessor :vAppName
111
+
112
+ # vApp Id (String)
113
+ attr_accessor :vAppId
114
+
115
+ def validate(machine)
116
+ errors = _detected_errors
117
+
118
+ # TODO: add blank?
119
+ errors << I18n.t("config.hostname") if hostname.nil?
120
+ errors << I18n.t("config.org_name") if org_name.nil?
121
+ errors << I18n.t("config.username") if username.nil?
122
+ errors << I18n.t("config.password") if password.nil?
123
+
124
+ errors << I18n.t("config.catalog_name") if catalog_name.nil?
125
+ errors << I18n.t("config.vdc_name") if vdc_name.nil?
126
+ errors << I18n.t("config.vdc_network_name") if vdc_network_name.nil?
127
+
128
+ { "vCloud Provider" => errors }
129
+ end
130
+ end
131
+ end
132
+ end