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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2225b21d3d39c0bbd8be864bff61450e04989570
4
+ data.tar.gz: 0bb584b49730dcc825f6ee31cdce2f6c3026748c
5
+ SHA512:
6
+ metadata.gz: c8ad741705b3c4d1761f7b6e9a96fd8e48c953dc4f212108d066d31179b1a0aa104821fd7a2b0768199a9b7606665c88a511f787b0d5a1c6046fed7793d8d4ab
7
+ data.tar.gz: ed8bb6a2e30c4217d43592c8eac7b4ab076d7d8b27992ff57561f1ac3b35c1997410716f679edfa15fd544df2e5a63ff8bfdd3bbbf8d4fac4a04c79a52e21ea8
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .vagrant/*
2
+ pkg/*
3
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git'
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Fabio Rapposelli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ [Vagrant](http://www.vagrantup.com) provider for VMware vCloud Director®
2
+ =============
3
+
4
+ [Version 0.1.0](https://github.com/frapposelli/vagrant-vcloud/releases/tag/v0.1.0) has been released!
5
+ -------------
6
+
7
+ Please note that this software is still Alpha/Beta quality and is not recommended for production usage.
8
+
9
+ Right now a [Precise32](http://vagrant.tsugliani.fr/precise32.box) is available for use, or you can roll your own as you please, make sure to install VMware tools in it.
10
+
11
+ Features of Version 0.1.0 are:
12
+
13
+ - Basic Create/Provision/Destroy lifecycle.
14
+ - Rsync-based provisioning (working on alternatives for that).
15
+ - Use a single vApp as a container for Multi-VM Vagrantfiles.
16
+ - Use a vApp vShield Edge to perform DNAT/SNAT on a single IP for Multi-VM Vagrantfiles.
17
+ - Automatically create NAT rules on a fronting Organization Edge.
18
+ - Automatic upload of the Vagrant box to the specified catalog.
19
+ - Works on [vCloud® Hybrid Service™](http://www.vmware.com/products/vcloud-hybrid-service)!
20
+
21
+ What is still missing:
22
+
23
+ - TEST SUITES! (working on that).
24
+ - Speed, the code is definitely not optimized.
25
+ - Permission checks, make sure you have at least Catalog Admin privileges if you want to upload boxes to vCloud.
26
+ - Thorough testing.
27
+ - Error checking is absymal.
28
+ - Some spaghetti code here and there.
29
+ - Bugs, bugs and BUGS!.
30
+
31
+ If you're a developer and want to lend us a hand, head over to our ```develop``` branch and get busy!
32
+
33
+ A Sample Multi-VM Vagrantfile:
34
+
35
+ ```ruby
36
+ precise32_vm_box_url = "http://vagrant.tsugliani.fr/precise32.box"
37
+
38
+ nodes = [
39
+ { :hostname => "web-vm", :box => "precise32", :box_url => precise32_vm_box_url},
40
+ { :hostname => "ssh-vm", :box => "precise32" , :box_url => precise32_vm_box_url},
41
+ { :hostname => "sql-vm", :box => "precise32", :box_url => precise32_vm_box_url },
42
+ { :hostname => "lb-vm", :box => "precise64", :box_url => precise32_vm_box_url },
43
+ { :hostname => "app-vm", :box => "precise32", :box_url => precise32_vm_box_url },
44
+ ]
45
+
46
+ Vagrant.configure("2") do |config|
47
+
48
+ # vCloud Director provider settings
49
+ config.vm.provider :vcloud do |vcloud|
50
+ vcloud.hostname = "https://my.cloudprovider.com"
51
+ vcloud.username = "MyUserName"
52
+ vcloud.password = "MySup3rS3cr3tPassw0rd!"
53
+
54
+ vcloud.org_name = "OrganizationName"
55
+ vcloud.vdc_name = "vDC_Name"
56
+
57
+ vcloud.catalog_name = "Vagrant"
58
+ vcloud.ip_subnet = "172.16.32.125/255.255.255.240"
59
+
60
+ vcloud.vdc_network_name = "MyNetwork"
61
+
62
+ vcloud.vdc_edge_gateway = "MyOrgEdgeGateway"
63
+ vcloud.vdc_edge_gateway_ip = "10.10.10.10"
64
+ end
65
+
66
+ nodes.each do |node|
67
+ config.vm.define node[:hostname] do |node_config|
68
+ node_config.vm.box = node[:box]
69
+ node_config.vm.hostname = node[:hostname]
70
+ node_config.vm.box_url = node[:box_url]
71
+ node_config.vm.network :forwarded_port, guest: 80, host: 8080, auto_correct: true
72
+ # node_config.vm.provision :puppet do |puppet|
73
+ # puppet.manifests_path = 'puppet/manifests'
74
+ # puppet.manifest_file = 'site.pp'
75
+ # puppet.module_path = 'puppet/modules'
76
+ # end
77
+ end
78
+ end
79
+ end
80
+ ```
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/core/rake_task'
4
+
5
+ # Immediately sync all stdout so that tools like buildbot can
6
+ # immediately load in the output.
7
+ $stdout.sync = true
8
+ $stderr.sync = true
9
+
10
+ # Change to the directory of this file.
11
+ Dir.chdir(File.expand_path('../', __FILE__))
12
+
13
+ Bundler::GemHelper.install_tasks
14
+
15
+ RSpec::Core::RakeTask.new
16
+
17
+ task :default => 'spec'
@@ -0,0 +1,13 @@
1
+ # vagrant-vcloud box specifications [WIP]
2
+
3
+ *Note that vagrant-vcloud currently supports only single VM vApp boxes*
4
+
5
+ BOX package should contain:
6
+
7
+ - `metadata.json` -- Vagrant metadata file
8
+ - `<boxname>.ovf` -- OVF descriptor of the vApp.
9
+ - `<boxname>.mf` -- OVF manifest file containing file hashes.
10
+ - `<boxname>-disk-<#>.vmdk` -- Associated VMDK files.
11
+ - `Vagrantfile`-- vagrant-vcloud default Vagrantfile
12
+
13
+ A [task is open](https://github.com/frapposelli/vagrant-vcloud/issues/12) for creating a veewee plugin to facilitate Box creation
@@ -0,0 +1,6 @@
1
+ Vagrant::Config.run do |config|
2
+ config.vm.base_mac = "<mac address>"
3
+ end
4
+
5
+ include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
6
+ load include_vagrantfile if File.exist?(include_vagrantfile)
@@ -0,0 +1 @@
1
+ {"provider": "vagrant-vcloud"}
@@ -0,0 +1,65 @@
1
+ require "pathname"
2
+ require "vagrant-vcloud/plugin"
3
+
4
+ module VagrantPlugins
5
+ module VCloud
6
+ lib_path = Pathname.new(File.expand_path("../vagrant-vcloud", __FILE__))
7
+ autoload :Action, lib_path.join("action")
8
+ autoload :Errors, lib_path.join("errors")
9
+
10
+ # This returns the path to the source of this plugin.
11
+ #
12
+ # @return [Pathname]
13
+ def self.source_root
14
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
15
+ end
16
+ end
17
+ end
18
+
19
+ module Vagrant
20
+ class Machine
21
+
22
+ attr_reader :vappid
23
+
24
+ def vappid=(value)
25
+ @logger.info("New vApp ID: #{value.inspect}")
26
+
27
+ # The file that will store the id if we have one. This allows the
28
+ # ID to persist across Vagrant runs.
29
+
30
+ id_file = @data_dir.join("../../../vcloud_vappid")
31
+
32
+ ### this should be ./.vagrant/vcloud_vappid
33
+
34
+ if value
35
+ # Write the "id" file with the id given.
36
+ id_file.open("w+") do |f|
37
+ f.write(value)
38
+ end
39
+ else
40
+ # Delete the file, since the machine is now destroyed
41
+ id_file.delete if id_file.file?
42
+ end
43
+
44
+ # Store the ID locally
45
+ @vappid = value
46
+
47
+ # Notify the provider that the ID changed in case it needs to do
48
+ # any accounting from it.
49
+ #@provider.machine_id_changed
50
+ end
51
+
52
+ # This returns the vCloud Director vApp ID.
53
+ #
54
+ # @return [vAppId]
55
+ def get_vapp_id
56
+ vappid_file = @data_dir.join("../../../vcloud_vappid")
57
+ if vappid_file.file?
58
+ @vappid = vappid_file.read
59
+ else
60
+ nil
61
+ end
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,226 @@
1
+ require "pathname"
2
+ require "vagrant/action/builder"
3
+
4
+ module VagrantPlugins
5
+ module VCloud
6
+ module Action
7
+ include Vagrant::Action::Builtin
8
+
9
+ # Vagrant commands
10
+ # This action boots the VM, assuming the VM is in a state that requires
11
+ # a bootup (i.e. not saved).
12
+ def self.action_boot
13
+ Vagrant::Action::Builder.new.tap do |b|
14
+ b.use PowerOn
15
+ b.use HandleNATPortCollisions
16
+ b.use ForwardPorts
17
+ b.use Provision
18
+ b.use SyncFolders
19
+ end
20
+ end
21
+
22
+ def self.action_reload
23
+ Vagrant::Action::Builder.new.tap do |b|
24
+ b.use ConfigValidate
25
+ b.use Call, IsCreated do |env, b2|
26
+ if !env[:result]
27
+ b2.use MessageNotCreated
28
+ next
29
+ end
30
+ b2.use action_halt
31
+ b2.use action_start
32
+ b2.use DisconnectVCloud
33
+ end
34
+ end
35
+ end
36
+
37
+ # This action starts a VM, assuming it is already imported and exists.
38
+ # A precondition of this action is that the VM exists.
39
+ def self.action_start
40
+ Vagrant::Action::Builder.new.tap do |b|
41
+ b.use ConfigValidate
42
+ b.use ConnectVCloud
43
+ b.use Call, IsRunning do |env, b2|
44
+ # If the VM is running, then our work here is done, exit
45
+ if env[:result]
46
+ b2.use MessageAlreadyRunning
47
+ next
48
+ end
49
+ b2.use Call, IsPaused do |env2, b3|
50
+ if env2[:result]
51
+ b3.use Resume
52
+ next
53
+ end
54
+ b3.use action_boot
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def self.action_halt
61
+ Vagrant::Action::Builder.new.tap do |b|
62
+ b.use ConnectVCloud
63
+ b.use Call, IsPaused do |env, b2|
64
+ if env[:result]
65
+ b2.use Resume
66
+ end
67
+ b2.use UnmapPortForwardings
68
+ b2.use PowerOff
69
+ end
70
+ end
71
+ end
72
+
73
+ def self.action_suspend
74
+ Vagrant::Action::Builder.new.tap do |b|
75
+ b.use ConnectVCloud
76
+ b.use Call, IsRunning do |env, b2|
77
+ # If the VM is stopped, can't suspend
78
+ if !env[:result]
79
+ b2.use MessageCannotSuspend
80
+ else
81
+ b2.use Suspend
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def self.action_resume
88
+ Vagrant::Action::Builder.new.tap do |b|
89
+ b.use ConnectVCloud
90
+ b.use Resume
91
+ end
92
+ end
93
+
94
+ def self.action_destroy
95
+ Vagrant::Action::Builder.new.tap do |b|
96
+ b.use Call, DestroyConfirm do |env, b2|
97
+ if env[:result]
98
+ b2.use ConfigValidate
99
+ b2.use ConnectVCloud
100
+ b2.use Call, IsRunning do |env2, b3|
101
+ # If the VM is running, must power off
102
+ if env2[:result]
103
+ b3.use action_halt
104
+ end
105
+ b3.use Destroy
106
+ end
107
+ else
108
+ b2.use MessageWillNotDestroy
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ def self.action_provision
115
+ Vagrant::Action::Builder.new.tap do |b|
116
+ b.use ConfigValidate
117
+ b.use Call, IsCreated do |env, b2|
118
+ if !env[:result]
119
+ b2.use MessageNotCreated
120
+ next
121
+ end
122
+ b2.use Provision
123
+ b2.use SyncFolders
124
+ end
125
+ end
126
+ end
127
+
128
+ # This action is called to read the SSH info of the machine. The
129
+ # resulting state is expected to be put into the `:machine_ssh_info`
130
+ # key.
131
+ def self.action_read_ssh_info
132
+ Vagrant::Action::Builder.new.tap do |b|
133
+ b.use ConfigValidate
134
+ b.use ConnectVCloud
135
+ b.use ReadSSHInfo
136
+ end
137
+ end
138
+
139
+ # This action is called to read the state of the machine. The
140
+ # resulting state is expected to be put into the `:machine_state_id`
141
+ # key.
142
+ def self.action_read_state
143
+ Vagrant::Action::Builder.new.tap do |b|
144
+ b.use ConfigValidate
145
+ b.use ConnectVCloud
146
+ b.use ReadState
147
+ end
148
+ end
149
+
150
+ def self.action_ssh
151
+ Vagrant::Action::Builder.new.tap do |b|
152
+ b.use ConfigValidate
153
+ b.use Call, IsCreated do |env, b2|
154
+ if !env[:result]
155
+ b2.use MessageNotCreated
156
+ next
157
+ end
158
+ # This calls our helper that announces the IP used to connect
159
+ # to the VM, either directly to the vApp vShield or to the Org Edge.
160
+ b2.use AnnounceSSHExec
161
+ end
162
+ end
163
+ end
164
+
165
+ def self.action_ssh_run
166
+ Vagrant::Action::Builder.new.tap do |b|
167
+ b.use ConfigValidate
168
+ b.use Call, IsCreated do |env, b2|
169
+ if !env[:result]
170
+ b2.use MessageNotCreated
171
+ next
172
+ end
173
+
174
+ b2.use SSHRun
175
+ end
176
+ end
177
+ end
178
+
179
+ def self.action_up
180
+ Vagrant::Action::Builder.new.tap do |b|
181
+ b.use ConfigValidate
182
+ b.use Call, IsCreated do |env, b2|
183
+ if !env[:result]
184
+ b2.use HandleBoxUrl
185
+ end
186
+ end
187
+ b.use ConnectVCloud
188
+ b.use Call, IsCreated do |env, b2|
189
+ if !env[:result]
190
+ b2.use InventoryCheck
191
+ b2.use BuildVApp
192
+ end
193
+ end
194
+ b.use action_start
195
+ b.use DisconnectVCloud
196
+ end
197
+ end
198
+
199
+ # The autoload farm
200
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
201
+ autoload :AnnounceSSHExec, action_root.join("announce_ssh_exec")
202
+ autoload :BuildVApp, action_root.join("build_vapp")
203
+ autoload :ConnectVCloud, action_root.join("connect_vcloud")
204
+ autoload :Destroy, action_root.join("destroy")
205
+ autoload :DisconnectVCloud, action_root.join("disconnect_vcloud")
206
+ autoload :ForwardPorts, action_root.join("forward_ports")
207
+ autoload :HandleNATPortCollisions, action_root.join("handle_nat_port_collisions")
208
+ autoload :InventoryCheck, action_root.join("inventory_check")
209
+ autoload :IsCreated, action_root.join("is_created")
210
+ autoload :IsPaused, action_root.join("is_paused")
211
+ autoload :IsRunning, action_root.join("is_running")
212
+ autoload :MessageAlreadyRunning, action_root.join("message_already_running")
213
+ autoload :MessageCannotSuspend, action_root.join("message_cannot_suspend")
214
+ autoload :MessageNotCreated, action_root.join("message_not_created")
215
+ autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
216
+ autoload :PowerOff, action_root.join("power_off")
217
+ autoload :PowerOn, action_root.join("power_on")
218
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
219
+ autoload :ReadState, action_root.join("read_state")
220
+ autoload :Resume, action_root.join("resume")
221
+ autoload :Suspend, action_root.join("suspend")
222
+ autoload :SyncFolders, action_root.join("sync_folders")
223
+ autoload :UnmapPortForwardings, action_root.join("unmap_port_forwardings")
224
+ end
225
+ end
226
+ end