dopi 0.17.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 +20 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +322 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +102 -0
- data/LICENSE.txt +177 -0
- data/README.md +309 -0
- data/Rakefile +44 -0
- data/Vagrantfile +64 -0
- data/bin/dopi +4 -0
- data/doc/getting_started.md +247 -0
- data/doc/getting_started_examples/001_hello_world.yaml +17 -0
- data/doc/getting_started_examples/002_connecting_over_ssh.yaml +35 -0
- data/doc/plugins/custom.md +88 -0
- data/doc/plugins/mco/rpc.md +82 -0
- data/doc/plugins/ssh/custom.md +141 -0
- data/doc/plugins/ssh/file_contains.md +37 -0
- data/doc/plugins/ssh/file_deploy.md +52 -0
- data/doc/plugins/ssh/file_exists.md +31 -0
- data/doc/plugins/ssh/file_replace.md +37 -0
- data/doc/plugins/ssh/puppet_agent_run.md +50 -0
- data/doc/plugins/ssh/reboot.md +22 -0
- data/doc/plugins/ssh/wait_for_login.md +53 -0
- data/doc/plugins/winrm/cmd.md +161 -0
- data/doc/plugins/winrm/file_contains.md +39 -0
- data/doc/plugins/winrm/file_exists.md +31 -0
- data/doc/plugins/winrm/powershell.md +27 -0
- data/doc/plugins/winrm/puppet_agent_run.md +49 -0
- data/doc/plugins/winrm/reboot.md +17 -0
- data/doc/plugins/winrm/wait_for_login.md +55 -0
- data/dopi.gemspec +42 -0
- data/lib/dopi/cli/command_add.rb +35 -0
- data/lib/dopi/cli/command_list.rb +19 -0
- data/lib/dopi/cli/command_remove.rb +31 -0
- data/lib/dopi/cli/command_reset.rb +27 -0
- data/lib/dopi/cli/command_run.rb +68 -0
- data/lib/dopi/cli/command_show.rb +109 -0
- data/lib/dopi/cli/command_update.rb +37 -0
- data/lib/dopi/cli/command_validate.rb +27 -0
- data/lib/dopi/cli/global_options.rb +55 -0
- data/lib/dopi/cli/log.rb +33 -0
- data/lib/dopi/cli.rb +57 -0
- data/lib/dopi/command/custom.rb +52 -0
- data/lib/dopi/command/dummy.rb +27 -0
- data/lib/dopi/command/mco/rpc.rb +158 -0
- data/lib/dopi/command/ssh/custom.rb +48 -0
- data/lib/dopi/command/ssh/file_contains.rb +70 -0
- data/lib/dopi/command/ssh/file_deploy.rb +71 -0
- data/lib/dopi/command/ssh/file_exists.rb +54 -0
- data/lib/dopi/command/ssh/file_replace.rb +96 -0
- data/lib/dopi/command/ssh/puppet_agent_run.rb +63 -0
- data/lib/dopi/command/ssh/reboot.rb +50 -0
- data/lib/dopi/command/ssh/wait_for_login.rb +68 -0
- data/lib/dopi/command/winrm/cmd.rb +44 -0
- data/lib/dopi/command/winrm/file_contains.rb +66 -0
- data/lib/dopi/command/winrm/file_exists.rb +51 -0
- data/lib/dopi/command/winrm/powershell.rb +16 -0
- data/lib/dopi/command/winrm/puppet_agent_run.rb +61 -0
- data/lib/dopi/command/winrm/reboot.rb +33 -0
- data/lib/dopi/command/winrm/wait_for_login.rb +49 -0
- data/lib/dopi/command.rb +239 -0
- data/lib/dopi/command_parser/arguments.rb +38 -0
- data/lib/dopi/command_parser/credentials.rb +59 -0
- data/lib/dopi/command_parser/env.rb +37 -0
- data/lib/dopi/command_parser/exec.rb +27 -0
- data/lib/dopi/command_parser/exit_code.rb +73 -0
- data/lib/dopi/command_parser/output.rb +126 -0
- data/lib/dopi/command_set.rb +66 -0
- data/lib/dopi/connector/local.rb +77 -0
- data/lib/dopi/connector/ssh.rb +170 -0
- data/lib/dopi/connector/winrm.rb +167 -0
- data/lib/dopi/error.rb +43 -0
- data/lib/dopi/log.rb +18 -0
- data/lib/dopi/node.rb +70 -0
- data/lib/dopi/plan.rb +99 -0
- data/lib/dopi/pluginmanager.rb +62 -0
- data/lib/dopi/state.rb +226 -0
- data/lib/dopi/state_store.rb +155 -0
- data/lib/dopi/step.rb +227 -0
- data/lib/dopi/step_set.rb +70 -0
- data/lib/dopi/version.rb +3 -0
- data/lib/dopi.rb +165 -0
- data/spec/command_helper.rb +11 -0
- data/spec/fixtures/mco_client.cfg +26 -0
- data/spec/fixtures/plans/fail_on_timeout.yaml +20 -0
- data/spec/fixtures/plans/hello_world.yaml +34 -0
- data/spec/fixtures/plans/non_existing_node.yaml +26 -0
- data/spec/fixtures/plans/test_role_variable.yaml +29 -0
- data/spec/fixtures/puppet/Puppetfile +8 -0
- data/spec/fixtures/puppet/Puppetfile.lock +57 -0
- data/spec/fixtures/puppet/hiera.yaml +6 -0
- data/spec/fixtures/puppet/manifests/site.pp +52 -0
- data/spec/fixtures/test_configuration.yaml +54 -0
- data/spec/fixtures/test_credentials.yaml +11 -0
- data/spec/fixtures/test_deloyed_file.txt +5 -0
- data/spec/fixtures/test_infrastructure.yaml +12 -0
- data/spec/fixtures/test_nodes.yaml +45 -0
- data/spec/fixtures/testenv_plan.yaml +159 -0
- data/spec/integration/dopi/addrun_spec.rb +31 -0
- data/spec/integration/dopi/cli/command_run_spec.rb +38 -0
- data/spec/integration/dopi/cli/global_options_spec.rb +128 -0
- data/spec/integration/dopi/command_spec.rb +66 -0
- data/spec/integration/dopi/fail_check_plans/file_exists_fails.yaml +38 -0
- data/spec/integration/dopi/fail_check_plans/output_parser.yaml +39 -0
- data/spec/integration/dopi/fail_check_plans/powershell_fail.yaml +25 -0
- data/spec/integration/dopi/fail_check_plans/timeout.yaml +29 -0
- data/spec/integration/dopi/fail_check_plans/verify_commands.yaml +33 -0
- data/spec/integration/dopi/failplan.rb +27 -0
- data/spec/integration/dopi/plan.rb +27 -0
- data/spec/integration/dopi/plans/dummy.yaml +29 -0
- data/spec/integration/dopi/plans/max_per_role.yaml +55 -0
- data/spec/integration/dopi/plans/no_timeout.yaml +29 -0
- data/spec/integration/dopi/plans/node_and_role_patterns.yaml +58 -0
- data/spec/integration/dopi/plans/node_by_config.yaml +116 -0
- data/spec/integration/dopi/plans/plugin_defaults.yaml +86 -0
- data/spec/integration/dopi/plans/plugins/mco/rpc.yaml +33 -0
- data/spec/integration/dopi/plans/plugins/ssh/custom.yaml +97 -0
- data/spec/integration/dopi/plans/plugins/ssh/file_contains.yaml +51 -0
- data/spec/integration/dopi/plans/plugins/ssh/file_deploy.yaml +82 -0
- data/spec/integration/dopi/plans/plugins/ssh/file_exists.yaml +69 -0
- data/spec/integration/dopi/plans/plugins/ssh/file_replace.yaml +55 -0
- data/spec/integration/dopi/plans/plugins/ssh/puppet_agent_run.yaml +45 -0
- data/spec/integration/dopi/plans/plugins/ssh/reboot.yaml +43 -0
- data/spec/integration/dopi/plans/plugins/ssh/wait_for_login.yaml +45 -0
- data/spec/integration/dopi/plans/plugins/winrm/cmd.yaml +39 -0
- data/spec/integration/dopi/plans/plugins/winrm/file_contains.yaml +51 -0
- data/spec/integration/dopi/plans/plugins/winrm/file_exists.yaml +69 -0
- data/spec/integration/dopi/plans/plugins/winrm/reboot.yaml +31 -0
- data/spec/integration/dopi/plans/resolve_roles_on_validate.yaml +23 -0
- data/spec/integration/dopi/plans/ssh_parallel.yaml +37 -0
- data/spec/integration/dopi/plans/verify_commands.yaml +49 -0
- data/spec/spec_helper.rb +104 -0
- data/spec/unit/dopi/command/custom_spec.rb +58 -0
- data/spec/unit/dopi/command/mco/rpc_spec.rb +157 -0
- data/spec/unit/dopi/command/ssh/custom_spec.rb +30 -0
- data/spec/unit/dopi/command/ssh/file_deploy_spec.rb +42 -0
- data/spec/unit/dopi/command/ssh/file_replace_spec.rb +35 -0
- data/spec/unit/dopi/command_parser/credentials_spec.rb +53 -0
- data/spec/unit/dopi/command_parser/exit_code_spec.rb +63 -0
- data/spec/unit/dopi/command_parser/output_spec.rb +129 -0
- data/spec/unit/dopi/command_spec.rb +14 -0
- data/spec/unit/dopi/connector/winrm_spec.rb +111 -0
- data/spec/unit/dopi/node_spec.rb +24 -0
- data/spec/unit/dopi/plan_spec.rb +31 -0
- data/spec/unit/dopi/state_spec.rb +109 -0
- data/spec/unit/dopi/step_spec.rb +13 -0
- metadata +448 -0
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
SimpleCov.start do
|
|
3
|
+
add_filter '/spec/'
|
|
4
|
+
add_filter '/.bundle/'
|
|
5
|
+
add_filter '/vendor/'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
require 'dopi'
|
|
9
|
+
require 'command_helper'
|
|
10
|
+
require 'rspec_command'
|
|
11
|
+
|
|
12
|
+
Dopi.log.level = ::Logger::FATAL
|
|
13
|
+
|
|
14
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
|
15
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
|
16
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause this
|
|
17
|
+
# file to always be loaded, without a need to explicitly require it in any files.
|
|
18
|
+
#
|
|
19
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
|
20
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
|
21
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
|
22
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
|
23
|
+
# a separate helper file that requires the additional dependencies and performs
|
|
24
|
+
# the additional setup, and require it from the spec files that actually need it.
|
|
25
|
+
#
|
|
26
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
|
27
|
+
# users commonly want.
|
|
28
|
+
#
|
|
29
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
|
30
|
+
RSpec.configure do |config|
|
|
31
|
+
config.include CommandHelper
|
|
32
|
+
config.include RSpecCommand
|
|
33
|
+
# rspec-expectations config goes here. You can use an alternate
|
|
34
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
|
35
|
+
# assertions if you prefer.
|
|
36
|
+
config.expect_with :rspec do |expectations|
|
|
37
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
|
38
|
+
# and `failure_message` of custom matchers include text for helper methods
|
|
39
|
+
# defined using `chain`, e.g.:
|
|
40
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
|
41
|
+
# # => "be bigger than 2 and smaller than 4"
|
|
42
|
+
# ...rather than:
|
|
43
|
+
# # => "be bigger than 2"
|
|
44
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
|
48
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
|
49
|
+
config.mock_with :rspec do |mocks|
|
|
50
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
|
51
|
+
# a real object. This is generally recommended, and will default to
|
|
52
|
+
# `true` in RSpec 4.
|
|
53
|
+
mocks.verify_partial_doubles = true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# The settings below are suggested to provide a good initial experience
|
|
57
|
+
# with RSpec, but feel free to customize to your heart's content.
|
|
58
|
+
=begin
|
|
59
|
+
# These two settings work together to allow you to limit a spec run
|
|
60
|
+
# to individual examples or groups you care about by tagging them with
|
|
61
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
|
62
|
+
# get run.
|
|
63
|
+
config.filter_run :focus
|
|
64
|
+
config.run_all_when_everything_filtered = true
|
|
65
|
+
|
|
66
|
+
# Limits the available syntax to the non-monkey patched syntax that is recommended.
|
|
67
|
+
# For more details, see:
|
|
68
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
|
69
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
|
70
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
|
71
|
+
config.disable_monkey_patching!
|
|
72
|
+
|
|
73
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
|
74
|
+
# be too noisy due to issues in dependencies.
|
|
75
|
+
config.warnings = true
|
|
76
|
+
|
|
77
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
|
78
|
+
# file, and it's useful to allow more verbose output when running an
|
|
79
|
+
# individual spec file.
|
|
80
|
+
if config.files_to_run.one?
|
|
81
|
+
# Use the documentation formatter for detailed output,
|
|
82
|
+
# unless a formatter has already been configured
|
|
83
|
+
# (e.g. via a command-line flag).
|
|
84
|
+
config.default_formatter = 'doc'
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Print the 10 slowest examples and example groups at the
|
|
88
|
+
# end of the spec run, to help surface which specs are running
|
|
89
|
+
# particularly slow.
|
|
90
|
+
config.profile_examples = 10
|
|
91
|
+
|
|
92
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
93
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
94
|
+
# the seed, which is printed after each run.
|
|
95
|
+
# --seed 1234
|
|
96
|
+
config.order = :random
|
|
97
|
+
|
|
98
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
|
99
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
|
100
|
+
# test failures related to randomization by passing the same `--seed` value
|
|
101
|
+
# as the one that triggered the failure.
|
|
102
|
+
Kernel.srand config.seed
|
|
103
|
+
=end
|
|
104
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Dopi::Command do
|
|
4
|
+
|
|
5
|
+
describe '#exec' do
|
|
6
|
+
it 'should return the exec value if specified' do
|
|
7
|
+
command = create_command({:plugin => 'custom', :exec => 'echo'})
|
|
8
|
+
expect(command.exec).to eq('echo')
|
|
9
|
+
end
|
|
10
|
+
it 'will raise and error if exec is not specified' do
|
|
11
|
+
command = create_command({:plugin => 'custom'})
|
|
12
|
+
expect{command.exec}.to raise_error Dopi::CommandParsingError
|
|
13
|
+
end
|
|
14
|
+
it 'will raise and error if exec is not a String' do
|
|
15
|
+
command = create_command({:plugin => 'custom', :exec => 2})
|
|
16
|
+
expect{command.exec}.to raise_error Dopi::CommandParsingError
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#env' do
|
|
21
|
+
it 'should return the defaults hash if nothing is specified' do
|
|
22
|
+
command = create_command({:plugin => 'custom'})
|
|
23
|
+
expect(command.env).to eq({'DOP_NODE_FQDN' => 'test.example.com'})
|
|
24
|
+
end
|
|
25
|
+
it 'should return the specified hash merged with the defaults' do
|
|
26
|
+
command = create_command({:plugin => 'custom', :env => {'MYVAR' => 'MYVALUE'}})
|
|
27
|
+
expect(command.env).to eq({'DOP_NODE_FQDN' => 'test.example.com', 'MYVAR' => 'MYVALUE'})
|
|
28
|
+
end
|
|
29
|
+
it 'will raise and error if env is not a hash' do
|
|
30
|
+
command = create_command({:plugin => 'custom', :env => 2})
|
|
31
|
+
expect{command.env}.to raise_error Dopi::CommandParsingError
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe '#arguments' do
|
|
36
|
+
it 'should return an empty hash if nothing is specified' do
|
|
37
|
+
command = create_command({:plugin => 'custom'})
|
|
38
|
+
expect(command.arguments).to eq("")
|
|
39
|
+
end
|
|
40
|
+
it 'should return a correct string if arguments are specified as a String' do
|
|
41
|
+
command = create_command({:plugin => 'custom', :arguments => "my custom arguments"})
|
|
42
|
+
expect(command.arguments).to eq("my custom arguments")
|
|
43
|
+
end
|
|
44
|
+
it 'should return a correct string if arguments are specified as an Array' do
|
|
45
|
+
command = create_command({:plugin => 'custom', :arguments => ['my', 'custom', 'arguments']})
|
|
46
|
+
expect(command.arguments).to eq("my custom arguments")
|
|
47
|
+
end
|
|
48
|
+
it 'should return a correct string if arguments are specified as a Hash' do
|
|
49
|
+
command = create_command({:plugin => 'custom', :arguments => {'my' => 'custom', 'arguments' => ''}})
|
|
50
|
+
expect(command.arguments).to eq("my custom arguments ")
|
|
51
|
+
end
|
|
52
|
+
it 'will raise and error if arguments is not a String, Array or Hash' do
|
|
53
|
+
command = create_command({:plugin => 'custom', :arguments => 2})
|
|
54
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'mcollective'
|
|
3
|
+
|
|
4
|
+
describe Dopi::Command::Mco::Rpc do
|
|
5
|
+
|
|
6
|
+
describe '#agent' do
|
|
7
|
+
it 'should return the name of the agent if it is specified' do
|
|
8
|
+
command = create_command({:plugin => 'mco/rpc', :agent => 'rpcutil'})
|
|
9
|
+
expect(command.agent).to eq('rpcutil')
|
|
10
|
+
end
|
|
11
|
+
it 'will raise and error if agent is not specified and valid' do
|
|
12
|
+
command = create_command({:plugin => 'mco/rpc'})
|
|
13
|
+
expect{command.agent}.to raise_error Dopi::CommandParsingError
|
|
14
|
+
end
|
|
15
|
+
it 'will raise and error if agent is not a String' do
|
|
16
|
+
command = create_command({:plugin => 'mco/rpc', :agent => 2})
|
|
17
|
+
expect{command.agent}.to raise_error Dopi::CommandParsingError
|
|
18
|
+
end
|
|
19
|
+
it 'will raise and error if agent does not exists' do
|
|
20
|
+
command = create_command({:plugin => 'mco/rpc', :agent => 'nonexistingagent'})
|
|
21
|
+
expect{command.agent}.to raise_error Dopi::CommandParsingError
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe '#options' do
|
|
26
|
+
it 'should return the merged options hash if the hash is valid' do
|
|
27
|
+
command = create_command({:plugin => 'mco/rpc', :options => {:ttl => 300}})
|
|
28
|
+
expect(command.options[:ttl]).to eq(300)
|
|
29
|
+
end
|
|
30
|
+
it 'should return the default options hash if the hash is not defined' do
|
|
31
|
+
command = create_command({:plugin => 'mco/rpc'})
|
|
32
|
+
expect(command.options).to eq(command.send(:options_defaults))
|
|
33
|
+
end
|
|
34
|
+
it 'will raise and error if options is not a hash' do
|
|
35
|
+
command = create_command({:plugin => 'mco/rpc', :options => 2})
|
|
36
|
+
expect{command.options}.to raise_error Dopi::CommandParsingError
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe '#action' do
|
|
41
|
+
it 'should return the name of the action if it is specified and valid' do
|
|
42
|
+
command = create_command({
|
|
43
|
+
:plugin => 'mco/rpc',
|
|
44
|
+
:agent => 'rpcutil',
|
|
45
|
+
:action => 'inventory'
|
|
46
|
+
})
|
|
47
|
+
expect(command.action).to eq('inventory')
|
|
48
|
+
end
|
|
49
|
+
it 'will raise an error if action is not defined' do
|
|
50
|
+
command = create_command({
|
|
51
|
+
:plugin => 'mco/rpc',
|
|
52
|
+
:agent => 'nonexistingagent'
|
|
53
|
+
})
|
|
54
|
+
expect{command.action}.to raise_error Dopi::CommandParsingError
|
|
55
|
+
end
|
|
56
|
+
it 'will raise an error if agent is not valid' do
|
|
57
|
+
command = create_command({
|
|
58
|
+
:plugin => 'mco/rpc',
|
|
59
|
+
:agent => 'nonexistingagent',
|
|
60
|
+
:action => 'inventory'
|
|
61
|
+
})
|
|
62
|
+
expect{command.action}.to raise_error Dopi::CommandParsingError
|
|
63
|
+
end
|
|
64
|
+
it 'will raise an error if action is not valid' do
|
|
65
|
+
command = create_command({
|
|
66
|
+
:plugin => 'mco/rpc',
|
|
67
|
+
:agent => 'rpcutil',
|
|
68
|
+
:action => 'nonexixtingaction'
|
|
69
|
+
})
|
|
70
|
+
expect{command.action}.to raise_error Dopi::CommandParsingError
|
|
71
|
+
end
|
|
72
|
+
it 'will raise and error if action is not a String' do
|
|
73
|
+
command = create_command({
|
|
74
|
+
:plugin => 'mco/rpc',
|
|
75
|
+
:agent => 'rpcutil',
|
|
76
|
+
:action => 2
|
|
77
|
+
})
|
|
78
|
+
expect{command.action}.to raise_error Dopi::CommandParsingError
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe '#arguments' do
|
|
83
|
+
it 'should return the arguments hash if it is specified and valid' do
|
|
84
|
+
command = create_command({
|
|
85
|
+
:plugin => 'mco/rpc',
|
|
86
|
+
:agent => 'rpcutil',
|
|
87
|
+
:action => 'get_fact',
|
|
88
|
+
:arguments => { :fact => 'osfamily' }
|
|
89
|
+
})
|
|
90
|
+
expect(command.arguments).to eq({ :fact => 'osfamily' })
|
|
91
|
+
end
|
|
92
|
+
it 'should return an empty hash if "arguments" is not specified and all arguments are optional' do
|
|
93
|
+
command = create_command({
|
|
94
|
+
:plugin => 'mco/rpc',
|
|
95
|
+
:agent => 'rpcutil',
|
|
96
|
+
:action => 'inventory'
|
|
97
|
+
})
|
|
98
|
+
expect(command.arguments).to eq({})
|
|
99
|
+
end
|
|
100
|
+
it 'will raise an error if "arguments" is not specified and there are required arguments' do
|
|
101
|
+
command = create_command({
|
|
102
|
+
:plugin => 'mco/rpc',
|
|
103
|
+
:agent => 'rpcutil',
|
|
104
|
+
:action => 'get_fact'
|
|
105
|
+
})
|
|
106
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
107
|
+
end
|
|
108
|
+
it 'will raise an error if an argument key is not valid' do
|
|
109
|
+
command = create_command({
|
|
110
|
+
:plugin => 'mco/rpc',
|
|
111
|
+
:agent => 'rpcutil',
|
|
112
|
+
:action => 'get_fact',
|
|
113
|
+
:arguments => { :foo => 'osfamily' }
|
|
114
|
+
})
|
|
115
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
116
|
+
end
|
|
117
|
+
it 'will raise an error if an argument value is not valid' do
|
|
118
|
+
command = create_command({
|
|
119
|
+
:plugin => 'mco/rpc',
|
|
120
|
+
:agent => 'rpcutil',
|
|
121
|
+
:action => 'get_fact',
|
|
122
|
+
:arguments => { :fact => 'osfamily&&' }
|
|
123
|
+
})
|
|
124
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
125
|
+
end
|
|
126
|
+
it 'will raise an error if agent is not valid' do
|
|
127
|
+
command = create_command({
|
|
128
|
+
:plugin => 'mco/rpc',
|
|
129
|
+
:agent => 'nonexistingagent',
|
|
130
|
+
:action => 'get_fact'
|
|
131
|
+
})
|
|
132
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
133
|
+
end
|
|
134
|
+
it 'will raise an error if action is not valid' do
|
|
135
|
+
command = create_command({
|
|
136
|
+
:plugin => 'mco/rpc',
|
|
137
|
+
:agent => 'rpcutil',
|
|
138
|
+
:action => 'nonexistingaction'
|
|
139
|
+
})
|
|
140
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
141
|
+
end
|
|
142
|
+
it 'will raise and error if arguments is not a Hash' do
|
|
143
|
+
command = create_command({
|
|
144
|
+
:plugin => 'mco/rpc',
|
|
145
|
+
:agent => 'rpcutil',
|
|
146
|
+
:action => 'get_fact',
|
|
147
|
+
:arguments => 'foo'
|
|
148
|
+
})
|
|
149
|
+
expect{command.arguments}.to raise_error Dopi::CommandParsingError
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe '#run' do
|
|
154
|
+
pending
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Dopi::Command::Ssh do
|
|
4
|
+
|
|
5
|
+
describe '#quiet' do
|
|
6
|
+
pending
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '#port' do
|
|
10
|
+
it 'should return the default port if nothing is specified' do
|
|
11
|
+
command = create_command({:plugin => 'ssh/custom'})
|
|
12
|
+
expect(command.port).to eq('22')
|
|
13
|
+
end
|
|
14
|
+
it 'should return the correct port if specified correctly' do
|
|
15
|
+
command = create_command({:plugin => 'ssh/custom', :port => 42})
|
|
16
|
+
expect(command.port).to eq('42')
|
|
17
|
+
end
|
|
18
|
+
it 'will raise an error if port is not a number' do
|
|
19
|
+
command = create_command({:plugin => 'ssh/custom', :port => "2"})
|
|
20
|
+
expect{command.port}.to raise_error Dopi::CommandParsingError
|
|
21
|
+
end
|
|
22
|
+
it 'will raise an error if port is not in the valid range' do
|
|
23
|
+
command = create_command({:plugin => 'ssh/custom', :port => -1})
|
|
24
|
+
expect{command.port}.to raise_error Dopi::CommandParsingError
|
|
25
|
+
command = create_command({:plugin => 'ssh/custom', :port => 70000})
|
|
26
|
+
expect{command.port}.to raise_error Dopi::CommandParsingError
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Dopi::Command::Ssh::FileDeploy do
|
|
4
|
+
|
|
5
|
+
describe '#file' do
|
|
6
|
+
it 'should return the file path if specified correctly' do
|
|
7
|
+
command = create_command({:plugin => 'ssh/file_deploy', :file => '/tmp/foo'})
|
|
8
|
+
expect(command.file).to eq('/tmp/foo')
|
|
9
|
+
end
|
|
10
|
+
it 'will raise an error if the file path is not pecified' do
|
|
11
|
+
command = create_command({:plugin => 'ssh/file_deploy'})
|
|
12
|
+
expect{command.file}.to raise_error Dopi::CommandParsingError
|
|
13
|
+
end
|
|
14
|
+
it 'will raise an error if file path is not a String' do
|
|
15
|
+
command = create_command({:plugin => 'ssh/file_deploy', :file => 2})
|
|
16
|
+
expect{command.file}.to raise_error Dopi::CommandParsingError
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#content' do
|
|
21
|
+
it 'should return an error if nothing is specified' do
|
|
22
|
+
command = create_command({:plugin => 'ssh/file_deploy'})
|
|
23
|
+
expect{command.content}.to raise_error Dopi::CommandParsingError
|
|
24
|
+
end
|
|
25
|
+
it 'should return the content if specified correctly as a string' do
|
|
26
|
+
command = create_command({:plugin => 'ssh/file_deploy', :content => 'hello world'})
|
|
27
|
+
expect(command.content).to eq('hello world')
|
|
28
|
+
end
|
|
29
|
+
it 'should return the content if specified correctly as a file' do
|
|
30
|
+
file = Tempfile.new('secret_file', ENV['HOME'])
|
|
31
|
+
file.write('hello world')
|
|
32
|
+
file.close
|
|
33
|
+
command = create_command({:plugin => 'ssh/file_deploy', :content => {'file' => file.path} })
|
|
34
|
+
expect(command.content).to eq('hello world')
|
|
35
|
+
file.delete
|
|
36
|
+
end
|
|
37
|
+
it 'will raise an error if content is not a string' do
|
|
38
|
+
command = create_command({:plugin => 'ssh/file_deploy', :content => 2})
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Dopi::Command::Ssh::FileReplace do
|
|
4
|
+
|
|
5
|
+
describe '#replacement' do
|
|
6
|
+
it 'should return the replacement value if specified' do
|
|
7
|
+
command = create_command({:plugin => 'ssh/file_replace', :replacement => 'foo'})
|
|
8
|
+
expect(command.replacement).to eq('foo')
|
|
9
|
+
end
|
|
10
|
+
it 'will raise and error if replacement is not specified' do
|
|
11
|
+
command = create_command({:plugin => 'ssh/file_replace'})
|
|
12
|
+
expect{command.replacement}.to raise_error Dopi::CommandParsingError
|
|
13
|
+
end
|
|
14
|
+
it 'will raise and error if replacement is not a String' do
|
|
15
|
+
command = create_command({:plugin => 'ssh/file_replace', :replacement => 2})
|
|
16
|
+
expect{command.replacement}.to raise_error Dopi::CommandParsingError
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#global' do
|
|
21
|
+
it 'should return true if nothing is specified' do
|
|
22
|
+
command = create_command({:plugin => 'ssh/file_replace'})
|
|
23
|
+
expect(command.global).to be true
|
|
24
|
+
end
|
|
25
|
+
it 'should return the correct value if specified' do
|
|
26
|
+
command = create_command({:plugin => 'ssh/file_replace', :global => false})
|
|
27
|
+
expect(command.global).to be false
|
|
28
|
+
end
|
|
29
|
+
it 'will raise and error if global is not a boolean' do
|
|
30
|
+
command = create_command({:plugin => 'ssh/file_replace', :global => 2})
|
|
31
|
+
expect{command.global}.to raise_error Dopi::CommandParsingError
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class CredentialsTestKlass
|
|
4
|
+
include Dopi::CommandParser::Credentials
|
|
5
|
+
attr_accessor :hash, :step
|
|
6
|
+
def supported_credential_types() [:username_password] end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe Dopi::CommandParser::Credentials do
|
|
10
|
+
|
|
11
|
+
before :each do
|
|
12
|
+
@credentials = CredentialsTestKlass.new
|
|
13
|
+
@fake_credentials = instance_double('DopCommon::Credentials', :type => :username_password)
|
|
14
|
+
@fake_credentials4 = instance_double('DopCommon::Credentials', :type => :non_existing_type)
|
|
15
|
+
plan = instance_double('Dopi::Plan', :credentials => {
|
|
16
|
+
'test_credentials_01' => @fake_credentials,
|
|
17
|
+
'test_credentials_02' => @fake_credentials,
|
|
18
|
+
'test_credentials_04' => @fake_credentials4
|
|
19
|
+
})
|
|
20
|
+
@credentials.step = instance_double('Dopi::Step', :plan => plan)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe '#credentials' do
|
|
24
|
+
it 'returns an empty array if nothing is specified' do
|
|
25
|
+
@credentials.hash = {}
|
|
26
|
+
expect(@credentials.credentials).to eq([])
|
|
27
|
+
end
|
|
28
|
+
it 'returns an array with one credential if only one is specified' do
|
|
29
|
+
@credentials.hash = {:credentials => 'test_credentials_01'}
|
|
30
|
+
expect(@credentials.credentials.length).to eq(1)
|
|
31
|
+
expect(@credentials.credentials.first).to be @fake_credentials
|
|
32
|
+
end
|
|
33
|
+
it 'returns an array with two credentials if two are specified' do
|
|
34
|
+
@credentials.hash = {:credentials => ['test_credentials_01', 'test_credentials_02']}
|
|
35
|
+
expect(@credentials.credentials.length).to eq(2)
|
|
36
|
+
expect(@credentials.credentials.last).to be @fake_credentials
|
|
37
|
+
end
|
|
38
|
+
it 'raises an error if the credentials are not valid' do
|
|
39
|
+
@credentials.hash = {:credentials => ['test_credentials_01', 2]}
|
|
40
|
+
expect{@credentials.credentials}.to raise_error Dopi::CommandParsingError
|
|
41
|
+
end
|
|
42
|
+
it 'raises an error if the credentials do not exist' do
|
|
43
|
+
@credentials.hash = {:credentials => ['test_credentials_01', 'test_credentials_03']}
|
|
44
|
+
expect{@credentials.credentials}.to raise_error Dopi::CommandParsingError
|
|
45
|
+
end
|
|
46
|
+
it 'raises an error if one of the credential types is not supported' do
|
|
47
|
+
@credentials.hash = {:credentials => ['test_credentials_01', 'test_credentials_04']}
|
|
48
|
+
expect{@credentials.credentials}.to raise_error Dopi::CommandParsingError
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
class ExitCodeTestKlass
|
|
5
|
+
include Dopi::CommandParser::ExitCode
|
|
6
|
+
attr_accessor :hash
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ExitCodeDefaults
|
|
10
|
+
def expect_exit_codes_defaults
|
|
11
|
+
[1,2,3]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe Dopi::CommandParser::ExitCode do
|
|
16
|
+
|
|
17
|
+
describe '#expect_exit_codes' do
|
|
18
|
+
subject do
|
|
19
|
+
exit_code_parser = ExitCodeTestKlass.new
|
|
20
|
+
exit_code_parser.hash = hash
|
|
21
|
+
exit_code_parser.expect_exit_codes
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'Nothing is specified' do
|
|
25
|
+
let(:hash){nil}
|
|
26
|
+
it{ is_expected.to eq(0) }
|
|
27
|
+
end
|
|
28
|
+
context 'A number is specified' do
|
|
29
|
+
let(:hash){{:expect_exit_codes => 3}}
|
|
30
|
+
it{ is_expected.to eq(3) }
|
|
31
|
+
end
|
|
32
|
+
context 'An Array is specified' do
|
|
33
|
+
let(:hash){{:expect_exit_codes => [0, 1, 3]}}
|
|
34
|
+
it{ is_expected.to eq([0, 1, 3]) }
|
|
35
|
+
end
|
|
36
|
+
context 'The :all keyword is specified' do
|
|
37
|
+
let(:hash){{:expect_exit_codes => 'all'}}
|
|
38
|
+
it{ is_expected.to eq('all') }
|
|
39
|
+
end
|
|
40
|
+
context 'The value is an invalid string' do
|
|
41
|
+
let(:hash){{:expect_exit_codes => 'foo'}}
|
|
42
|
+
it{ expect{subject}.to raise_error Dopi::CommandParsingError }
|
|
43
|
+
end
|
|
44
|
+
context 'The Array contains a String' do
|
|
45
|
+
let(:hash){{:expect_exit_codes => [1, 2, 'foo']}}
|
|
46
|
+
it{ expect{subject}.to raise_error Dopi::CommandParsingError }
|
|
47
|
+
end
|
|
48
|
+
context 'A plugin defaults method is specified' do
|
|
49
|
+
subject do
|
|
50
|
+
exit_code_parser = ExitCodeTestKlass.new
|
|
51
|
+
exit_code_parser.extend(ExitCodeDefaults)
|
|
52
|
+
exit_code_parser.expect_exit_codes
|
|
53
|
+
end
|
|
54
|
+
it{ is_expected.to eq([1,2,3])}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe 'check_exit_code' do
|
|
59
|
+
pending
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class OutputTestKlass
|
|
4
|
+
include Dopi::CommandParser::Output
|
|
5
|
+
attr_accessor :hash
|
|
6
|
+
def log(s,m); end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe Dopi::CommandParser::Output do
|
|
10
|
+
|
|
11
|
+
before :each do
|
|
12
|
+
@output_parser = OutputTestKlass.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe 'parse_output' do
|
|
16
|
+
it 'Returns an empty hash if nothing is defined' do
|
|
17
|
+
expect(@output_parser.parse_output).to eq({})
|
|
18
|
+
end
|
|
19
|
+
it 'Returns the correct hash if one is defined' do
|
|
20
|
+
@output_parser.hash = {:parse_output => {:error => [], :warning => []}}
|
|
21
|
+
expect(@output_parser.parse_output).to eq({:error => [], :warning => []})
|
|
22
|
+
end
|
|
23
|
+
it 'Raises an exeption if the value is not a hash' do
|
|
24
|
+
@output_parser.hash = {:parse_output => 2}
|
|
25
|
+
expect{@output_parser.parse_output}.to raise_error Dopi::CommandParsingError
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe 'error_patterns' do
|
|
30
|
+
it 'Returns an empty array if nothing is defined' do
|
|
31
|
+
expect(@output_parser.error_patterns).to eq([])
|
|
32
|
+
end
|
|
33
|
+
it 'Returns the correct array if it is specified' do
|
|
34
|
+
@output_parser.hash = {:parse_output => {:error => [ 'foo', '^bar$' ]}}
|
|
35
|
+
expect(@output_parser.error_patterns).to eq([ 'foo', '^bar$' ])
|
|
36
|
+
end
|
|
37
|
+
it 'Raises an exeption if the value is not an array' do
|
|
38
|
+
@output_parser.hash = {:parse_output => {:error => 2}}
|
|
39
|
+
expect{@output_parser.error_patterns}.to raise_error Dopi::CommandParsingError
|
|
40
|
+
end
|
|
41
|
+
it 'Raises an exception if the pattern is not a Regular Expression' do
|
|
42
|
+
@output_parser.hash = {:parse_output => {:error => ['][']}}
|
|
43
|
+
expect{@output_parser.error_patterns}.to raise_error Dopi::CommandParsingError
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe 'warning_patterns' do
|
|
48
|
+
it 'Returns an empty array if nothing is defined' do
|
|
49
|
+
expect(@output_parser.warning_patterns).to eq([])
|
|
50
|
+
end
|
|
51
|
+
it 'Returns the correct array if it is specified' do
|
|
52
|
+
@output_parser.hash = {:parse_output => {:warning => [ 'foo', '^bar$' ]}}
|
|
53
|
+
expect(@output_parser.warning_patterns).to eq([ 'foo', '^bar$' ])
|
|
54
|
+
end
|
|
55
|
+
it 'Raises an exeption if the value is not an array' do
|
|
56
|
+
@output_parser.hash = {:parse_output => {:warning => 2}}
|
|
57
|
+
expect{@output_parser.warning_patterns}.to raise_error Dopi::CommandParsingError
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe 'fail_on_warning' do
|
|
62
|
+
it 'Returns false if nothing is defined' do
|
|
63
|
+
expect(@output_parser.fail_on_warning).to be false
|
|
64
|
+
end
|
|
65
|
+
it 'Returns true if specified' do
|
|
66
|
+
@output_parser.hash = {:fail_on_warning => true}
|
|
67
|
+
expect(@output_parser.fail_on_warning).to be true
|
|
68
|
+
end
|
|
69
|
+
it 'Returns false if specified' do
|
|
70
|
+
@output_parser.hash = {:fail_on_warning => false}
|
|
71
|
+
expect(@output_parser.fail_on_warning).to be false
|
|
72
|
+
end
|
|
73
|
+
it 'Raises an exeption if the value is not a boolean' do
|
|
74
|
+
@output_parser.hash = {:fail_on_warning => 2}
|
|
75
|
+
expect{@output_parser.fail_on_warning}.to raise_error Dopi::CommandParsingError
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe 'check_output' do
|
|
80
|
+
it 'Returns true if no error is detected' do
|
|
81
|
+
raw_output = <<-OUTPUT
|
|
82
|
+
Foo
|
|
83
|
+
Bar
|
|
84
|
+
OUTPUT
|
|
85
|
+
@output_parser.hash = {:parse_output => {:error => [ 'Error:' ]}}
|
|
86
|
+
expect(@output_parser.check_output(raw_output)).to be true
|
|
87
|
+
end
|
|
88
|
+
it 'Returns false if an error is detected' do
|
|
89
|
+
raw_output = <<-OUTPUT
|
|
90
|
+
Foo
|
|
91
|
+
Error: this is a fake error
|
|
92
|
+
Bar
|
|
93
|
+
OUTPUT
|
|
94
|
+
@output_parser.hash = {:parse_output => {:error => [ 'Error:' ]}}
|
|
95
|
+
expect(@output_parser.check_output(raw_output)).to be false
|
|
96
|
+
end
|
|
97
|
+
it 'Returns true if no warning is detected' do
|
|
98
|
+
raw_output = <<-OUTPUT
|
|
99
|
+
Foo
|
|
100
|
+
Bar
|
|
101
|
+
OUTPUT
|
|
102
|
+
@output_parser.hash = {:parse_output => {:warning => [ 'Warning:' ]}}
|
|
103
|
+
expect(@output_parser.check_output(raw_output)).to be true
|
|
104
|
+
end
|
|
105
|
+
it 'Returns true if an warning is detected but fail_on_warning is not true' do
|
|
106
|
+
raw_output = <<-OUTPUT
|
|
107
|
+
Foo
|
|
108
|
+
Warning: this is a fake error
|
|
109
|
+
Bar
|
|
110
|
+
OUTPUT
|
|
111
|
+
@output_parser.hash = {:parse_output => {:warning => [ 'Warning:' ]}}
|
|
112
|
+
expect(@output_parser.check_output(raw_output)).to be true
|
|
113
|
+
end
|
|
114
|
+
it 'Returns true if an warning is detected but fail_on_warning is not true' do
|
|
115
|
+
raw_output = <<-OUTPUT
|
|
116
|
+
Foo
|
|
117
|
+
Warning: this is a fake error
|
|
118
|
+
Bar
|
|
119
|
+
OUTPUT
|
|
120
|
+
@output_parser.hash = {
|
|
121
|
+
:fail_on_warning => true,
|
|
122
|
+
:parse_output => {:warning => [ 'Warning:' ]}
|
|
123
|
+
}
|
|
124
|
+
expect(@output_parser.check_output(raw_output)).to be false
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
|