nodespec 0.1.10 → 1.0.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 +4 -4
- data/.gitignore +2 -1
- data/Gemfile.lock +29 -21
- data/README.md +10 -8
- data/lib/nodespec/backend_proxy/ssh.rb +1 -1
- data/lib/nodespec/backend_proxy/winrm.rb +1 -1
- data/lib/nodespec/backend_proxy.rb +23 -0
- data/lib/nodespec/communication_adapters/aws_ec2.rb +3 -3
- data/lib/nodespec/communication_adapters/native_communicator.rb +11 -18
- data/lib/nodespec/communication_adapters/ssh.rb +2 -3
- data/lib/nodespec/communication_adapters/ssh_communicator.rb +15 -28
- data/lib/nodespec/communication_adapters/vagrant.rb +2 -2
- data/lib/nodespec/communication_adapters/winrm.rb +2 -2
- data/lib/nodespec/communication_adapters/winrm_communicator.rb +17 -30
- data/lib/nodespec/communication_adapters.rb +3 -3
- data/lib/nodespec/configuration_binding.rb +48 -0
- data/lib/nodespec/node.rb +1 -3
- data/lib/nodespec/provisioning/ansible.rb +1 -1
- data/lib/nodespec/version.rb +1 -1
- data/lib/nodespec.rb +9 -11
- data/nodespec.gemspec +7 -4
- data/spec/backend_proxy/exec_spec.rb +4 -4
- data/spec/backend_proxy/ssh_spec.rb +5 -5
- data/spec/backend_proxy/unixshell_utility_spec.rb +1 -1
- data/spec/backend_proxy/winrm_spec.rb +2 -2
- data/spec/command_execution_spec.rb +2 -2
- data/spec/communication_adapters/aws_ec2_spec.rb +8 -8
- data/spec/communication_adapters/native_communicator_spec.rb +16 -34
- data/spec/communication_adapters/ssh_communicator_spec.rb +34 -90
- data/spec/communication_adapters/ssh_spec.rb +1 -9
- data/spec/communication_adapters/vagrant_spec.rb +2 -2
- data/spec/communication_adapters/winrm_communicator_spec.rb +31 -83
- data/spec/communication_adapters/winrm_spec.rb +1 -9
- data/spec/communication_adapters_spec.rb +4 -4
- data/spec/configuration_binding_spec.rb +167 -0
- data/spec/local_command_runner_spec.rb +3 -3
- data/spec/node_spec.rb +10 -10
- data/spec/provisioning_spec.rb +3 -3
- data/spec/support/backend.rb +5 -5
- data/spec/support/communicator_adapters.rb +23 -0
- data/spec/support/init_with_current_node.rb +1 -1
- metadata +32 -22
- data/lib/nodespec/backends.rb +0 -13
- data/lib/nodespec/communication_adapters/local_backend.rb +0 -15
- data/lib/nodespec/communication_adapters/remote_backend.rb +0 -15
- data/spec/communication_adapters/local_backend_spec.rb +0 -38
- data/spec/communication_adapters/remote_backend_spec.rb +0 -46
- data/spec/support/ssh_communicator.rb +0 -9
- data/spec/support/winrm_communicator.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c521201ce3c84255c9eadcf6f4e120601f2c6782
|
4
|
+
data.tar.gz: b5128627491fd84aae37789dca3560d77531284d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e08d0e4dc3acf0545ec32f0e4ada934e7899df36d6225028995589b8a8ffa992dc2b19760afefa90faa2d55a9bfa973c13f47c41cb055a3af3bb32468f71ce7
|
7
|
+
data.tar.gz: f5e3b4ae194e6f943ba560e33abb43d4bc823f0309f09d7e0a8bd2a4ce07077ee8a0f1fb106aba5cfc61cf8532a484a72edf2c394633f771dfb7f5becc9fabf4
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nodespec (0.
|
4
|
+
nodespec (1.0.0)
|
5
5
|
net-ssh
|
6
|
-
|
7
|
-
|
6
|
+
os
|
7
|
+
serverspec (~> 2.3)
|
8
|
+
specinfra (~> 2.4)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
@@ -22,7 +23,6 @@ GEM
|
|
22
23
|
ffi (>= 1.0.1)
|
23
24
|
gyoku (1.1.1)
|
24
25
|
builder (>= 2.1.2)
|
25
|
-
highline (1.6.21)
|
26
26
|
httpclient (2.4.0)
|
27
27
|
httpi (0.9.7)
|
28
28
|
rack
|
@@ -33,24 +33,30 @@ GEM
|
|
33
33
|
multi_json (>= 1.8.4)
|
34
34
|
mini_portile (0.6.0)
|
35
35
|
multi_json (1.10.1)
|
36
|
+
net-scp (1.2.1)
|
37
|
+
net-ssh (>= 2.6.5)
|
36
38
|
net-ssh (2.9.1)
|
37
39
|
nokogiri (1.6.2.1)
|
38
40
|
mini_portile (= 0.6.0)
|
39
41
|
nori (1.1.5)
|
42
|
+
os (0.9.6)
|
40
43
|
rack (1.5.2)
|
41
44
|
rake (10.3.2)
|
42
|
-
rspec (3.
|
43
|
-
rspec-core (~> 3.
|
44
|
-
rspec-expectations (~> 3.
|
45
|
-
rspec-mocks (~> 3.
|
46
|
-
rspec-core (3.
|
47
|
-
rspec-support (~> 3.
|
48
|
-
rspec-expectations (3.
|
45
|
+
rspec (3.1.0)
|
46
|
+
rspec-core (~> 3.1.0)
|
47
|
+
rspec-expectations (~> 3.1.0)
|
48
|
+
rspec-mocks (~> 3.1.0)
|
49
|
+
rspec-core (3.1.7)
|
50
|
+
rspec-support (~> 3.1.0)
|
51
|
+
rspec-expectations (3.1.2)
|
49
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
-
rspec-support (~> 3.
|
51
|
-
rspec-
|
52
|
-
rspec-
|
53
|
-
|
53
|
+
rspec-support (~> 3.1.0)
|
54
|
+
rspec-its (1.0.1)
|
55
|
+
rspec-core (>= 2.99.0.beta1)
|
56
|
+
rspec-expectations (>= 2.99.0.beta1)
|
57
|
+
rspec-mocks (3.1.3)
|
58
|
+
rspec-support (~> 3.1.0)
|
59
|
+
rspec-support (3.1.2)
|
54
60
|
rubyntlm (0.1.1)
|
55
61
|
savon (0.9.5)
|
56
62
|
akami (~> 1.0)
|
@@ -60,12 +66,14 @@ GEM
|
|
60
66
|
nokogiri (>= 1.4.0)
|
61
67
|
nori (~> 1.0)
|
62
68
|
wasabi (~> 1.0)
|
63
|
-
serverspec (
|
64
|
-
|
69
|
+
serverspec (2.3.1)
|
70
|
+
multi_json
|
71
|
+
rspec (~> 3.0)
|
72
|
+
rspec-its
|
73
|
+
specinfra (~> 2.3)
|
74
|
+
specinfra (2.4.1)
|
75
|
+
net-scp
|
65
76
|
net-ssh
|
66
|
-
rspec (>= 2.13.0)
|
67
|
-
specinfra (>= 0.7.1)
|
68
|
-
specinfra (1.22.0)
|
69
77
|
uuidtools (2.1.4)
|
70
78
|
wasabi (1.0.0)
|
71
79
|
nokogiri (>= 1.4.0)
|
@@ -86,5 +94,5 @@ DEPENDENCIES
|
|
86
94
|
bundler
|
87
95
|
nodespec!
|
88
96
|
rake
|
89
|
-
rspec (~> 3.
|
97
|
+
rspec (~> 3.1)
|
90
98
|
winrm
|
data/README.md
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
nodespec
|
2
2
|
========
|
3
3
|
|
4
|
-
RSpec style tests for multiple nodes/server instances with support for provisioning with puppet, chef, ansible
|
4
|
+
RSpec style tests for multiple nodes/server instances with support for provisioning with puppet, chef, ansible.
|
5
|
+
|
6
|
+
- [**Read the documentation**](https://github.com/smontanari/nodespec/wiki)
|
5
7
|
|
6
8
|
## Nodespec vs Serverspec
|
7
9
|
[Serverspec](http://serverspec.org) is a popular gem that allows you to write rspec tests to validate your servers/hosts configuration.
|
8
|
-
|
10
|
+
|
9
11
|
Nodespec is not an alternative to Serverspec, rather it's build on top of it, so you can still leverage all of its features while enjoying some extra goodies.
|
10
12
|
|
11
13
|
#### What's different
|
@@ -37,7 +39,7 @@ end
|
|
37
39
|
No more ruby code and create programmatically SSH objects, just a quick and easy inline (or file/yaml based) configuration:
|
38
40
|
|
39
41
|
```ruby
|
40
|
-
describe "test.
|
42
|
+
describe "test.example.com", nodespec: {
|
41
43
|
'adapter' => 'ssh',
|
42
44
|
'user' => 'testuser',
|
43
45
|
'keys' => 'path/to/key'
|
@@ -48,10 +50,10 @@ end
|
|
48
50
|
#### Support connections to Windows & Un*x servers
|
49
51
|
One of the major limitations of serverspec is that you have to make a hard decision beforehand on which OS/backend you are targeting with your tests. In particular you have to include specific specinfra modules in your `spec_helper` depending on whether you're connecting to Un\*x or Windows machines, and you cannot test both OS as part of the same spec run (unless you start hacking some conditional logic in your spec_helper, that is).
|
50
52
|
|
51
|
-
With Nodespec that problem is resolved and you can easily connect and test multiple OS and multiple backends in the same rspec run. For instance, to connect to a
|
53
|
+
With Nodespec that problem is resolved and you can easily connect and test multiple OS and multiple backends in the same rspec run. For instance, to connect to a Gentoo box:
|
52
54
|
```ruby
|
53
55
|
describe "test.example2.com", nodespec: {
|
54
|
-
'os' => '
|
56
|
+
'os' => 'Gentoo',
|
55
57
|
'adapter' => 'winrm',
|
56
58
|
'user' => 'testuser',
|
57
59
|
'pass' => 'somepass',
|
@@ -80,15 +82,15 @@ end
|
|
80
82
|
|
81
83
|
#### Puppet
|
82
84
|
```ruby
|
83
|
-
describe "
|
85
|
+
describe "test.server", nodespec: {'adapter' => 'ssh'} do
|
84
86
|
before :all do
|
85
87
|
provision_node_with_puppet do
|
86
88
|
set_modulepaths '/vshared/src/modules'
|
87
89
|
set_hieradata('users' => {'roger' => {'uid' => 5801}, 'peter' => {'uid' => 5802}})
|
88
90
|
puppet_apply_execute "include demo::wheel_users"
|
89
|
-
end
|
91
|
+
end
|
90
92
|
end
|
91
|
-
...
|
93
|
+
...
|
92
94
|
end
|
93
95
|
```
|
94
96
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'specinfra/backend'
|
2
|
+
%w[exec cmd ssh winrm].each {|f| require_relative "backend_proxy/#{f}"}
|
3
|
+
|
4
|
+
module NodeSpec
|
5
|
+
module BackendProxy
|
6
|
+
PROXIES = {
|
7
|
+
exec: 'Exec',
|
8
|
+
ssh: 'Ssh',
|
9
|
+
cmd: 'Cmd',
|
10
|
+
winrm: 'Winrm'
|
11
|
+
}
|
12
|
+
class SpecinfraCompatibilityError < StandardError; end
|
13
|
+
|
14
|
+
PROXIES.values.each do |name|
|
15
|
+
raise SpecinfraCompatibilityError.new("Specinfra::Backend::#{name} is not defined!") unless Specinfra::Backend.const_defined?(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create(backend, *args)
|
19
|
+
class_name = PROXIES.fetch(backend, PROXIES[:exec])
|
20
|
+
self.const_get(class_name).send(:new, *args)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -6,16 +6,16 @@ module NodeSpec
|
|
6
6
|
module CommunicationAdapters
|
7
7
|
class AwsEc2
|
8
8
|
GEMLOAD_ERROR = 'In order to use any aws adapter you must install the Amazon Web Service gem'
|
9
|
-
def self.communicator_for(node_name,
|
9
|
+
def self.communicator_for(node_name, options = {})
|
10
10
|
RuntimeGemLoader.require_or_fail('aws-sdk', GEMLOAD_ERROR) do
|
11
11
|
instance_name = options['instance'] || node_name
|
12
12
|
ec2_instance = AWS.ec2.instances[instance_name]
|
13
13
|
|
14
14
|
raise "EC2 Instance #{instance_name} is not reachable" unless ec2_instance.exists? && ec2_instance.status == :running
|
15
15
|
if options.has_key?('winrm')
|
16
|
-
WinrmCommunicator.new(ec2_instance.public_dns_name,
|
16
|
+
WinrmCommunicator.new(ec2_instance.public_dns_name, options['winrm'])
|
17
17
|
else
|
18
|
-
SshCommunicator.new(ec2_instance.public_dns_name,
|
18
|
+
SshCommunicator.new(ec2_instance.public_dns_name, options['ssh'] || {})
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -1,31 +1,24 @@
|
|
1
|
+
require 'os'
|
1
2
|
require 'nodespec/verbose_output'
|
2
|
-
|
3
|
+
require 'nodespec/backend_proxy'
|
3
4
|
|
4
5
|
module NodeSpec
|
5
6
|
module CommunicationAdapters
|
6
7
|
class NativeCommunicator
|
7
|
-
include LocalBackend
|
8
8
|
include VerboseOutput
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def bind_to(configuration)
|
11
|
+
configuration.unbind_ssh_session
|
12
|
+
configuration.unbind_winrm_session
|
13
|
+
verbose_puts "\nRunning on local host..."
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
msg << ":#{configuration.ssh.options[:port]}" if configuration.ssh.options[:port]
|
20
|
-
verbose_puts msg
|
21
|
-
configuration.ssh.close
|
22
|
-
configuration.ssh = nil
|
23
|
-
verbose_puts "\nRunning on local host..."
|
24
|
-
end
|
16
|
+
def backend_proxy
|
17
|
+
BackendProxy.create(backend)
|
18
|
+
end
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
end
|
20
|
+
def backend
|
21
|
+
OS.windows? ? :cmd : :exec
|
29
22
|
end
|
30
23
|
end
|
31
24
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
require 'net/ssh'
|
2
1
|
require_relative 'ssh_communicator'
|
3
2
|
|
4
3
|
module NodeSpec
|
5
4
|
module CommunicationAdapters
|
6
5
|
class Ssh
|
7
|
-
def self.communicator_for(node_name,
|
6
|
+
def self.communicator_for(node_name, options = {})
|
8
7
|
opts = options.dup
|
9
8
|
host = opts.delete('host') || node_name
|
10
|
-
SshCommunicator.new(host,
|
9
|
+
SshCommunicator.new(host, opts)
|
11
10
|
end
|
12
11
|
end
|
13
12
|
end
|
@@ -1,17 +1,15 @@
|
|
1
1
|
require 'net/ssh'
|
2
2
|
require 'nodespec/verbose_output'
|
3
|
-
|
3
|
+
require 'nodespec/backend_proxy'
|
4
4
|
|
5
5
|
module NodeSpec
|
6
6
|
module CommunicationAdapters
|
7
7
|
class SshCommunicator
|
8
8
|
include VerboseOutput
|
9
|
-
|
10
|
-
attr_reader :session, :os
|
9
|
+
attr_reader :session
|
11
10
|
|
12
|
-
def initialize(host,
|
11
|
+
def initialize(host, options = {})
|
13
12
|
@host = host
|
14
|
-
@os = os
|
15
13
|
@ssh_options = Net::SSH.configuration_for(@host)
|
16
14
|
@user = options['user'] || @ssh_options[:user]
|
17
15
|
%w[port password keys].each do |param|
|
@@ -20,34 +18,23 @@ module NodeSpec
|
|
20
18
|
end
|
21
19
|
|
22
20
|
def bind_to(configuration)
|
23
|
-
configuration.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
configuration.ssh = current_session
|
21
|
+
configuration.unbind_winrm_session
|
22
|
+
|
23
|
+
@session = configuration.bind_ssh_session_for(@host, @ssh_options[:port]) do
|
24
|
+
msg = "\nConnecting to #{@host}"
|
25
|
+
msg << ":#{@ssh_options[:port]}" if @ssh_options[:port]
|
26
|
+
msg << " as #{@user}..."
|
27
|
+
verbose_puts msg
|
28
|
+
Net::SSH.start(@host, @user, @ssh_options)
|
32
29
|
end
|
33
|
-
@session = current_session
|
34
30
|
end
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
def close_ssh_session(session)
|
39
|
-
msg = "\nClosing connection to #{session.host}"
|
40
|
-
msg << ":#{session.options[:port]}" if session.options[:port]
|
41
|
-
verbose_puts msg
|
42
|
-
session.close
|
32
|
+
def backend_proxy
|
33
|
+
BackendProxy.create(:ssh, @session)
|
43
34
|
end
|
44
35
|
|
45
|
-
def
|
46
|
-
|
47
|
-
msg << ":#{@ssh_options[:port]}" if @ssh_options[:port]
|
48
|
-
msg << " as #{@user}..."
|
49
|
-
verbose_puts msg
|
50
|
-
Net::SSH.start(@host, @user, @ssh_options)
|
36
|
+
def backend
|
37
|
+
:ssh
|
51
38
|
end
|
52
39
|
end
|
53
40
|
end
|
@@ -4,10 +4,10 @@ require_relative 'ssh_communicator'
|
|
4
4
|
module NodeSpec
|
5
5
|
module CommunicationAdapters
|
6
6
|
class Vagrant
|
7
|
-
def self.communicator_for(node_name,
|
7
|
+
def self.communicator_for(node_name, options = {})
|
8
8
|
vm_name = options['vm_name'] || node_name
|
9
9
|
fetch_connection_details(vm_name) do |host, opts|
|
10
|
-
SshCommunicator.new(host,
|
10
|
+
SshCommunicator.new(host, opts)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -3,10 +3,10 @@ require_relative 'winrm_communicator'
|
|
3
3
|
module NodeSpec
|
4
4
|
module CommunicationAdapters
|
5
5
|
class Winrm
|
6
|
-
def self.communicator_for(node_name,
|
6
|
+
def self.communicator_for(node_name, options = {})
|
7
7
|
opts = options.dup
|
8
8
|
hostname = opts.delete('host') || node_name
|
9
|
-
WinrmCommunicator.new(hostname,
|
9
|
+
WinrmCommunicator.new(hostname, opts)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -1,24 +1,23 @@
|
|
1
|
+
require 'winrm'
|
1
2
|
require 'nodespec/verbose_output'
|
2
3
|
require 'nodespec/runtime_gem_loader'
|
3
|
-
|
4
|
+
require 'nodespec/backend_proxy'
|
4
5
|
|
5
6
|
module NodeSpec
|
6
7
|
module CommunicationAdapters
|
7
8
|
class WinrmCommunicator
|
8
|
-
include RemoteBackend
|
9
9
|
include VerboseOutput
|
10
10
|
DEFAULT_PORT = 5985
|
11
11
|
DEFAULT_TRANSPORT = :plaintext
|
12
12
|
DEFAULT_TRANSPORT_OPTIONS = {disable_sspi: true}
|
13
|
-
|
14
|
-
attr_reader :session, :os
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
attr_reader :session
|
15
|
+
|
16
|
+
def initialize(host, options = {})
|
17
|
+
@host = host
|
19
18
|
opts = options.dup
|
20
19
|
port = opts.delete('port') || DEFAULT_PORT
|
21
|
-
@endpoint = "http://#{
|
20
|
+
@endpoint = "http://#{host}:#{port}/wsman"
|
22
21
|
|
23
22
|
if opts.has_key?('transport')
|
24
23
|
@transport = opts.delete('transport').to_sym
|
@@ -31,34 +30,22 @@ module NodeSpec
|
|
31
30
|
end
|
32
31
|
|
33
32
|
def bind_to(configuration)
|
34
|
-
|
35
|
-
close_ssh_session(configuration.ssh)
|
36
|
-
configuration.ssh = nil
|
37
|
-
end
|
33
|
+
configuration.unbind_ssh_session
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
@session = configuration.bind_winrm_session_for(@host, @endpoint) do
|
36
|
+
RuntimeGemLoader.require_or_fail('winrm') do
|
37
|
+
verbose_puts "\nConnecting to #{@endpoint}..."
|
38
|
+
WinRM::WinRMWebService.new(@endpoint, @transport, @options)
|
39
|
+
end
|
44
40
|
end
|
45
|
-
@session = current_session
|
46
41
|
end
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
def close_ssh_session(session)
|
51
|
-
msg = "\nClosing connection to #{session.host}"
|
52
|
-
msg << ":#{session.options[:port]}" if session.options[:port]
|
53
|
-
verbose_puts msg
|
54
|
-
session.close
|
43
|
+
def backend_proxy
|
44
|
+
BackendProxy.create(:winrm, @session)
|
55
45
|
end
|
56
46
|
|
57
|
-
def
|
58
|
-
|
59
|
-
verbose_puts "\nConnecting to #{@endpoint}..."
|
60
|
-
WinRM::WinRMWebService.new(@endpoint, @transport, @options)
|
61
|
-
end
|
47
|
+
def backend
|
48
|
+
:winrm
|
62
49
|
end
|
63
50
|
end
|
64
51
|
end
|
@@ -2,13 +2,13 @@ require 'nodespec/communication_adapters/native_communicator'
|
|
2
2
|
|
3
3
|
module NodeSpec
|
4
4
|
module CommunicationAdapters
|
5
|
-
def self.get_communicator(node_name,
|
5
|
+
def self.get_communicator(node_name, adapter_name = nil, adapter_options = {})
|
6
6
|
if adapter_name
|
7
7
|
require_relative "communication_adapters/#{adapter_name}.rb"
|
8
8
|
clazz = adapter_class(adapter_name)
|
9
|
-
clazz.communicator_for(node_name,
|
9
|
+
clazz.communicator_for(node_name, adapter_options)
|
10
10
|
else
|
11
|
-
NativeCommunicator.new
|
11
|
+
NativeCommunicator.new
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'nodespec/verbose_output'
|
2
|
+
|
3
|
+
module NodeSpec
|
4
|
+
class ConfigurationBinding
|
5
|
+
include VerboseOutput
|
6
|
+
|
7
|
+
def initialize(configuration)
|
8
|
+
@configuration = configuration
|
9
|
+
end
|
10
|
+
|
11
|
+
def bind_ssh_session_for(host, port)
|
12
|
+
current_session = @configuration.ssh
|
13
|
+
if current_session.nil? || current_session.host != host || current_session.options[:port] != port
|
14
|
+
unbind_ssh_session
|
15
|
+
current_session = yield
|
16
|
+
@configuration.ssh = current_session
|
17
|
+
@configuration.ssh_options = current_session.options
|
18
|
+
@configuration.host = current_session.host
|
19
|
+
end
|
20
|
+
current_session
|
21
|
+
end
|
22
|
+
|
23
|
+
def bind_winrm_session_for(host, endpoint)
|
24
|
+
current_session = @configuration.winrm
|
25
|
+
if current_session.nil? || current_session.endpoint != endpoint
|
26
|
+
unbind_winrm_session
|
27
|
+
current_session = yield
|
28
|
+
@configuration.winrm = current_session
|
29
|
+
@configuration.host = host
|
30
|
+
end
|
31
|
+
current_session
|
32
|
+
end
|
33
|
+
|
34
|
+
def unbind_ssh_session
|
35
|
+
if @configuration.ssh
|
36
|
+
msg = "\nClosing connection to #{@configuration.ssh.host}"
|
37
|
+
msg << ":#{@configuration.ssh.options[:port]}" if @configuration.ssh.options[:port]
|
38
|
+
verbose_puts msg
|
39
|
+
@configuration.ssh.close
|
40
|
+
end
|
41
|
+
@configuration.ssh = @configuration.ssh_options = @configuration.host =nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def unbind_winrm_session
|
45
|
+
@configuration.winrm = @configuration.host = nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/nodespec/node.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
require 'specinfra/helper'
|
2
1
|
require 'nodespec/communication_adapters'
|
3
|
-
require 'nodespec/communication_adapters/native_communicator'
|
4
2
|
|
5
3
|
module NodeSpec
|
6
4
|
class Node
|
@@ -14,7 +12,7 @@ module NodeSpec
|
|
14
12
|
opts = (options || {}).dup
|
15
13
|
@os = opts.delete('os')
|
16
14
|
adapter_name = opts.delete('adapter')
|
17
|
-
@communicator = CommunicationAdapters.get_communicator(@name,
|
15
|
+
@communicator = CommunicationAdapters.get_communicator(@name, adapter_name, opts)
|
18
16
|
end
|
19
17
|
|
20
18
|
def backend
|
data/lib/nodespec/version.rb
CHANGED
data/lib/nodespec.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'rspec'
|
2
|
-
|
3
2
|
require 'serverspec'
|
3
|
+
require 'specinfra'
|
4
|
+
|
4
5
|
require 'nodespec/node_configurations'
|
6
|
+
require 'nodespec/configuration_binding'
|
5
7
|
require 'nodespec/run_options'
|
6
8
|
require 'nodespec/provisioning'
|
7
9
|
|
@@ -19,17 +21,13 @@ RSpec.configure do |config|
|
|
19
21
|
config.before :all do |eg|
|
20
22
|
if eg.class.metadata.key?(:nodespec)
|
21
23
|
NodeSpec.set_current_node(eg.class.description, eg.class.metadata[:nodespec]) do |node|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
24
|
+
property[:os] = nil # prevent os caching so we can switch os for any node test
|
25
|
+
config.os = Specinfra::Helper::DetectOs.const_get(node.os).detect if node.os
|
26
|
+
|
27
|
+
Specinfra.configuration.backend = node.backend
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
if subject_type == Serverspec::Type.name
|
31
|
-
subject.extend SpecInfra::Helper.const_get(NodeSpec.current_node.backend)
|
32
|
-
subject.extend SpecInfra::Helper.const_get(NodeSpec.current_node.os || 'DetectOS')
|
29
|
+
node.communicator.bind_to(NodeSpec::ConfigurationBinding.new(config))
|
30
|
+
end
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
data/nodespec.gemspec
CHANGED
@@ -8,9 +8,11 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = NodeSpec::VERSION
|
9
9
|
gem.summary = 'RSpec style tests for multiple nodes/server instances with support for provisioning instructions'
|
10
10
|
gem.description = 'RSpec style tests for multiple nodes/server instances with support for provisioning instructions'
|
11
|
-
|
11
|
+
|
12
12
|
gem.authors = ['Silvio Montanari']
|
13
13
|
gem.homepage = 'https://github.com/smontanari/nodespec'
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
14
16
|
gem.files = `git ls-files`.split($/)
|
15
17
|
gem.test_files = gem.files.grep(%r{^spec/})
|
16
18
|
gem.require_paths = ['lib']
|
@@ -18,9 +20,10 @@ Gem::Specification.new do |gem|
|
|
18
20
|
gem.required_ruby_version = '>= 1.9.3'
|
19
21
|
|
20
22
|
gem.add_runtime_dependency 'net-ssh'
|
21
|
-
gem.add_runtime_dependency 'serverspec'
|
22
|
-
gem.add_runtime_dependency 'specinfra', '
|
23
|
-
gem.
|
23
|
+
gem.add_runtime_dependency 'serverspec', '~> 2.3'
|
24
|
+
gem.add_runtime_dependency 'specinfra', '~> 2.4'
|
25
|
+
gem.add_runtime_dependency 'os'
|
26
|
+
gem.add_development_dependency 'rspec', '~> 3.1'
|
24
27
|
gem.add_development_dependency 'aws-sdk'
|
25
28
|
gem.add_development_dependency 'winrm'
|
26
29
|
gem.add_development_dependency 'bundler'
|
@@ -13,20 +13,20 @@ module NodeSpec
|
|
13
13
|
allow(subject).to receive(:execute_within_timeout).with(actual_command).and_yield
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
|
17
17
|
it 'returns true if the command succeeds' do
|
18
18
|
allow(cmd_status).to receive(:success?).and_return(true)
|
19
|
-
|
19
|
+
|
20
20
|
expect(subject.execute(original_command)).to be_truthy
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns false if the command fails' do
|
24
24
|
allow(cmd_status).to receive(:success?).and_return(false)
|
25
|
-
|
25
|
+
|
26
26
|
expect(subject.execute(original_command)).to be_falsy
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it_behaves_like 'a command run', 'test command', 'test command', false
|
31
31
|
it_behaves_like 'a command run', 'test command', 'sudo test command', true
|
32
32
|
end
|