ansible_spec_plus 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 +7 -0
- data/.gitignore +3 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +73 -0
- data/Guardfile +14 -0
- data/Jenkinsfile +71 -0
- data/README.md +291 -0
- data/ansible_spec_plus.gemspec +26 -0
- data/bin/asp +72 -0
- data/bin/asp-init +78 -0
- data/lib/ansible_spec_plus.rb +653 -0
- data/lib/ansiblespec_helper.rb +34 -0
- data/lib/helpers/buffered_logger.rb +110 -0
- data/lib/helpers/color_formatter.rb +18 -0
- data/lib/helpers/colorize.rb +52 -0
- data/lib/helpers/log.rb +80 -0
- data/lib/helpers/ring_buffer.rb +65 -0
- data/lib/src/.ansiblespec +5 -0
- data/lib/src/.rspec +3 -0
- data/lib/src/spec/spec_helper.rb +92 -0
- data/spec/ansible_spec_plus_spec.rb +553 -0
- data/spec_helper.rb +16 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 71a9057eb22931ac55f3e0ce9a5cd9b6f9488f53
|
4
|
+
data.tar.gz: a5d3515236ba25066e3b288fe6a38ea9720b8fc2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7c1587fa9bf2f5d3098d42081fe7f90f1257ccd2aa3b9881c3fe840c5e69fbca7b452d4c39c840bbd2203eb7184dfc03a0ab318f782a45a910126ccfb683f237
|
7
|
+
data.tar.gz: 2604d9789dcabe4d5a6372218ebeb48057249542234be511d5bb289d0c35d61aac9b81b5c43678cc616bcc13c48b51492a1e12218f0f47ccf2173bbab2bfa9c5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
coderay (1.1.1)
|
5
|
+
diff-lcs (1.3)
|
6
|
+
docile (1.1.5)
|
7
|
+
ffi (1.9.17)
|
8
|
+
formatador (0.2.5)
|
9
|
+
guard (2.14.1)
|
10
|
+
formatador (>= 0.2.4)
|
11
|
+
listen (>= 2.7, < 4.0)
|
12
|
+
lumberjack (~> 1.0)
|
13
|
+
nenv (~> 0.1)
|
14
|
+
notiffany (~> 0.0)
|
15
|
+
pry (>= 0.9.12)
|
16
|
+
shellany (~> 0.0)
|
17
|
+
thor (>= 0.18.1)
|
18
|
+
guard-compat (1.2.1)
|
19
|
+
guard-rspec (4.7.3)
|
20
|
+
guard (~> 2.1)
|
21
|
+
guard-compat (~> 1.1)
|
22
|
+
rspec (>= 2.99.0, < 4.0)
|
23
|
+
json (2.0.3)
|
24
|
+
listen (3.1.5)
|
25
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
26
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
27
|
+
ruby_dep (~> 1.2)
|
28
|
+
lumberjack (1.0.11)
|
29
|
+
method_source (0.8.2)
|
30
|
+
nenv (0.3.0)
|
31
|
+
notiffany (0.1.1)
|
32
|
+
nenv (~> 0.1)
|
33
|
+
shellany (~> 0.0)
|
34
|
+
pry (0.10.4)
|
35
|
+
coderay (~> 1.1.0)
|
36
|
+
method_source (~> 0.8.1)
|
37
|
+
slop (~> 3.4)
|
38
|
+
rb-fsevent (0.9.8)
|
39
|
+
rb-inotify (0.9.8)
|
40
|
+
ffi (>= 0.5.0)
|
41
|
+
rspec (3.5.0)
|
42
|
+
rspec-core (~> 3.5.0)
|
43
|
+
rspec-expectations (~> 3.5.0)
|
44
|
+
rspec-mocks (~> 3.5.0)
|
45
|
+
rspec-core (3.5.4)
|
46
|
+
rspec-support (~> 3.5.0)
|
47
|
+
rspec-expectations (3.5.0)
|
48
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
49
|
+
rspec-support (~> 3.5.0)
|
50
|
+
rspec-mocks (3.5.0)
|
51
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
52
|
+
rspec-support (~> 3.5.0)
|
53
|
+
rspec-support (3.5.0)
|
54
|
+
ruby_dep (1.5.0)
|
55
|
+
shellany (0.0.1)
|
56
|
+
simplecov (0.12.0)
|
57
|
+
docile (~> 1.1.0)
|
58
|
+
json (>= 1.8, < 3)
|
59
|
+
simplecov-html (~> 0.10.0)
|
60
|
+
simplecov-html (0.10.0)
|
61
|
+
slop (3.6.0)
|
62
|
+
thor (0.19.4)
|
63
|
+
|
64
|
+
PLATFORMS
|
65
|
+
ruby
|
66
|
+
|
67
|
+
DEPENDENCIES
|
68
|
+
guard-rspec
|
69
|
+
rspec
|
70
|
+
simplecov
|
71
|
+
|
72
|
+
BUNDLED WITH
|
73
|
+
1.13.6
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
2
|
+
require "guard/rspec/dsl"
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
# RSpec files
|
6
|
+
rspec = dsl.rspec
|
7
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
8
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
9
|
+
watch(rspec.spec_files)
|
10
|
+
|
11
|
+
# Ruby files
|
12
|
+
ruby = dsl.ruby
|
13
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
14
|
+
end
|
data/Jenkinsfile
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!groovy
|
2
|
+
|
3
|
+
node('master') {
|
4
|
+
|
5
|
+
currentBuild.result = "SUCCESS"
|
6
|
+
|
7
|
+
try {
|
8
|
+
|
9
|
+
stage('Checkout') {
|
10
|
+
|
11
|
+
deleteDir()
|
12
|
+
|
13
|
+
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'LocalBranch', localBranch: 'master']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '2e705f31-c6c1-4e5d-8568-49c1562dccbe', url: 'git@github.com:consort-it/ansible_spec_plus.git']]])
|
14
|
+
|
15
|
+
}
|
16
|
+
|
17
|
+
stage('Version') {
|
18
|
+
|
19
|
+
sh "sed -i 's/^ gem.version.*/ gem.version = \"1.0.${env.BUILD_NUMBER}\"/g' ansible_spec_plus.gemspec"
|
20
|
+
|
21
|
+
}
|
22
|
+
|
23
|
+
stage('Build') {
|
24
|
+
|
25
|
+
sh "gem build ansible_spec_plus.gemspec"
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
stage('Release') {
|
30
|
+
|
31
|
+
sh ""
|
32
|
+
|
33
|
+
}
|
34
|
+
|
35
|
+
// stage('Notification') {
|
36
|
+
//
|
37
|
+
// GIT_AUTHOR = sh (
|
38
|
+
// script: 'git --no-pager show -s --format="%an <%ae>" HEAD',
|
39
|
+
// returnStdout: true
|
40
|
+
// ).trim()
|
41
|
+
//
|
42
|
+
// GIT_COMMIT_MESSAGE = sh (
|
43
|
+
// script: 'git --no-pager show -s --format="%s" HEAD',
|
44
|
+
// returnStdout: true
|
45
|
+
// ).trim()
|
46
|
+
//
|
47
|
+
// mail body: "${GIT_AUTHOR} hat erfolgreich folgende Änderung auf http://www.consort-academy.de deployt:\n\n${GIT_COMMIT_MESSAGE}\n\nSiehe ${env.BUILD_URL}",
|
48
|
+
// from: 'jenkins@consort-it.de',
|
49
|
+
// replyTo: 'jenkins@consort-it.de',
|
50
|
+
// subject: 'live deployment SUCCESSFUL',
|
51
|
+
// to: 'dev@consort-it.de'
|
52
|
+
//
|
53
|
+
// }
|
54
|
+
|
55
|
+
}
|
56
|
+
|
57
|
+
catch (err) {
|
58
|
+
|
59
|
+
currentBuild.result = "FAILURE"
|
60
|
+
|
61
|
+
// mail body: "${env.BUILD_URL}",
|
62
|
+
// from: 'jenkins@consort-it.de',
|
63
|
+
// replyTo: 'jenkins@consort-it.de',
|
64
|
+
// subject: 'live deployment FAILED',
|
65
|
+
// to: 'dev@consort-it.de'
|
66
|
+
|
67
|
+
throw err
|
68
|
+
|
69
|
+
}
|
70
|
+
|
71
|
+
}
|
data/README.md
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
# ansible_spec_plus
|
2
|
+
|
3
|
+
Tests Ansible roles, hosts and playbooks separately with Serverspec. Provides test coverage. Supports local and remote test execution.
|
4
|
+
|
5
|
+
This is a Ruby gem that uses the [Ansible Config Parser for Serverspec](https://github.com/volanja/ansible_spec) connector and
|
6
|
+
extends it to be able to run tests for roles, hosts or playbooks separately.
|
7
|
+
|
8
|
+
# Features
|
9
|
+
|
10
|
+
- Supports all features of [ansible_spec](https://github.com/volanja/ansible_spec)
|
11
|
+
- Supports listing of available tests
|
12
|
+
- Supports separate test execution of role tests
|
13
|
+
- Supports separate test execution of host tests
|
14
|
+
- Supports separate test execution of playbook tests (playbook tests combine role and hosts tests)
|
15
|
+
- Supports resource code/test coverage
|
16
|
+
- Supports remote (default) and local test execution (on a Vagrant box for example) by a command switch
|
17
|
+
- Currently supported Ansible resources:
|
18
|
+
- file
|
19
|
+
- template
|
20
|
+
- docker_container
|
21
|
+
- docker_image
|
22
|
+
- service
|
23
|
+
- apt
|
24
|
+
- pip
|
25
|
+
- gem
|
26
|
+
|
27
|
+
# Installation
|
28
|
+
|
29
|
+
```
|
30
|
+
$ gem install ansible_spec_plus
|
31
|
+
```
|
32
|
+
|
33
|
+
# Usage
|
34
|
+
|
35
|
+
## Create necessary files
|
36
|
+
|
37
|
+
```
|
38
|
+
$ asp-init
|
39
|
+
create spec
|
40
|
+
create spec/spec_helper.rb
|
41
|
+
create .ansiblespec
|
42
|
+
create .rspec
|
43
|
+
```
|
44
|
+
|
45
|
+
## [Optional] `site.yml`
|
46
|
+
|
47
|
+
This files describes the master playbook and includes all your custom
|
48
|
+
playbooks. Ansible Spec plus relies on all entries when it comes to
|
49
|
+
playbooks. If you ever create a playbook, make sure to add it into `site.yml`,
|
50
|
+
too.
|
51
|
+
|
52
|
+
```site.yml
|
53
|
+
- include: demo.yml
|
54
|
+
- include: another-playbook.yml
|
55
|
+
```
|
56
|
+
|
57
|
+
## [Optional] `.ansiblespec`
|
58
|
+
|
59
|
+
By default, `site.yml` will be used as the playbook and `hosts` as the
|
60
|
+
inventory file. You can either follow these conventions or you can
|
61
|
+
customize the playbook and inventory using an `.ansiblespec` file.
|
62
|
+
|
63
|
+
```.ansiblespec
|
64
|
+
---
|
65
|
+
-
|
66
|
+
playbook: site.yml
|
67
|
+
inventory: hosts
|
68
|
+
hash_behaviour: merge
|
69
|
+
```
|
70
|
+
|
71
|
+
## [Optional] `.rspec`
|
72
|
+
|
73
|
+
Test coverage calculation rested on RSpec's JSON report.
|
74
|
+
|
75
|
+
```.rspec
|
76
|
+
--color
|
77
|
+
--format documentation
|
78
|
+
--format json --out report.json
|
79
|
+
```
|
80
|
+
|
81
|
+
## Inventory
|
82
|
+
|
83
|
+
All inventory files from [ansible_spec](https://github.com/volanja/ansible_spec) are supported
|
84
|
+
as well as Vagrant-style inventory files like this:
|
85
|
+
|
86
|
+
```hosts
|
87
|
+
# Generated by Vagrant
|
88
|
+
|
89
|
+
dev ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_private_key_file=private_key ansible_ssh_user=vagrant
|
90
|
+
```
|
91
|
+
|
92
|
+
These Vagrant-style inventories will be created by Vagrant's VAI plugin. No need to add this to
|
93
|
+
version control. Install the VAI plugin with `vagrant plugin install vai` and add this section
|
94
|
+
to your Vagrantfile:
|
95
|
+
|
96
|
+
```Vagrantfile
|
97
|
+
config.vm.provision :vai do |ansible|
|
98
|
+
ansible.inventory_dir = './'
|
99
|
+
ansible.inventory_filename = 'hosts'
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
## Writing tests
|
104
|
+
|
105
|
+
You can write tests for roles and/or hosts. Create a `*_spec.rb` file at the proper place (see below).
|
106
|
+
Require your spec_helper to include all needed logic and start writing your specs. Use all resource types
|
107
|
+
described at the [Serverspec documentation](http://serverspec.org/resource_types.html).
|
108
|
+
|
109
|
+
## Running tests
|
110
|
+
|
111
|
+
#### Role tests
|
112
|
+
|
113
|
+
Role tests can be found under `roles/<name of your role>/spec/*_spec.rb`. Execute tests by simply typing
|
114
|
+
|
115
|
+
```
|
116
|
+
asp rolespec <name of your role>
|
117
|
+
```
|
118
|
+
|
119
|
+
or - for local test execution on a Vagrant box -
|
120
|
+
|
121
|
+
```
|
122
|
+
asp rolespec <name of your role> -l
|
123
|
+
```
|
124
|
+
|
125
|
+
#### Host tests
|
126
|
+
|
127
|
+
Host tests can be found under `spec/<name of your host>/*_spec.rb`. Execute tests by simply typing
|
128
|
+
|
129
|
+
```
|
130
|
+
asp hostspec <name of your host>
|
131
|
+
```
|
132
|
+
|
133
|
+
or - for local test execution on a Vagrant box -
|
134
|
+
|
135
|
+
```
|
136
|
+
asp hostspec <name of your host> -l
|
137
|
+
```
|
138
|
+
|
139
|
+
#### Playbook tests
|
140
|
+
|
141
|
+
Host tests combine role and host tests for a given playbook. Execute tests by simply typing
|
142
|
+
|
143
|
+
```
|
144
|
+
asp playbookspec <name of your playbook>
|
145
|
+
```
|
146
|
+
|
147
|
+
or - for local test execution on a Vagrant box -
|
148
|
+
|
149
|
+
```
|
150
|
+
asp playbookspec <name of your playbook> -l
|
151
|
+
```
|
152
|
+
|
153
|
+
## Example
|
154
|
+
|
155
|
+
Please see [ansible-example](https://github.com/consort-it/ansible-example) for a full working example.
|
156
|
+
|
157
|
+
```
|
158
|
+
├── Gemfile
|
159
|
+
├── Gemfile.lock
|
160
|
+
├── README.md
|
161
|
+
├── Vagrantfile
|
162
|
+
├── ansible.cfg
|
163
|
+
├── demo.yml
|
164
|
+
├── hosts
|
165
|
+
├── report.json
|
166
|
+
├── roles
|
167
|
+
│ ├── common
|
168
|
+
│ │ ├── defaults
|
169
|
+
│ │ │ └── main.yml
|
170
|
+
│ │ ├── spec
|
171
|
+
│ │ │ └── main_spec.rb
|
172
|
+
│ │ ├── tasks
|
173
|
+
│ │ │ └── main.yml
|
174
|
+
│ │ └── templates
|
175
|
+
│ │ └── profile
|
176
|
+
│ ├── demo
|
177
|
+
│ │ ├── spec
|
178
|
+
│ │ │ └── main_spec.rb
|
179
|
+
│ │ └── tasks
|
180
|
+
│ │ └── main.yml
|
181
|
+
│ └── docker
|
182
|
+
│ ├── defaults
|
183
|
+
│ │ └── main.yml
|
184
|
+
│ ├── spec
|
185
|
+
│ │ └── main_spec.rb
|
186
|
+
│ ├── tasks
|
187
|
+
│ │ └── main.yml
|
188
|
+
│ └── templates
|
189
|
+
│ ├── config.json
|
190
|
+
│ └── docker.cfg
|
191
|
+
├── scripts
|
192
|
+
│ └── bootstrap_ansible.sh
|
193
|
+
├── site.yml
|
194
|
+
└── spec
|
195
|
+
├── demo
|
196
|
+
│ └── demo_spec.rb
|
197
|
+
└── spec_helper.rb
|
198
|
+
```
|
199
|
+
|
200
|
+
1. Create the test code that verifies our future Ansible implementation:
|
201
|
+
|
202
|
+
```roles/docker/spec/common_spec.rb
|
203
|
+
require 'spec_helper'
|
204
|
+
|
205
|
+
describe package('python-pip') do
|
206
|
+
it { should be_installed.by('apt') }
|
207
|
+
end
|
208
|
+
```
|
209
|
+
|
210
|
+
2. Run the test and see it fail:
|
211
|
+
|
212
|
+
`asp rolespec docker`
|
213
|
+
|
214
|
+
```
|
215
|
+
Package "docker-engine"
|
216
|
+
should be installed by "apt"
|
217
|
+
|
218
|
+
Package "python-pip"
|
219
|
+
should be installed by "apt" (FAILED - 1)
|
220
|
+
|
221
|
+
Failures:
|
222
|
+
|
223
|
+
1) Package "python-pip" should be installed by "apt"
|
224
|
+
On host `127.0.0.1'
|
225
|
+
Failure/Error: it { should be_installed.by('apt') }
|
226
|
+
expected Package "python-pip" to be installed by "apt"
|
227
|
+
sudo -p 'Password: ' /bin/sh -c dpkg-query\ -f\ \'\$\{Status\}\'\ -W\ python-pip\ \|\ grep\ -E\ \'\^\(install\|hold\)\ ok\ installed\$\'
|
228
|
+
|
229
|
+
# ./roles/docker/spec/main_spec.rb:8:in `block (2 levels) in <top (required)>'
|
230
|
+
|
231
|
+
Finished in 0.56807 seconds (files took 1.02 seconds to load)
|
232
|
+
2 examples, 1 failure
|
233
|
+
|
234
|
+
Failed examples:
|
235
|
+
|
236
|
+
rspec ./roles/docker/spec/main_spec.rb:8 # Package "python-pip" should be installed by "apt"
|
237
|
+
```
|
238
|
+
|
239
|
+
3. Implement the Ansible feature and provision your system:
|
240
|
+
|
241
|
+
```roles/docker/tasks/main.yml
|
242
|
+
- name: Debian python-pip is present
|
243
|
+
apt:
|
244
|
+
name: python-pip
|
245
|
+
state: present
|
246
|
+
force: yes
|
247
|
+
```
|
248
|
+
|
249
|
+
`vagrant provision demo`
|
250
|
+
|
251
|
+
4. Run the test again and see it pass:
|
252
|
+
|
253
|
+
`asp rolespec docker`
|
254
|
+
|
255
|
+
```
|
256
|
+
Package "docker-engine"
|
257
|
+
should be installed by "apt"
|
258
|
+
|
259
|
+
Package "python-pip"
|
260
|
+
should be installed by "apt"
|
261
|
+
|
262
|
+
Finished in 0.70224 seconds (files took 1.24 seconds to load)
|
263
|
+
2 examples, 0 failures
|
264
|
+
|
265
|
+
W, [2017-04-04T18:57:08.650883 #70141396384260] WARN -- : Unknown resource: {"name"=>"Debian add Docker repository and update apt cache", "apt_repository"=>{"repo"=>"deb https://apt.dockerproject.org/repo ubuntu-trusty main", "update_cache"=>true, "state"=>"present"}, "roles"=>[]}
|
266
|
+
W, [2017-04-04T18:57:08.651194 #70141396384260] WARN -- : Unknown resource: {"name"=>"Debian Daemon is reloaded", "command"=>"systemctl daemon-reload", "when"=>"copy_result|changed and is_systemd is defined", "roles"=>[]}
|
267
|
+
W, [2017-04-04T18:57:08.651412 #70141396384260] WARN -- : Unknown resource: {"name"=>"vagrant user is added to the docker group", "user"=>{"name"=>"vagrant", "group"=>"docker"}, "register"=>"user_result", "roles"=>[]}
|
268
|
+
Total resources: 9
|
269
|
+
Touched resources: 2
|
270
|
+
Resource coverage: 22%
|
271
|
+
|
272
|
+
Uncovered resources:
|
273
|
+
- Package "docker-py"
|
274
|
+
- File "/etc/default/docker"
|
275
|
+
- Service "docker"
|
276
|
+
- File "/root/.docker"
|
277
|
+
- File "/root/.docker/config.json"
|
278
|
+
- File "/home/vagrant/.docker"
|
279
|
+
- File "/home/vagrant/.docker/config.json"
|
280
|
+
```
|
281
|
+
|
282
|
+
# Contributing
|
283
|
+
|
284
|
+
* Fork it
|
285
|
+
* Write awesome code
|
286
|
+
* Test your awesome code (`bundle exec guard` and `rspec` are your friends)
|
287
|
+
* Create your feature branch (`git checkout -b my-new-feature`)
|
288
|
+
* Commit your changes (`git commit -am 'Add some feature'`)
|
289
|
+
* Push to the branch (`git push origin my-new-feature`)
|
290
|
+
* Create new Pull Request at https://github.com/consort-it/ansible_spec_plus
|
291
|
+
* Contact us
|