vagrant-vrealize 0.0.4

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 (37) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +16 -0
  3. data/LICENSE +55 -0
  4. data/README.md +132 -0
  5. data/Rakefile +29 -0
  6. data/example_box/README.md +13 -0
  7. data/example_box/Vagrantfile +7 -0
  8. data/example_box/metadata.json +3 -0
  9. data/example_box/mkbox.sh +3 -0
  10. data/example_box/vrealize.box +0 -0
  11. data/lib/vagrant-vrealize/action/connect_vrealize.rb +65 -0
  12. data/lib/vagrant-vrealize/action/is_created.rb +35 -0
  13. data/lib/vagrant-vrealize/action/is_stopped.rb +18 -0
  14. data/lib/vagrant-vrealize/action/message_already_created.rb +18 -0
  15. data/lib/vagrant-vrealize/action/message_not_created.rb +16 -0
  16. data/lib/vagrant-vrealize/action/message_will_not_destroy.rb +16 -0
  17. data/lib/vagrant-vrealize/action/read_ssh_info.rb +28 -0
  18. data/lib/vagrant-vrealize/action/read_state.rb +28 -0
  19. data/lib/vagrant-vrealize/action/run_instance.rb +111 -0
  20. data/lib/vagrant-vrealize/action/start_instance.rb +25 -0
  21. data/lib/vagrant-vrealize/action/stop_instance.rb +19 -0
  22. data/lib/vagrant-vrealize/action/terminate_instance.rb +23 -0
  23. data/lib/vagrant-vrealize/action/timed_provision.rb +21 -0
  24. data/lib/vagrant-vrealize/action/wait_for_state.rb +25 -0
  25. data/lib/vagrant-vrealize/action/warn_networks.rb +19 -0
  26. data/lib/vagrant-vrealize/action.rb +191 -0
  27. data/lib/vagrant-vrealize/config.rb +138 -0
  28. data/lib/vagrant-vrealize/errors.rb +32 -0
  29. data/lib/vagrant-vrealize/extra-entries.rb +46 -0
  30. data/lib/vagrant-vrealize/plugin.rb +73 -0
  31. data/lib/vagrant-vrealize/provider.rb +52 -0
  32. data/lib/vagrant-vrealize/util/timer.rb +17 -0
  33. data/lib/vagrant-vrealize/version.rb +5 -0
  34. data/lib/vagrant-vrealize/vra_client.rb +140 -0
  35. data/lib/vagrant-vrealize.rb +19 -0
  36. data/locales/en.yml +148 -0
  37. metadata +106 -0
@@ -0,0 +1,23 @@
1
+ require "log4r"
2
+ require "json"
3
+
4
+ module VagrantPlugins
5
+ module Vrealize
6
+ module Action
7
+ # This terminates the running instance.
8
+ class TerminateInstance
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new("vagrant_vrealize::action::terminate_instance")
12
+ end
13
+
14
+ def call(env)
15
+ vra = env[:vra]
16
+ vra.destroy(env[:machine].id) if env[:machine].id
17
+
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ require "vagrant-vrealize/util/timer"
2
+
3
+ module VagrantPlugins
4
+ module Vrealize
5
+ module Action
6
+ # This is the same as the builtin provision except it times the
7
+ # provisioner runs.
8
+ class TimedProvision < Vagrant::Action::Builtin::Provision
9
+ def run_provisioner(env, name, p)
10
+ timer = Util::Timer.time do
11
+ super
12
+ end
13
+
14
+ env[:metrics] ||= {}
15
+ env[:metrics]["provisioner_times"] ||= []
16
+ env[:metrics]["provisioner_times"] << [name, timer]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require "log4r"
2
+ require "timeout"
3
+
4
+ module VagrantPlugins
5
+ module Vrealize
6
+ module Action
7
+ # This action will wait for a machine to reach a specific state or quit by timeout
8
+ class WaitForState
9
+ # env[:result] will be false in case of timeout.
10
+ # @param [Symbol] state Target machine state.
11
+ # @param [Number] timeout Timeout in seconds.
12
+ def initialize(app, env, state, timeout)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant_vrealize::action::wait_for_state")
15
+ @state = state
16
+ @timeout = timeout
17
+ end
18
+
19
+ def call(env)
20
+ fail NotImplementedError
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module Vrealize
3
+ module Action
4
+ class WarnNetworks
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].config.vm.networks.length > 0
11
+ env[:ui].warn(I18n.t("vagrant_vrealize.warn_networks"))
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,191 @@
1
+ require "pathname"
2
+
3
+ require "vagrant/action/builder"
4
+ require 'vagrant/action'
5
+
6
+ module VagrantPlugins
7
+ module Vrealize
8
+ module Action
9
+ # Include the built-in modules so we can use them as top-level things.
10
+ include Vagrant::Action::Builtin
11
+
12
+ # This action is called to halt the remote machine.
13
+ def self.action_halt
14
+ Vagrant::Action::Builder.new.tap do |b|
15
+ b.use ConfigValidate
16
+ b.use Call, IsCreated do |env, b2|
17
+ if !env[:result]
18
+ b2.use MessageNotCreated
19
+ next
20
+ end
21
+
22
+ b2.use ConnectVrealize
23
+ b2.use StopInstance
24
+ end
25
+ end
26
+ end
27
+
28
+ # This action is called to terminate the remote machine.
29
+ def self.action_destroy
30
+ Vagrant::Action::Builder.new.tap do |b|
31
+ b.use Call, DestroyConfirm do |env, b2|
32
+ if env[:result]
33
+ b2.use ConfigValidate
34
+ b2.use Call, IsCreated do |env2, b3|
35
+ if !env2[:result]
36
+ b3.use MessageNotCreated
37
+ next
38
+ end
39
+ b3.use ConnectVrealize
40
+ b3.use TerminateInstance
41
+ b3.use ProvisionerCleanup if defined?(ProvisionerCleanup)
42
+ end
43
+ else
44
+ b2.use MessageWillNotDestroy
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ # This action is called when `vagrant provision` is called.
51
+ def self.action_provision
52
+ Vagrant::Action::Builder.new.tap do |b|
53
+ b.use ConfigValidate
54
+ b.use Call, IsCreated do |env, b2|
55
+ if !env[:result]
56
+ b2.use MessageNotCreated
57
+ next
58
+ end
59
+
60
+ b2.use Provision
61
+ end
62
+ end
63
+ end
64
+
65
+ # This action is called to read the SSH info of the machine. The
66
+ # resulting state is expected to be put into the `:machine_ssh_info`
67
+ # key.
68
+ def self.action_read_ssh_info
69
+ Vagrant::Action::Builder.new.tap do |b|
70
+ b.use ConfigValidate
71
+ b.use ConnectVrealize
72
+ b.use ReadSSHInfo
73
+ end
74
+ end
75
+
76
+ # This action is called to read the state of the machine. The
77
+ # resulting state is expected to be put into the `:machine_state_id`
78
+ # key.
79
+ def self.action_read_state
80
+ Vagrant::Action::Builder.new.tap do |b|
81
+ b.use ConfigValidate
82
+ b.use ConnectVrealize
83
+ b.use ReadState
84
+ end
85
+ end
86
+
87
+ # This action is called to SSH into the machine.
88
+ def self.action_ssh
89
+ Vagrant::Action::Builder.new.tap do |b|
90
+ b.use ConfigValidate
91
+ b.use Call, IsCreated do |env, b2|
92
+ if !env[:result]
93
+ b2.use MessageNotCreated
94
+ next
95
+ end
96
+
97
+ b2.use SSHExec
98
+ end
99
+ end
100
+ end
101
+
102
+ def self.action_ssh_run
103
+ Vagrant::Action::Builder.new.tap do |b|
104
+ b.use ConfigValidate
105
+ b.use Call, IsCreated do |env, b2|
106
+ if !env[:result]
107
+ b2.use MessageNotCreated
108
+ next
109
+ end
110
+
111
+ b2.use SSHRun
112
+ end
113
+ end
114
+ end
115
+
116
+ def self.action_prepare_boot
117
+ Vagrant::Action::Builder.new.tap do |b|
118
+ b.use Provision
119
+ b.use SyncedFolders
120
+ b.use WarnNetworks
121
+ end
122
+ end
123
+
124
+ # This action is called to bring the box up from nothing.
125
+ def self.action_up
126
+ Vagrant::Action::Builder.new.tap do |b|
127
+ b.use HandleBox
128
+ b.use ConfigValidate
129
+ b.use BoxCheckOutdated
130
+ b.use ConnectVrealize
131
+ b.use Call, IsCreated do |env1, b1|
132
+ if env1[:result]
133
+ b1.use Call, IsStopped do |env2, b2|
134
+ if env2[:result]
135
+ b2.use action_prepare_boot
136
+ b2.use StartInstance # restart this instance
137
+ else
138
+ b2.use MessageAlreadyCreated # TODO write a better message
139
+ end
140
+ end
141
+ else
142
+ b1.use action_prepare_boot
143
+ b1.use RunInstance # launch a new instance
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ def self.action_reload
150
+ Vagrant::Action::Builder.new.tap do |b|
151
+ b.use ConfigValidate
152
+ b.use ConnectVrealize
153
+ b.use Call, IsCreated do |env, b2|
154
+ if !env[:result]
155
+ b2.use MessageNotCreated
156
+ next
157
+ end
158
+
159
+ b2.use action_halt
160
+ b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
161
+ if env2[:result]
162
+ b3.use action_up
163
+ else
164
+ # TODO we couldn't reach :stopped, what now?
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ # The autoload farm
172
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
173
+ autoload :ConnectVrealize, action_root.join("connect_vrealize")
174
+ autoload :IsCreated, action_root.join("is_created")
175
+ autoload :IsStopped, action_root.join("is_stopped")
176
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
177
+ autoload :MessageNotCreated, action_root.join("message_not_created")
178
+ autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
179
+ autoload :PackageInstance, action_root.join("package_instance")
180
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
181
+ autoload :ReadState, action_root.join("read_state")
182
+ autoload :RunInstance, action_root.join("run_instance")
183
+ autoload :StartInstance, action_root.join("start_instance")
184
+ autoload :StopInstance, action_root.join("stop_instance")
185
+ autoload :TerminateInstance, action_root.join("terminate_instance")
186
+ autoload :TimedProvision, action_root.join("timed_provision") # some plugins now expect this action to exist
187
+ autoload :WaitForState, action_root.join("wait_for_state")
188
+ autoload :WarnNetworks, action_root.join("warn_networks")
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,138 @@
1
+ require "vagrant"
2
+ require "vagrant-vrealize/extra-entries"
3
+
4
+ module VagrantPlugins
5
+ module Vrealize
6
+ class Config < Vagrant.plugin("2", :config)
7
+
8
+ def initialize(*args, &blk)
9
+ @vra_username =
10
+ @vra_password =
11
+ @vra_tenant =
12
+ @vra_base_url =
13
+ @subtenant_id =
14
+ @catalog_item_id =
15
+ @requested_for =
16
+ UNSET_VALUE
17
+
18
+ @cpus = 1
19
+ @memory = 1024
20
+ @lease_days = 5
21
+
22
+ @__extra_entries = ExtraEntries.new
23
+ super
24
+ end
25
+
26
+ #
27
+ # The username for accessing the VRealize instance.
28
+ #
29
+ # @return [String]
30
+ attr_accessor :vra_username
31
+
32
+ #
33
+ # The password for accessing the VRealize instance.
34
+ #
35
+ # @return [String]
36
+ attr_accessor :vra_password
37
+
38
+
39
+ #
40
+ # The tenant to own the requested resource.
41
+ #
42
+ # @return [String]
43
+ attr_accessor :vra_tenant
44
+
45
+
46
+ #
47
+ # The VRealize endpoint URL.
48
+ #
49
+ # @return [String]
50
+ attr_accessor :vra_base_url
51
+
52
+
53
+ #
54
+ attr_accessor :subtenant_id
55
+ attr_accessor :catalog_item_id
56
+ attr_accessor :requested_for, :cpus, :memory, :lease_days
57
+
58
+ def add_entries
59
+ yield @__extra_entries
60
+ end
61
+
62
+ def extra_entries
63
+ @__extra_entries
64
+ end
65
+
66
+ def validate(machine)
67
+ errors = _detected_errors()
68
+ validation_failures =
69
+ [
70
+ validate_vra_username(),
71
+ validate_vra_password(),
72
+ validate_vra_username(),
73
+ validate_vra_password(),
74
+ validate_vra_tenant(),
75
+ validate_vra_base_url(),
76
+ validate_requested_for(),
77
+ validate_subtenant_id(),
78
+ validate_catalog_item_id(),
79
+ validate_memory()
80
+ ].compact
81
+
82
+ validation_failures.each do |msg|
83
+ errors << msg
84
+ end
85
+
86
+ {'Vrealize provider' => errors}
87
+ end
88
+
89
+ private
90
+ def validate_cpu(errors)
91
+ errors << "cpus required" if @cpus == UNSET_VALUE ||
92
+ @cpus.nil? ||
93
+ @cpus == 0
94
+ end
95
+
96
+ def unset?(str)
97
+ @vra_username == UNSET_VALUE ||
98
+ @vra_username.nil? ||
99
+ @vra_username.empty?
100
+ end
101
+
102
+ def validate_vra_username
103
+ "vra_username required" if unset?(@vra_username)
104
+ end
105
+
106
+ def validate_vra_password
107
+ "vra_password required" if unset?(@vra_password)
108
+ end
109
+
110
+ def validate_vra_tenant
111
+ "vra_tenant required" if unset?(@vra_tenant)
112
+ end
113
+
114
+ def validate_vra_base_url
115
+ "vra_base_url required" if unset?(@vra_base_url)
116
+ end
117
+
118
+ def validate_requested_for
119
+ "requested_for required" if unset?(@requested_for)
120
+ end
121
+
122
+ def validate_subtenant_id
123
+ "subtenant_id required" if unset?(@subtenant_id)
124
+ end
125
+
126
+ def validate_catalog_item_id
127
+ "catalog_item_id required" if unset?(@catalog_item_id)
128
+ end
129
+
130
+ def validate_memory
131
+ "memory required" if @memory == UNSET_VALUE ||
132
+ @memory.nil? ||
133
+ @memory == 0
134
+ end
135
+
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,32 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Vrealize
5
+ module Errors
6
+ class VagrantVrealizeError < Vagrant::Errors::VagrantError
7
+ error_namespace("vagrant_vrealize.errors")
8
+ end
9
+
10
+ class InstanceReadyTimeout < VagrantVrealizeError
11
+ error_key(:instance_ready_timeout)
12
+ end
13
+
14
+ class InstancePackageError < VagrantVrealizeError
15
+ error_key(:instance_package_error)
16
+ end
17
+
18
+ class InstancePackageTimeout < VagrantVrealizeError
19
+ error_key(:instance_package_timeout)
20
+ end
21
+
22
+ class RsyncError < VagrantVrealizeError
23
+ error_key(:rsync_error)
24
+ end
25
+
26
+ class MkdirError < VagrantVrealizeError
27
+ error_key(:mkdir_error)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ # This class provides a little DSL for setting extra config entries
2
+ # in the Vagrantfile.
3
+ # It's used like so:
4
+ #
5
+ # config.vm.provider :vrealize do |vrealize|
6
+ # vrealize.add_entries do |extra_entries|
7
+ # extra_entries.string "provider-MyCustomSetting", "myCustomValue"
8
+ # end
9
+ # end
10
+ #
11
+ class ExtraEntries
12
+
13
+ LiteralTypes = %w{
14
+ boolean
15
+ decimal
16
+ integer
17
+ string
18
+ }
19
+
20
+ def initialize
21
+ @entries = Hash.new(){|h,k| h[k] = {}}
22
+ end
23
+
24
+ # This block defines a setter for each LiteralType.
25
+ # Use like this:
26
+ #
27
+ # extra_entries.string "foo", "bar"
28
+ #
29
+ # then retrieve with
30
+ #
31
+ # extra_entries.of_type("string") #=> [["foo", "bar"]]
32
+ #
33
+ LiteralTypes.each do |type|
34
+ define_method(type.to_sym) do |key,value|
35
+ @entries[type][key] = value
36
+ end
37
+ end
38
+
39
+ def of_type(type)
40
+ @entries[type] || []
41
+ end
42
+
43
+ def types
44
+ @entries.keys
45
+ end
46
+ end
@@ -0,0 +1,73 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant VRealize 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.2.0"
10
+ raise "The Vagrant VRealize plugin is only compatible with Vagrant 1.2+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module Vrealize
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "VRealize"
17
+ description <<-DESC
18
+ This plugin installs a provider that allows Vagrant to manage
19
+ machines in VMWare VRealize.
20
+ DESC
21
+
22
+ config(:vrealize, :provider) do
23
+ require_relative "config"
24
+ Config
25
+ end
26
+
27
+ provider(:vrealize, parallel: true) do
28
+ # Setup logging and i18n
29
+ setup_logging
30
+ setup_i18n
31
+
32
+ # Return the provider
33
+ require_relative "provider"
34
+ Provider
35
+ end
36
+
37
+ # This initializes the internationalization strings.
38
+ def self.setup_i18n
39
+ I18n.load_path << File.expand_path("locales/en.yml", Vrealize.source_root)
40
+ I18n.reload!
41
+ end
42
+
43
+ # This sets up our log level to be whatever VAGRANT_LOG is.
44
+ def self.setup_logging
45
+ require "log4r"
46
+
47
+ level = nil
48
+ begin
49
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
50
+ rescue NameError
51
+ # This means that the logging constant wasn't found,
52
+ # which is fine. We just keep `level` as `nil`. But
53
+ # we tell the user.
54
+ level = nil
55
+ end
56
+
57
+ # Some constants, such as "true" resolve to booleans, so the
58
+ # above error checking doesn't catch it. This will check to make
59
+ # sure that the log level is an integer, as Log4r requires.
60
+ level = nil if !level.is_a?(Integer)
61
+
62
+ # Set the logging level on all "vagrant" namespaced
63
+ # logs as long as we have a valid level.
64
+ if level
65
+ logger = Log4r::Logger.new("vagrant_vrealize")
66
+ logger.outputters = Log4r::Outputter.stderr
67
+ logger.level = level
68
+ logger = nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,52 @@
1
+ require "log4r"
2
+ require "vagrant"
3
+
4
+ require_relative './action'
5
+
6
+ module VagrantPlugins
7
+ module Vrealize
8
+ class Provider < Vagrant.plugin("2", :provider)
9
+ def initialize(machine)
10
+ @machine = machine
11
+ end
12
+
13
+ def action(name)
14
+ # Attempt to get the action method from the Action class if it
15
+ # exists, otherwise return nil to show that we don't support the
16
+ # given action.
17
+ action_method = "action_#{name}"
18
+ return Action.send(action_method) if Action.respond_to?(action_method)
19
+ nil
20
+ end
21
+
22
+ def ssh_info
23
+ # Run a custom action called "read_ssh_info" which does what it
24
+ # says and puts the resulting SSH info into the `:machine_ssh_info`
25
+ # key in the environment.
26
+ env = @machine.action("read_ssh_info")
27
+ env[:machine_ssh_info]
28
+ end
29
+
30
+ def state
31
+ # Run a custom action we define called "read_state" which does
32
+ # what it says. It puts the state in the `:machine_state_id`
33
+ # key in the environment.
34
+ env = @machine.action("read_state")
35
+
36
+ state_id = env[:machine_state_id]
37
+
38
+ # Get the short and long description
39
+ short = I18n.t("vagrant_vrealize.states.short_#{state_id}")
40
+ long = I18n.t("vagrant_vrealize.states.long_#{state_id}")
41
+
42
+ # Return the MachineState object
43
+ Vagrant::MachineState.new(state_id, short, long)
44
+ end
45
+
46
+ def to_s
47
+ id = @machine.id.nil? ? "new" : @machine.id
48
+ "Vrealize (#{id})"
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ module VagrantPlugins
2
+ module Vrealize
3
+ module Util
4
+ class Timer
5
+ # A basic utility method that times the execution of the given
6
+ # block and returns it.
7
+ def self.time
8
+ start_time = Time.now.to_f
9
+ yield
10
+ end_time = Time.now.to_f
11
+
12
+ end_time - start_time
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Vrealize
3
+ VERSION = '0.0.4'
4
+ end
5
+ end