vaquero_io 0.1.1

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.
@@ -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