vcloud-disk_launcher 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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +15 -0
- data/LICENSE +22 -0
- data/README.md +92 -0
- data/Rakefile +26 -0
- data/bin/vcloud-disk-launch +5 -0
- data/lib/vcloud/disk_launcher.rb +16 -0
- data/lib/vcloud/disk_launcher/cli.rb +89 -0
- data/lib/vcloud/disk_launcher/disk_launch.rb +43 -0
- data/lib/vcloud/disk_launcher/schema/disk_launch.rb +35 -0
- data/lib/vcloud/disk_launcher/version.rb +5 -0
- data/spec/erb_helper.rb +11 -0
- data/spec/integration/disk_launcher/data/single_disk.yaml.erb +4 -0
- data/spec/integration/disk_launcher/disk_launch_spec.rb +63 -0
- data/spec/integration/vcloud_tools_testing_config.yaml.template +3 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/vcloud/disk_launcher/cli_spec.rb +137 -0
- data/spec/vcloud/disk_launcher/disk_launch_schema_spec.rb +61 -0
- data/spec/vcloud/disk_launcher/disk_launch_spec.rb +56 -0
- data/vcloud-disk_launcher.gemspec +36 -0
- metadata +186 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c03fd0856daed7e31cbd131476ab8e0dab1cedbf
|
4
|
+
data.tar.gz: 6918130bc12fcfac4dcf2e362e33ed7a3e846f32
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 54edcf208c56dd58c8cc6c95e25018108883f873439cd9a68902cb9250bb67e5020d82b8b12d97ae30233ba18b2f15073f377f70a92ed033afb6ce8089bdd05f
|
7
|
+
data.tar.gz: cd882048431301863565dbeb1d8ea44fb246daa7e22129eeab0a33373c2f1ad5a22e93a7758847f5313f617c5f7170d9c264f6932a93c0f702e4759cb82ff3ad
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
if ENV['VCLOUD_TOOLS_TESTER_DEV_MASTER']
|
6
|
+
gem 'vcloud-tools-tester', :git => 'git@github.com:gds-operations/vcloud-tools-tester.git', :branch => 'master'
|
7
|
+
elsif ENV['VCLOUD_TOOLS_TESTER_LOCAL']
|
8
|
+
gem 'vcloud-tools-tester', :path => '../vcloud-tools-tester'
|
9
|
+
end
|
10
|
+
|
11
|
+
if ENV['VCLOUD_CORE_DEV_MASTER']
|
12
|
+
gem 'vcloud-core', :git => 'git@github.com:gds-operations/vcloud-core.git', :branch => 'master'
|
13
|
+
elsif ENV['VCLOUD_CORE_DEV_LOCAL']
|
14
|
+
gem 'vcloud-core', :path => '../vcloud-core'
|
15
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 GOV.UK
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, 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,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
vCloud Disk Launcher
|
2
|
+
====================
|
3
|
+
|
4
|
+
A tool that takes a YAML or JSON configuration file describing a list of
|
5
|
+
Independent Disks in a vCloud Director Organisation, and provisions them
|
6
|
+
as needed.
|
7
|
+
|
8
|
+
### Supports
|
9
|
+
|
10
|
+
- Configuration of multiple Independent Disks with:
|
11
|
+
- custom name
|
12
|
+
- custom size
|
13
|
+
- Basic idempotent operation - disks that already exist are skipped.
|
14
|
+
- Adds helper code to prevent creation of disks with the same name.
|
15
|
+
|
16
|
+
### Limitations
|
17
|
+
|
18
|
+
- Does not yet support configuration of the storage profile of an independent
|
19
|
+
disk. The default storage profile for the vDC is used.
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile:
|
24
|
+
|
25
|
+
gem 'vcloud-disk_launcher'
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
|
29
|
+
$ bundle
|
30
|
+
|
31
|
+
Or install it yourself as:
|
32
|
+
|
33
|
+
$ gem install vcloud-disk_launcher
|
34
|
+
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
`vcloud-disk_launch disk_list.yaml`
|
39
|
+
|
40
|
+
## Configuration schemas
|
41
|
+
|
42
|
+
Configuration schemas can be found in [`lib/vcloud/disk_launcher/schema/`][schema].
|
43
|
+
|
44
|
+
[schema]: /lib/vcloud/disk_launcher/schema
|
45
|
+
|
46
|
+
## Credentials
|
47
|
+
|
48
|
+
Please see the [vcloud-tools usage documentation](http://gds-operations.github.io/vcloud-tools/usage/).
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
57
|
+
|
58
|
+
## Other settings
|
59
|
+
|
60
|
+
vCloud Disk Launcher uses vCloud Core. If you want to use the latest version of
|
61
|
+
vCloud Core, or a local version, you can export some variables. See the Gemfile
|
62
|
+
for details.
|
63
|
+
|
64
|
+
## The vCloud API
|
65
|
+
|
66
|
+
vCloud Tools currently use version 5.1 of the [vCloud API](http://pubs.vmware.com/vcd-51/index.jsp?topic=%2Fcom.vmware.vcloud.api.doc_51%2FGUID-F4BF9D5D-EF66-4D36-A6EB-2086703F6E37.html). Version 5.5 may work but is not currently supported. You should be able to access the 5.1 API in a 5.5 environment, and this *is* currently supported.
|
67
|
+
|
68
|
+
The default version is defined in [Fog](https://github.com/fog/fog/blob/244a049918604eadbcebd3a8eaaf433424fe4617/lib/fog/vcloud_director/compute.rb#L32).
|
69
|
+
|
70
|
+
If you want to be sure you are pinning to 5.1, or use 5.5, you can set the API version to use in your fog file, e.g.
|
71
|
+
|
72
|
+
`vcloud_director_api_version: 5.1`
|
73
|
+
|
74
|
+
## Debugging
|
75
|
+
|
76
|
+
`export EXCON_DEBUG=true` - this will print out the API requests and responses.
|
77
|
+
|
78
|
+
`export DEBUG=true` - this will show you the stack trace when there is an exception instead of just the message.
|
79
|
+
|
80
|
+
## Testing
|
81
|
+
|
82
|
+
Run the default suite of tests (e.g. lint, unit, features):
|
83
|
+
|
84
|
+
bundle exec rake
|
85
|
+
|
86
|
+
Run the integration tests (slower and requires a real environment):
|
87
|
+
|
88
|
+
bundle exec rake integration
|
89
|
+
|
90
|
+
You need access to a suitable vCloud Director organization to run the
|
91
|
+
integration tests. See the [integration tests README](/spec/integration/README.md) for
|
92
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'gem_publisher'
|
3
|
+
|
4
|
+
task :default => [:rubocop, :spec]
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
7
|
+
# Set a bogus Fog credential, otherwise it's possible for the unit
|
8
|
+
# tests to accidentially run (and succeed against!) an actual
|
9
|
+
# environment, if Fog connection is not stubbed correctly.
|
10
|
+
ENV['FOG_CREDENTIAL'] = 'random_nonsense_owiejfoweijf'
|
11
|
+
task.pattern = FileList['spec/vcloud/**/*_spec.rb']
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Core::RakeTask.new(:integration) do |t|
|
15
|
+
t.pattern = FileList['spec/integration/**/*_spec.rb']
|
16
|
+
end
|
17
|
+
|
18
|
+
task :publish_gem do
|
19
|
+
gem = GemPublisher.publish_if_updated("vcloud-disk_launcher.gemspec", :rubygems)
|
20
|
+
puts "Published #{gem}" if gem
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rubocop/rake_task'
|
24
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
25
|
+
task.options = ['--lint']
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
require 'csv'
|
6
|
+
require 'open3'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
require 'vcloud/disk_launcher/version'
|
10
|
+
|
11
|
+
require 'vcloud/core'
|
12
|
+
|
13
|
+
require 'vcloud/disk_launcher/schema/disk_launch'
|
14
|
+
require 'vcloud/disk_launcher/disk_launch'
|
15
|
+
require 'vcloud/disk_launcher/cli'
|
16
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Vcloud
|
4
|
+
module DiskLauncher
|
5
|
+
class Cli
|
6
|
+
|
7
|
+
# Initiates parsing of the command-line arguments.
|
8
|
+
#
|
9
|
+
# @param argv_array [Array] Command-line arguments
|
10
|
+
# @return [void]
|
11
|
+
def initialize(argv_array)
|
12
|
+
@usage_text = nil
|
13
|
+
@config_file = nil
|
14
|
+
|
15
|
+
parse(argv_array)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Runs +Vcloud::DiskLauncher::DiskLaunch#run+ to create independent disks defined
|
19
|
+
# in +@config_file+, catching any exceptions to prevent printing a backtrace.
|
20
|
+
#
|
21
|
+
# @return [void]
|
22
|
+
def run
|
23
|
+
begin
|
24
|
+
Vcloud::DiskLauncher::DiskLaunch.new.run(@config_file)
|
25
|
+
rescue => error_msg
|
26
|
+
$stderr.puts(error_msg)
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def parse(args)
|
34
|
+
opt_parser = OptionParser.new do |opts|
|
35
|
+
examples_dir = File.absolute_path(
|
36
|
+
File.join(
|
37
|
+
File.dirname(__FILE__),
|
38
|
+
"..",
|
39
|
+
"..",
|
40
|
+
"..",
|
41
|
+
"examples",
|
42
|
+
File.basename($0),
|
43
|
+
))
|
44
|
+
|
45
|
+
opts.banner = <<-EOS
|
46
|
+
Usage: #{$0} [options] config_file
|
47
|
+
|
48
|
+
vcloud-disk-launch takes a configuration describing a list of Independent Disks in a vCloud Org
|
49
|
+
and tries to make it a reality.
|
50
|
+
|
51
|
+
See https://github.com/gds-operations/vcloud-tools for more info
|
52
|
+
|
53
|
+
Example configuration files can be found in:
|
54
|
+
#{examples_dir}
|
55
|
+
EOS
|
56
|
+
|
57
|
+
opts.separator ""
|
58
|
+
opts.separator "Options:"
|
59
|
+
|
60
|
+
opts.on("-h", "--help", "Print usage and exit") do
|
61
|
+
$stderr.puts opts
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on("--version", "Display version and exit") do
|
66
|
+
puts Vcloud::DiskLauncher::VERSION
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
@usage_text = opt_parser.to_s
|
72
|
+
begin
|
73
|
+
opt_parser.parse!(args)
|
74
|
+
rescue OptionParser::InvalidOption => e
|
75
|
+
exit_error_usage(e)
|
76
|
+
end
|
77
|
+
|
78
|
+
exit_error_usage("must supply config_file") unless args.size == 1
|
79
|
+
@config_file = args.first
|
80
|
+
end
|
81
|
+
|
82
|
+
def exit_error_usage(error)
|
83
|
+
$stderr.puts "#{$0}: #{error}"
|
84
|
+
$stderr.puts @usage_text
|
85
|
+
exit 2
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Vcloud
|
2
|
+
module DiskLauncher
|
3
|
+
class DiskLaunch
|
4
|
+
|
5
|
+
# Initializes instance variables.
|
6
|
+
#
|
7
|
+
# @return [void]
|
8
|
+
def initialize
|
9
|
+
@config_loader = Vcloud::Core::ConfigLoader.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Parses a configuration file and provisions the networks it defines.
|
13
|
+
#
|
14
|
+
# @param config_file [String] Path to a YAML or JSON-formatted configuration file
|
15
|
+
# @return [void]
|
16
|
+
def run(config_file = nil)
|
17
|
+
config = @config_loader.load_config(config_file, Vcloud::DiskLauncher::Schema::DISK_LAUNCH)
|
18
|
+
|
19
|
+
config[:independent_disks].each do |disk_config|
|
20
|
+
name = disk_config[:name]
|
21
|
+
vdc_name = disk_config[:vdc_name]
|
22
|
+
size = disk_config[:size]
|
23
|
+
begin
|
24
|
+
disk = Vcloud::Core::IndependentDisk.create(
|
25
|
+
Vcloud::Core::Vdc.get_by_name(vdc_name),
|
26
|
+
name,
|
27
|
+
size
|
28
|
+
)
|
29
|
+
rescue Vcloud::Core::IndependentDisk::DiskAlreadyExistsException
|
30
|
+
Vcloud::Core.logger.info(
|
31
|
+
"Disk '#{name}' already exists in vDC '#{vdc_name}'. Skipping"
|
32
|
+
)
|
33
|
+
next
|
34
|
+
end
|
35
|
+
Vcloud::Core.logger.info(
|
36
|
+
"Created disk '#{name}' in vDC #{vdc_name} successfully. (id: #{disk.id})"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Vcloud
|
2
|
+
module DiskLauncher
|
3
|
+
module Schema
|
4
|
+
|
5
|
+
DISK_LAUNCH = {
|
6
|
+
type: 'hash',
|
7
|
+
internals: {
|
8
|
+
independent_disks: {
|
9
|
+
type: 'array',
|
10
|
+
required: true,
|
11
|
+
allowed_empty: true,
|
12
|
+
each_element_is: {
|
13
|
+
type: 'hash',
|
14
|
+
internals: {
|
15
|
+
name: {
|
16
|
+
type: 'string',
|
17
|
+
required: true,
|
18
|
+
},
|
19
|
+
vdc_name: {
|
20
|
+
type: 'string',
|
21
|
+
required: true,
|
22
|
+
},
|
23
|
+
size: {
|
24
|
+
type: 'string',
|
25
|
+
required: true,
|
26
|
+
},
|
27
|
+
},
|
28
|
+
},
|
29
|
+
},
|
30
|
+
},
|
31
|
+
}
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/erb_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
class ErbHelper
|
2
|
+
def self.convert_erb_template_to_yaml test_namespace, input_erb_config
|
3
|
+
input_erb_config = input_erb_config
|
4
|
+
e = ERB.new(File.open(input_erb_config).read)
|
5
|
+
output_yaml_config = File.join(File.dirname(input_erb_config), "output_#{Time.now.strftime('%s')}.yaml")
|
6
|
+
File.open(output_yaml_config, 'w') { |f|
|
7
|
+
f.write e.result(OpenStruct.new(test_namespace).instance_eval { binding })
|
8
|
+
}
|
9
|
+
output_yaml_config
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pp'
|
3
|
+
require 'erb'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'vcloud/tools/tester'
|
6
|
+
|
7
|
+
describe Vcloud::DiskLauncher::DiskLaunch do
|
8
|
+
context "with minimum input setup" do
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
@disks_to_delete = []
|
12
|
+
@files_to_delete = []
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should create a single disk" do
|
16
|
+
test_data_1 = define_test_data
|
17
|
+
minimum_data_erb = File.join(File.dirname(__FILE__), 'data/single_disk.yaml.erb')
|
18
|
+
minimum_data_yaml = ErbHelper.convert_erb_template_to_yaml(test_data_1, minimum_data_erb)
|
19
|
+
@files_to_delete.push(minimum_data_yaml)
|
20
|
+
Vcloud::DiskLauncher::DiskLaunch.new.run(minimum_data_yaml)
|
21
|
+
|
22
|
+
created_disk = Vcloud::Core::IndependentDisk.get_by_name_and_vdc_name(
|
23
|
+
test_data_1[:disk_name],
|
24
|
+
test_data_1[:vdc_1_name]
|
25
|
+
)
|
26
|
+
@disks_to_delete.push(created_disk)
|
27
|
+
|
28
|
+
expect(created_disk).not_to be_nil
|
29
|
+
expect(created_disk.name).to eq(test_data_1[:disk_name])
|
30
|
+
end
|
31
|
+
|
32
|
+
after(:all) do
|
33
|
+
unless ENV['VCLOUD_TOOLS_RSPEC_NO_DELETE']
|
34
|
+
@files_to_delete.each do |file|
|
35
|
+
File.delete file
|
36
|
+
end
|
37
|
+
@disks_to_delete.each do |disk|
|
38
|
+
disk.destroy
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def define_test_data
|
46
|
+
|
47
|
+
config_file = File.join(File.dirname(__FILE__),
|
48
|
+
"../vcloud_tools_testing_config.yaml")
|
49
|
+
required_user_params = [
|
50
|
+
"vdc_1_name",
|
51
|
+
"vdc_2_name",
|
52
|
+
]
|
53
|
+
parameters = Vcloud::Tools::Tester::TestSetup.new(config_file, required_user_params).test_params
|
54
|
+
|
55
|
+
{
|
56
|
+
disk_name: "vcloud-disk_launcher-tests-#{Time.now.strftime('%s')}",
|
57
|
+
vdc_1_name: parameters.vdc_1_name,
|
58
|
+
vdc_2_name: parameters.vdc_2_name,
|
59
|
+
}
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# SimpleCov must run _first_ according to its README
|
2
|
+
if ENV['COVERAGE']
|
3
|
+
require 'simplecov'
|
4
|
+
|
5
|
+
# monkey-patch to prevent SimpleCov from reporting coverage percentage
|
6
|
+
class SimpleCov::Formatter::HTMLFormatter
|
7
|
+
def output_message(_message)
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
SimpleCov.adapters.define 'gem' do
|
13
|
+
add_filter '/spec/'
|
14
|
+
add_filter '/features/'
|
15
|
+
add_filter '/vendor/'
|
16
|
+
|
17
|
+
add_group 'Libraries', '/lib/'
|
18
|
+
end
|
19
|
+
|
20
|
+
SimpleCov.minimum_coverage(99)
|
21
|
+
SimpleCov.start 'gem'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'erb_helper'
|
25
|
+
require 'vcloud/disk_launcher'
|
26
|
+
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.expect_with :rspec do |c|
|
29
|
+
c.syntax = :expect
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class CommandRun
|
4
|
+
attr_accessor :stdout, :stderr, :exitstatus
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
out = StringIO.new
|
8
|
+
err = StringIO.new
|
9
|
+
|
10
|
+
$stdout = out
|
11
|
+
$stderr = err
|
12
|
+
|
13
|
+
begin
|
14
|
+
Vcloud::DiskLauncher::Cli.new(args).run
|
15
|
+
@exitstatus = 0
|
16
|
+
rescue SystemExit => e
|
17
|
+
# Capture exit(n) value.
|
18
|
+
@exitstatus = e.status
|
19
|
+
end
|
20
|
+
|
21
|
+
@stdout = out.string.strip
|
22
|
+
@stderr = err.string.strip
|
23
|
+
|
24
|
+
$stdout = STDOUT
|
25
|
+
$stderr = STDERR
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Vcloud::DiskLauncher::Cli do
|
30
|
+
subject { CommandRun.new(args) }
|
31
|
+
|
32
|
+
let(:mock_disk_launch) {
|
33
|
+
double(:disk_launch, :run => true)
|
34
|
+
}
|
35
|
+
let(:config_file) { 'config.yaml' }
|
36
|
+
|
37
|
+
describe "under normal usage" do
|
38
|
+
shared_examples "a good CLI command" do
|
39
|
+
it "passes the right CLI options and exits normally" do
|
40
|
+
expect(Vcloud::DiskLauncher::DiskLaunch).to receive(:new).
|
41
|
+
and_return(mock_disk_launch)
|
42
|
+
expect(mock_disk_launch).to receive(:run).
|
43
|
+
with(config_file)
|
44
|
+
expect(subject.exitstatus).to eq(0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when given a single config file" do
|
49
|
+
let(:args) { [ config_file ] }
|
50
|
+
|
51
|
+
it_behaves_like "a good CLI command"
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when asked to display version" do
|
55
|
+
let(:args) { %w{--version} }
|
56
|
+
|
57
|
+
it "does not call DiskLaunch" do
|
58
|
+
expect(Vcloud::DiskLauncher::DiskLaunch).not_to receive(:new)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "prints version and exits normally" do
|
62
|
+
expect(subject.stdout).to eq(Vcloud::DiskLauncher::VERSION)
|
63
|
+
expect(subject.exitstatus).to eq(0)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when asked to display help" do
|
68
|
+
let(:args) { %w{--help} }
|
69
|
+
|
70
|
+
it "does not call DiskLaunch" do
|
71
|
+
expect(Vcloud::DiskLauncher::DiskLaunch).not_to receive(:new)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "prints usage and exits normally" do
|
75
|
+
expect(subject.stderr).to match(/\AUsage: \S+ \[options\] config_file\n/)
|
76
|
+
expect(subject.exitstatus).to eq(0)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "incorrect usage" do
|
82
|
+
shared_examples "print usage and exit abnormally" do |error|
|
83
|
+
it "does not call DiskLaunch" do
|
84
|
+
expect(Vcloud::DiskLauncher::DiskLaunch).not_to receive(:new)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "prints error message and usage" do
|
88
|
+
expect(subject.stderr).to match(/\A\S+: #{error}\nUsage: \S+/)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "exits abnormally for incorrect usage" do
|
92
|
+
expect(subject.exitstatus).to eq(2)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when run without any arguments" do
|
97
|
+
let(:args) { %w{} }
|
98
|
+
|
99
|
+
it_behaves_like "print usage and exit abnormally", "must supply config_file"
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when given multiple config files" do
|
103
|
+
let(:args) { %w{one.yaml two.yaml} }
|
104
|
+
|
105
|
+
it_behaves_like "print usage and exit abnormally", "must supply config_file"
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when given an unrecognised argument" do
|
109
|
+
let(:args) { %w{--this-is-garbage} }
|
110
|
+
|
111
|
+
it_behaves_like "print usage and exit abnormally", "invalid option: --this-is-garbage"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "error handling" do
|
116
|
+
context "when underlying code raises an exception" do
|
117
|
+
let(:args) { %w{test.yaml} }
|
118
|
+
|
119
|
+
it "should print error without backtrace and exit abnormally" do
|
120
|
+
expect(Vcloud::DiskLauncher::DiskLaunch).to receive(:new).
|
121
|
+
and_raise("something went horribly wrong")
|
122
|
+
expect(subject.stderr).to eq("something went horribly wrong")
|
123
|
+
expect(subject.exitstatus).to eq(1)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "when passed an non-existent configuration file" do
|
128
|
+
let(:args) { %w{non-existent.yaml} }
|
129
|
+
|
130
|
+
it "raises a descriptive error" do
|
131
|
+
# Use a regex match as a workaround to https://bugs.ruby-lang.org/issues/9285
|
132
|
+
expect(subject.stderr).to match(/\ANo such file or directory/)
|
133
|
+
expect(subject.exitstatus).to eq(1)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vcloud::DiskLauncher do
|
4
|
+
|
5
|
+
context "DiskLaunch schema validation" do
|
6
|
+
|
7
|
+
it "validates a legal minimal schema" do
|
8
|
+
test_config = {
|
9
|
+
:independent_disks => [
|
10
|
+
:name => "Valid disk name",
|
11
|
+
:vdc_name => "Some vDC",
|
12
|
+
:size => "10GB"
|
13
|
+
]
|
14
|
+
}
|
15
|
+
validator = Vcloud::Core::ConfigValidator.validate(:base, test_config, Vcloud::DiskLauncher::Schema::DISK_LAUNCH)
|
16
|
+
expect(validator.valid?).to be_true
|
17
|
+
expect(validator.errors).to be_empty
|
18
|
+
end
|
19
|
+
|
20
|
+
it "validates a multiple disks" do
|
21
|
+
test_config = {
|
22
|
+
:independent_disks => [
|
23
|
+
{
|
24
|
+
:name => "Valid disk 1",
|
25
|
+
:vdc_name => "Some vDC",
|
26
|
+
:size => "10GB"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
:name => "Valid disk 2",
|
30
|
+
:vdc_name => "Another vDC",
|
31
|
+
:size => "500MB"
|
32
|
+
},
|
33
|
+
]
|
34
|
+
}
|
35
|
+
validator = Vcloud::Core::ConfigValidator.validate(:base, test_config, Vcloud::DiskLauncher::Schema::DISK_LAUNCH)
|
36
|
+
expect(validator.valid?).to be_true
|
37
|
+
expect(validator.errors).to be_empty
|
38
|
+
end
|
39
|
+
|
40
|
+
it "validates an empty disk list" do
|
41
|
+
test_config = {
|
42
|
+
:independent_disks => []
|
43
|
+
}
|
44
|
+
validator = Vcloud::Core::ConfigValidator.validate(:base, test_config, Vcloud::DiskLauncher::Schema::DISK_LAUNCH)
|
45
|
+
expect(validator.valid?).to be_true
|
46
|
+
expect(validator.errors).to be_empty
|
47
|
+
end
|
48
|
+
|
49
|
+
it "does not validate an illegal schema" do
|
50
|
+
test_config = {
|
51
|
+
:no_disks_here => {
|
52
|
+
:name => "I am not valid"
|
53
|
+
}
|
54
|
+
}
|
55
|
+
validator = Vcloud::Core::ConfigValidator.validate(:base, test_config, Vcloud::DiskLauncher::Schema::DISK_LAUNCH)
|
56
|
+
expect(validator.valid?).to be_false
|
57
|
+
expect(validator.errors).to eq(["base: parameter 'no_disks_here' is invalid", "base: missing 'independent_disks' parameter"])
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vcloud::DiskLauncher::DiskLaunch do
|
4
|
+
|
5
|
+
context "ConfigLoader returns two different disks" do
|
6
|
+
let(:disk1) {
|
7
|
+
{
|
8
|
+
:name => 'Test Disk 1',
|
9
|
+
:vdc_name => 'TestVDC 1',
|
10
|
+
:size => '500MB',
|
11
|
+
}
|
12
|
+
}
|
13
|
+
let(:disk2) {
|
14
|
+
{
|
15
|
+
:name => 'Test Disk 2',
|
16
|
+
:vdc_name => 'TestVDC 2',
|
17
|
+
:size => '10GiB',
|
18
|
+
}
|
19
|
+
}
|
20
|
+
let(:mock_vdc_1) { double(:mock_vdc, :name => "TestVDC 1") }
|
21
|
+
let(:mock_vdc_2) { double(:mock_vdc, :name => "TestVDC 2") }
|
22
|
+
let(:mock_disk_1) { double(:mock_disk_1, :id => "12341234-1234-1234-1234-123455550001") }
|
23
|
+
let(:mock_disk_2) { double(:mock_disk_2, :id => "12341234-1234-1234-1234-123455550002") }
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
config_loader = double(:config_loader)
|
27
|
+
expect(Vcloud::Core::Vdc).to receive(:get_by_name).with("TestVDC 1").and_return(mock_vdc_1)
|
28
|
+
expect(Vcloud::Core::Vdc).to receive(:get_by_name).with("TestVDC 2").and_return(mock_vdc_2)
|
29
|
+
expect(Vcloud::Core::ConfigLoader).to receive(:new).and_return(config_loader)
|
30
|
+
expect(config_loader).to receive(:load_config).and_return({
|
31
|
+
:independent_disks => [disk1, disk2]
|
32
|
+
})
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should call Core::IndependentDisk.create once for each disk" do
|
36
|
+
expect(Vcloud::Core::IndependentDisk).
|
37
|
+
to receive(:create).with(mock_vdc_1, disk1[:name], disk1[:size]).and_return(mock_disk_1)
|
38
|
+
expect(Vcloud::Core::IndependentDisk).
|
39
|
+
to receive(:create).with(mock_vdc_2, disk2[:name], disk2[:size]).and_return(mock_disk_2)
|
40
|
+
expect(Vcloud::Core.logger).to receive(:info).exactly(2).times
|
41
|
+
subject.run('input_config_yaml')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "will still create disk2 if disk1 already exists (skipping disk1)" do
|
45
|
+
expect(Vcloud::Core::IndependentDisk).
|
46
|
+
to receive(:create).with(mock_vdc_1, disk1[:name], disk1[:size]).
|
47
|
+
and_raise(Vcloud::Core::IndependentDisk::DiskAlreadyExistsException)
|
48
|
+
expect(Vcloud::Core::IndependentDisk).
|
49
|
+
to receive(:create).with(mock_vdc_2, disk2[:name], disk2[:size]).and_return(mock_disk_2)
|
50
|
+
expect(Vcloud::Core.logger).to receive(:info).exactly(2).times
|
51
|
+
subject.run('input_config_yaml')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib/', __FILE__)
|
4
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'vcloud/disk_launcher/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.name = 'vcloud-disk_launcher'
|
10
|
+
s.version = Vcloud::DiskLauncher::VERSION
|
11
|
+
s.authors = ['Mike Pountney']
|
12
|
+
s.email = ['Mike.Pountney@gmail.com']
|
13
|
+
s.summary = 'Tool to launch and configure vCloud Independent Disks'
|
14
|
+
s.description = 'Tool to launch and configure vCloud Independent Disks. Uses vcloud-core.'
|
15
|
+
s.homepage = 'http://github.com/alphagov/vcloud-disk_launcher'
|
16
|
+
s.license = 'MIT'
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split($/)
|
19
|
+
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename(f)}
|
20
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
21
|
+
s.require_paths = ['lib']
|
22
|
+
|
23
|
+
s.required_ruby_version = '>= 1.9.3'
|
24
|
+
|
25
|
+
s.add_runtime_dependency 'vcloud-core', '~> 0.15.0'
|
26
|
+
s.add_development_dependency 'gem_publisher', '1.2.0'
|
27
|
+
s.add_development_dependency 'pry'
|
28
|
+
s.add_development_dependency 'rake'
|
29
|
+
s.add_development_dependency 'rspec', '~> 2.14.1'
|
30
|
+
s.add_development_dependency 'rubocop', '~> 0.23.0'
|
31
|
+
# Pin SimpleCov to < 0.8.x until this issue is resolved:
|
32
|
+
# https://github.com/colszowka/simplecov/issues/281
|
33
|
+
s.add_development_dependency 'simplecov', '~> 0.7.1'
|
34
|
+
s.add_development_dependency 'vcloud-tools-tester', '~> 0.3.0'
|
35
|
+
end
|
36
|
+
|
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vcloud-disk_launcher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Pountney
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: vcloud-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.15.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.15.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: gem_publisher
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.14.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.14.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.23.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.23.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.7.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.7.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: vcloud-tools-tester
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.3.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.3.0
|
125
|
+
description: Tool to launch and configure vCloud Independent Disks. Uses vcloud-core.
|
126
|
+
email:
|
127
|
+
- Mike.Pountney@gmail.com
|
128
|
+
executables:
|
129
|
+
- vcloud-disk-launch
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- CHANGELOG.md
|
135
|
+
- Gemfile
|
136
|
+
- LICENSE
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- bin/vcloud-disk-launch
|
140
|
+
- lib/vcloud/disk_launcher.rb
|
141
|
+
- lib/vcloud/disk_launcher/cli.rb
|
142
|
+
- lib/vcloud/disk_launcher/disk_launch.rb
|
143
|
+
- lib/vcloud/disk_launcher/schema/disk_launch.rb
|
144
|
+
- lib/vcloud/disk_launcher/version.rb
|
145
|
+
- spec/erb_helper.rb
|
146
|
+
- spec/integration/disk_launcher/data/single_disk.yaml.erb
|
147
|
+
- spec/integration/disk_launcher/disk_launch_spec.rb
|
148
|
+
- spec/integration/vcloud_tools_testing_config.yaml.template
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- spec/vcloud/disk_launcher/cli_spec.rb
|
151
|
+
- spec/vcloud/disk_launcher/disk_launch_schema_spec.rb
|
152
|
+
- spec/vcloud/disk_launcher/disk_launch_spec.rb
|
153
|
+
- vcloud-disk_launcher.gemspec
|
154
|
+
homepage: http://github.com/alphagov/vcloud-disk_launcher
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 1.9.3
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.2.2
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: Tool to launch and configure vCloud Independent Disks
|
178
|
+
test_files:
|
179
|
+
- spec/erb_helper.rb
|
180
|
+
- spec/integration/disk_launcher/data/single_disk.yaml.erb
|
181
|
+
- spec/integration/disk_launcher/disk_launch_spec.rb
|
182
|
+
- spec/integration/vcloud_tools_testing_config.yaml.template
|
183
|
+
- spec/spec_helper.rb
|
184
|
+
- spec/vcloud/disk_launcher/cli_spec.rb
|
185
|
+
- spec/vcloud/disk_launcher/disk_launch_schema_spec.rb
|
186
|
+
- spec/vcloud/disk_launcher/disk_launch_spec.rb
|