vagrant-vcloud 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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