vaquero_io 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,118 @@
1
+ Feature: New platform definition files for specified provider
2
+
3
+ As an Infracoder developing the vaquero command line tool
4
+ I want to test the ability to create platform definition template files for a provider
5
+ In order to assist the user in creating and maintaining definition files for product platforms
6
+
7
+ Scenario: Request help with NEW commands
8
+
9
+ When I run `vaquero help new`
10
+ Then the exit status should be 0
11
+ And the output should contain "Usage:"
12
+ And the output should contain "new"
13
+
14
+
15
+ Scenario: Create new platform definition file based on current provider
16
+
17
+ Given a file named "../../lib/providers/vaquero-test-a/Providerfile.yml" with:
18
+ """
19
+ provider:
20
+ name: vaquero-test-a
21
+ version: 0.1.0
22
+ location:
23
+
24
+ structure:
25
+
26
+ require:
27
+ - file1
28
+ - file2
29
+ - file3
30
+
31
+ platform:
32
+ path:
33
+ params:
34
+ count:
35
+ type: integer
36
+ range: 1..100
37
+ runlist:
38
+ array:
39
+ type: string
40
+ match: 'regex'
41
+ componentrole:
42
+ type: string
43
+ match: 'regex'
44
+ chefserver:
45
+ type: string
46
+ match: 'regex'
47
+
48
+ file1:
49
+ path: 'folder1/'
50
+ params:
51
+ location:
52
+ type: string
53
+ match: 'regex'
54
+ host:
55
+ type: string
56
+ match: 'regex'
57
+
58
+ file2:
59
+ path: 'folder1/'
60
+ params:
61
+ vlanid:
62
+ type: string
63
+ match: 'regex'
64
+ gateway:
65
+ type: IP
66
+ netmask:
67
+ type: integer
68
+ range: 1..24
69
+
70
+ file3:
71
+ path: 'folder2/'
72
+ params:
73
+ ram:
74
+ type: integer
75
+ range: 128..262144
76
+ cpu:
77
+ type: integer
78
+ range: 1..16
79
+ drive:
80
+ hash:
81
+ mount:
82
+ type: string
83
+ match: 'regex'
84
+ capacity:
85
+ type: integer
86
+ range: 8..2048
87
+ image:
88
+ type: string
89
+ match: 'regex'
90
+ """
91
+ Given a file named "../../lib/providers/vaquero-test-a/templates/platform.yml" with:
92
+ """
93
+ platform:
94
+ """
95
+ Given a file named "../../lib/providers/vaquero-test-a/templates/file1.yml" with:
96
+ """
97
+ file1:
98
+ """
99
+ Given a file named "../../lib/providers/vaquero-test-a/templates/file2.yml" with:
100
+ """
101
+ file2:
102
+ """
103
+ Given a file named "../../lib/providers/vaquero-test-a/templates/file3.yml" with:
104
+ """
105
+ file3:
106
+ """
107
+ Given a file named "../../lib/providers/vaquero-test-a/vaquero_test_a.rb" with:
108
+ """
109
+ """
110
+ When I run `vaquero new --provider vaquero-test-a`
111
+ Then the exit status should be 0
112
+ And the output should contain "Platform definition files successfully created"
113
+ And the following files should exist:
114
+ |platform.yml|
115
+ |folder1/file1.yml|
116
+ |folder1/file2.yml|
117
+ |folder2/file3.yml|
118
+ And I will clean up the test plugin "lib/providers/vaquero-test-a" when finished
@@ -0,0 +1,138 @@
1
+ Feature: Provider plugin modules
2
+
3
+ As an Infracoder developing the vaquero command line tool
4
+ I want to test the accuracy of the Provider plugin interactions for the PLUGIN command
5
+ In order to maintain the users ability to use and create provider plugins for custom infrastructure targets
6
+
7
+ Scenario: Request help with PLUGIN commands
8
+
9
+ When I get general help for "vaquero plugin"
10
+ Then the exit status should be 0
11
+ And the following commands should be documented:
12
+ |help|
13
+ |list|
14
+ |init|
15
+ |install|
16
+ |update|
17
+ |remove|
18
+
19
+ Scenario: List installed Providers
20
+
21
+ Given a file named "../../lib/providers/vaquero-test-a/Providerfile.yml" with:
22
+ """
23
+ provider:
24
+ name: test-installed-a
25
+ version: 0.0.0.a
26
+ """
27
+ Given a file named "../../lib/providers/vaquero-test-b/Providerfile.yml" with:
28
+ """
29
+ provider:
30
+ name: test-installed-b
31
+ version: 0.0.0.b
32
+ """
33
+ When I run `vaquero plugin list`
34
+ Then the exit status should be 0
35
+ And the output should contain "test-installed-a (0.0.0.a)"
36
+ And the output should contain "test-installed-b (0.0.0.b)"
37
+ And I will clean up the test plugin "lib/providers/vaquero-test-a" when finished
38
+ And I will clean up the test plugin "lib/providers/vaquero-test-b" when finished
39
+
40
+ Scenario: New Providerfile template
41
+
42
+ When I run `vaquero plugin init`
43
+ Then the exit status should be 0
44
+ And the output should contain "create Providerfile.yml"
45
+ And the following files should exist:
46
+ |Providerfile.yml|
47
+ And the file "Providerfile.yml" should contain:
48
+ """
49
+ provider:
50
+ # define the plugin name that can be used to select this provider from the command line or environmental variable
51
+ name:
52
+ version: 0.0.0
53
+ """
54
+
55
+ When I run `vaquero plugin init example`
56
+ Then the exit status should be 0
57
+ And the output should contain "called with arguments"
58
+
59
+ Scenario: Install new Provider
60
+
61
+ When I run `vaquero plugin install`
62
+ Then the exit status should be 0
63
+ And the output should contain "called with no arguments"
64
+
65
+ When I run `vaquero plugin install https://github.com/vaquero-io/vaquero_io-plugin-test.git`
66
+ Then the exit status should be 0
67
+ And the output should contain "Successfully installed vaquero_io-plugin-test"
68
+ And the following files should exist:
69
+ |../../lib/providers/vaquero_io-plugin-test/Providerfile.yml|
70
+ |../../lib/providers/vaquero_io-plugin-test/vaquero_io_plugin_test.rb|
71
+ And the file "../../lib/providers/vaquero_io-plugin-test/Providerfile.yml" should contain:
72
+ """
73
+ provider:
74
+ name: vaquero_io-plugin-test
75
+ version: 0.1.1
76
+ location: https://github.com/vaquero-io/vaquero_io-plugin-test.git
77
+ """
78
+ And I will clean up the test plugin "lib/providers/vaquero_io-plugin-test" when finished
79
+
80
+ Given a file named "../../lib/providers/vaquero_io-plugin-test/Providerfile.yml" with:
81
+ """
82
+ provider:
83
+ name: vaquero_io-plugin-test
84
+ version: 0.1.1
85
+ location: https://github.com/vaquero-io/vaquero_io-plugin-test.git
86
+ """
87
+ When I run `vaquero plugin install https://github.com/vaquero-io/vaquero_io-plugin-test.git`
88
+ Then the exit status should be 0
89
+ And the output should contain "vaquero_io-plugin-test already installed"
90
+ And I will clean up the test plugin "lib/providers/vaquero_io-plugin-test" when finished
91
+
92
+ Scenario: Update installed Provider(s)
93
+
94
+ Given a file named "../../lib/providers/vaquero_io-plugin-test/Providerfile.yml" with:
95
+ """
96
+ provider:
97
+ name: vaquero_io-plugin-test
98
+ version: 0.1.1
99
+ location: https://github.com/vaquero-io/vaquero_io-plugin-test.git
100
+ """
101
+ When I run `vaquero plugin update vaquero_io-plugin-test`
102
+ Then the exit status should be 0
103
+ And the output should contain "vaquero_io-plugin-test provider already at current version"
104
+ And I will clean up the test plugin "lib/providers/vaquero_io-plugin-test" when finished
105
+
106
+ Given a file named "../../lib/providers/vaquero_io-plugin-test/Providerfile.yml" with:
107
+ """
108
+ provider:
109
+ name: vaquero_io-plugin-test
110
+ version: 0.0.0
111
+ location: https://github.com/vaquero-io/vaquero_io-plugin-test.git
112
+ """
113
+ When I run `vaquero plugin update vaquero_io-plugin-test`
114
+ Then the exit status should be 0
115
+ And the output should contain "Updated vaquero_io-plugin-test version 0.0.0 -> 0.1.1"
116
+ And I will clean up the test plugin "lib/providers/vaquero_io-plugin-test" when finished
117
+
118
+ Scenario: Remove Provider
119
+
120
+ When I run `vaquero plugin remove`
121
+ Then the exit status should be 0
122
+ And the output should contain "called with no arguments"
123
+
124
+ When I run `vaquero plugin remove vaquero_io-plugin-test`
125
+ Then the exit status should be 1
126
+ And the output should contain "Missing or invalid Providerfile"
127
+
128
+ Given a file named "../../lib/providers/vaquero_io-plugin-test/Providerfile.yml" with:
129
+ """
130
+ provider:
131
+ name: vaquero_io-plugin-test
132
+ version: 0.1.1
133
+ location: https://github.com/vaquero-io/vaquero_io-plugin-test.git
134
+ """
135
+ When I run `vaquero plugin remove vaquero_io-plugin-test`
136
+ Then the exit status should be 0
137
+ And the output should contain "vaquero_io-plugin-test removed"
138
+ And I will clean up the test plugin "lib/providers/vaquero_io-plugin-test" when finished
@@ -0,0 +1,43 @@
1
+ require 'fileutils'
2
+ # rubocop:disable LineLength, StringLiterals
3
+ When(/^I get general help for "([^"]*)"$/) do |app_name|
4
+ @app_name = app_name
5
+ step %(I run `#{app_name} --help`)
6
+ step %(I run `#{app_name}`)
7
+ end
8
+
9
+ Then(/^the banner should be present$/) do
10
+ step %(the output should match /vaquero_io commands:/)
11
+ end
12
+
13
+ Then(/^the following commands should be documented:$/) do |options|
14
+ options.raw.each do |option|
15
+ step %(the command "#{option[0]}" should be documented)
16
+ end
17
+ end
18
+
19
+ Then(/^the command "([^"]*)" should be documented$/) do |options|
20
+ options.split(',').map(&:strip).each do |option|
21
+ step %(the output should match /\\s*#{Regexp.escape(option)}[\\s\\W]+\\w[\\s\\w][\\s\\w]+/)
22
+ end
23
+ end
24
+
25
+ Then(/^the output should display the version$/) do
26
+ step %(the output should match /\\d+\\.\\d+\\.\\d+/)
27
+ end
28
+
29
+ Then(/^I will clean up the test plugin "([^"]*)" when finished$/) do |plugin|
30
+ puts plugin
31
+ puts Dir.pwd
32
+ FileUtils.remove_dir(plugin) if File.file?("#{plugin}/Providerfile.yml")
33
+ end
34
+
35
+ # Then(/^I will clean up the test plugin "([^"]*)" when finished$/) do |plugin|
36
+ # FileUtils.remove_dir('lib/providers/vaquero_io-plugin-test') if File.file?('lib/providers/vaquero_io-plugin-test/Providerfile.yml')
37
+ # end
38
+
39
+ # Given(/^I have cleaned up the test plugin$/) do
40
+ # FileUtils.remove_dir('lib/providers/vaquero_io-plugin-test') if File.file?('lib/providers/vaquero_io-plugin-test/Providerfile.yml')
41
+ # end
42
+
43
+ # rubocop:enable LineLength, StringLiterals
@@ -0,0 +1,11 @@
1
+ require 'aruba/cucumber'
2
+ require 'aruba/in_process'
3
+ require 'vaquero_io/runner'
4
+ require 'coveralls'
5
+
6
+ ENV['PATH'] = "/lib#{File::PATH_SEPARATOR}#{ENV['PATH']}"
7
+
8
+ Coveralls.wear!
9
+
10
+ Aruba::InProcess.main_class = VaqueroIo::Runner
11
+ Aruba.process = Aruba::InProcess
@@ -0,0 +1,28 @@
1
+ Feature: Behavior of CLI with general features and commands
2
+
3
+ As an Infracoder developing a command line tool
4
+ I need to have the basic structure of the tool created
5
+ In order to engage in the BDD of the tool
6
+
7
+ Scenario: Request help with commands
8
+
9
+ When I get general help for "vaquero"
10
+ Then the exit status should be 0
11
+ And the banner should be present
12
+ And the following commands should be documented:
13
+ |help|
14
+ |version|
15
+ |plugin|
16
+ |new|
17
+
18
+ Scenario: Display gem version
19
+
20
+ When I run `vaquero -v`
21
+ Then the output should display the version
22
+
23
+ # commands
24
+ #
25
+ # $vaquero new <appname>, create yml folder structure for new platform definition
26
+ # $vaquero generate <environment>, generate new environment yml for current platform
27
+ # $vaquero validate [-e <env>, -p] no param is all, -e is specific env, -p is platform files only
28
+ # $vaquero build
@@ -0,0 +1,130 @@
1
+ module VaqueroIo
2
+ # Instantiates the platform
3
+ # builds the environment hash then
4
+ # passes to provider plugin
5
+ class Build < Thor::Group
6
+ include Thor::Actions
7
+
8
+ # Build subcommand arguments and options
9
+ # rubocop:disable LineLength
10
+ argument :env, type: :string, desc: DESC_BUILD
11
+ class_option :all, type: :boolean, aliases: '-a', desc: DESC_BUILD_ALL
12
+ class_option :component, type: :string, aliases: '-c', desc: DESC_BUILD_COMPONENT
13
+ class_option :node, type: :string, aliases: '-n', desc: DESC_BUILD_NODE
14
+ class_option :named_nodes, type: :boolean, default: true
15
+ class_option :verbose, type: :boolean, aliases: '-v', default: false
16
+ class_option :provider, type: :string, aliases: '-p'
17
+ class_option :verify_ssl, type: :boolean, default: nil
18
+ class_option :dry_run, type: :boolean, default: false
19
+ class_option :provider_username, type: :string, default: nil
20
+ class_option :provider_password, type: :string, default: nil
21
+ class_option :provider_options, type: :string, default: nil
22
+
23
+ # TODO: we don't have a tier definition any longer
24
+ # class_option :tier, type: :string, aliases: '-t', desc: DESC_BUILD_TIER
25
+ # TODO: Concurrency is an aspect of the provisioner not the tool so somehow you
26
+ # have to find a way to pass/set any kind of provider required options that is plugin agnostic
27
+ # class_option :concurrency, type: :numeric, aliases: '-C', default: 8, desc: DESC_BUILD_CONCURRENCY
28
+ # TODO: What to do about logfiles?
29
+ # class_option :logfiles, type: :string, aliases: '-l', default: 'logs', desc: DESC_BUILD_LOGFILES
30
+ # rubocop:enable LineLength
31
+
32
+ def self.source_root
33
+ File.dirname(__FILE__)
34
+ end
35
+
36
+ # rubocop:disable MethodLength, LineLength, CyclomaticComplexity, PerceivedComplexity
37
+
38
+ def build
39
+ # TODO: Initially, i am just passing the entire
40
+ # environment hash to the plugin
41
+ # But this can be further broken down based on parameters passed to build
42
+ provider = options[:provider] ? VaqueroIo::Provider.new(options[:provider]) : nil
43
+
44
+ plat = VaqueroIo::Platform.new(provider)
45
+
46
+ env_build = plat.environment(env)
47
+
48
+ if env_build.nil?
49
+ puts ''
50
+ puts "Platform #{plat.product} definition handed us a nil object for environment #{env}"
51
+ puts 'Cowardly refusing to build invalid environment definition!'
52
+ puts ''
53
+ fail(IOError, "Validation of platform #{plat.product} environment #{env} failed.")
54
+ end
55
+
56
+ # here we figure out what to cut
57
+
58
+ # If we're requesting a single component, we'll just do that.
59
+ if options[:component]
60
+ comp = options[:component]
61
+ unless env_build['components'][comp]
62
+ fail(IOError, "Requested component #{comp} not found in environment #{env}")
63
+ end
64
+ env_build['components'] = { comp => env_build['components'][comp] }
65
+ if options[:node]
66
+ node_list = []
67
+ node_max = env_build['components'][comp]['count']
68
+ options[:node].split(/,/).each do |n|
69
+ fail(IOError, "Requested node (#{n}) greater than component count (#{node_max})") if n.to_i > node_max.to_i
70
+ node_list << env_build['components'][comp]['nodes'][n.to_i - 1]
71
+ end
72
+
73
+ env_build['components'][comp]['nodes'] = node_list
74
+ env_build['components'][comp]['count'] = node_list.size
75
+ end
76
+ end
77
+
78
+ # Parse provider options from key1=val1,key2=val2 to a hash
79
+ provider_options = {}
80
+ options[:provider_options].split(/,/).each do |keyval|
81
+ key, value = keyval.split(/=/)
82
+ # Convert the key to a symbol
83
+ key = key.to_sym
84
+ # Do some quick checks for obvious boolean values
85
+ case value.downcase
86
+ when 'true'
87
+ value = true
88
+ when 'false'
89
+ value = false
90
+ end
91
+ provider_options[key] = value
92
+ end if options[:provider_options]
93
+
94
+ # Provision
95
+ provider_options = {
96
+ username: options[:provider_username],
97
+ password: options[:provider_password],
98
+ named_nodes: options[:named_nodes],
99
+ verify_ssl: options[:verify_ssl],
100
+ dry_run: options[:dry_run]
101
+ }.merge(provider_options)
102
+
103
+ if options[:dry_run]
104
+ puts "\nDry run only, will not do anything!\n"
105
+ puts "Calling provider #{provider} with options:"
106
+ provider_options.each { |k, v| puts " - '#{k}' = '#{v}'" }
107
+ end
108
+ puts "\nBuilding:"
109
+ puts " Product: #{plat.product}"
110
+ puts " Environment: #{env_build['environment']}"
111
+ puts ' Components:'
112
+ env_build['components'].each do |name, component|
113
+ print " - #{name}"
114
+ component['nodes'].each_with_index do |n, i|
115
+ print ' (' if i == 0
116
+ print n
117
+ if i == component['nodes'].size - 1
118
+ puts ')'
119
+ else
120
+ print ', '
121
+ end
122
+ end
123
+ end
124
+
125
+ plat.provision(env_build, provider_options) # unless options[:dry_run]
126
+ end
127
+
128
+ # rubocop:enable MethodLength, LineLength, CyclomaticComplexity, PerceivedComplexity
129
+ end
130
+ end
@@ -0,0 +1,19 @@
1
+ # Gem default configuration settings
2
+ # rubocop:disable LineLength
3
+ module VaqueroIo
4
+ # plugin conventions
5
+ PROVIDERFILE = 'Providerfile.yml'
6
+ PROVIDERS_PATH = "#{File.dirname(__FILE__).chomp('vaquero_io')}providers/"
7
+ LIST_PLUGINS_PATH = "#{PROVIDERS_PATH + '**/Providerfile.yml'}"
8
+ TEMPLATE_PROVIDER = "templates/#{PROVIDERFILE}.tt"
9
+ TMP_INSTALL_FOLDER = "#{Dir.pwd}/tmp-providers"
10
+ TMP_INSTALL_PROVIDER = "#{TMP_INSTALL_FOLDER}/#{PROVIDERFILE}"
11
+ ENVIRONMENTFILE = 'environments/'
12
+
13
+ # provider platform temmplates
14
+ PLATFORMFILE = 'platform.yml'
15
+
16
+ # system variables
17
+ PUTENV_PROVIDER = 'PUTENV_PROVIDER'
18
+ end
19
+ # rubocop:enable LineLength
@@ -0,0 +1,40 @@
1
+ # string constants for interactive messages
2
+ # rubocop:disable LineLength
3
+ module VaqueroIo
4
+ # command descriptions
5
+ DESC_VERSION = 'Display gem version'
6
+
7
+ DESC_PLUGIN = 'Manage Provider plugin modules'
8
+ DESC_PLUGIN_LIST = 'List installed Provider plugins'
9
+ DESC_PLUGIN_INSTALL = 'Install Provider plugin from LOCATION'
10
+ DESC_PLUGIN_UPDATE = 'Update installed Provider plugins'
11
+ DESC_PLUGIN_REMOVE = 'Remove installed Provider plugin'
12
+ DESC_PLUGIN_INIT = 'Create new Providerfile template for custom provider development'
13
+
14
+ DESC_NEW = 'Create new platform definition files based on specified Provider'
15
+ MSG_NEW_SUCCESS = 'Platform definition files successfully created'
16
+
17
+ DESC_HEALTH = 'Health check of all platform files and list all nodes for ENVIRONMENT'
18
+ HEALTHY = 'Success: Platform definition files exist and parameters match type requirements'
19
+
20
+ DESC_BUILD = 'Provision vms in an environment definition'
21
+ DESC_BUILD_ALL = 'Build everything for the named environment'
22
+ DESC_BUILD_COMPONENT = 'Build all nodes for the specified component'
23
+ DESC_BUILD_NODE = 'Build the single specified node'
24
+
25
+ # Error messages
26
+ NO_PROVIDER_FILE = 'Missing or invalid Providerfile'
27
+ NO_PROVIDER = 'Must specify a valid, installed provider plugin for platform definition'
28
+ PLUGINS_CURRENT = ' provider already at current version'
29
+ PLATFORM_EXISTS = 'Platform files already exist at this location'
30
+
31
+ MISSING_PLATFORM = 'Missing or invalid platform definitions file:'
32
+
33
+ FAIL_PROVIDER = 'Incorrect Provider'
34
+ WARN_PROVIDER_VERSION = 'Warning: Version difference between Provider plugin and platform definition'
35
+ FAIL_EMPTY_ENVIRONMENTS = 'Empty environments definition'
36
+ FAIL_EMPTY_NODENAME = 'Empty nodename convention'
37
+ FAIL_REQUIRED_FILES = 'No references to required file:'
38
+ FAIL_MISSING_ENV = 'Defined environment files not found:'
39
+ end
40
+ # rubocop:enable LineLength