volanja / ansible_spec Goto Github PK
View Code? Open in Web Editor NEWIt's ruby gem that connect Ansible & Serverspec for Test Driven Server Configuration(or TDD).
License: MIT License
It's ruby gem that connect Ansible & Serverspec for Test Driven Server Configuration(or TDD).
License: MIT License
Hello:
Thanks in advance for your time and attention.
The inventory looks like this
[A_DMGR_GROUP]
abc.cool.com ansible_host=100.8.168.173
[A_NODES_SET1_GROUP]
abc.cool.com ansible_host=100.8.168.173
[A_NODES_SET2_GROUP]
def.cool.com ansible_host=100.8.168.183
[A_NODES_GROUP:children]
A_NODES_SET1_GROUP
A_NODES_SET2_GROUP
[A_SERVERS_GROUP:children]
A_DMGR_GROUP
A_NODES_GROUP
When I run rake -T
I see this error
(?-mix::children)
A_NODES_GROUP:children
A_NODES_SET1_GROUP
A_NODES_SET2_GROUP
(?-mix::children)
A_SERVERS_GROUP:children
A_DMGR_GROUP
{"name"=>"A_NODES_GROUP", "port"=>22, "connection"=>"ssh", "uri"=>"A_NODES_GROUP"}
rake aborted!
TypeError: no implicit conversion of nil into Array
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:115:in `+'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:115:in `block in get_parent'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:114:in `each'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:114:in `get_parent'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:86:in `block in load_targets'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:80:in `each'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:80:in `load_targets'
/usr/local/lib/ruby/gems/2.7.0/gems/ansible_spec-0.3.2/lib/ansible_spec/load_ansible.rb:428:in `get_properties'
/Users/nlakshmi/samples/server_spec/Rakefile:6:in `<top (required)>'
/usr/local/lib/ruby/gems/2.7.0/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
Please suggest how to get around.
I'm trying to verify that a package has been installed on a Redhat server but I get this error:
1) Package "nfs-utils" should be installed
On host `xx.xx.xx.xx'
Failure/Error: it { should be_installed }
expected Package "nfs-utils" to be installed
/bin/sh -c dpkg-query\ -f\ \'\$\{Status\}\'\ -W\ nfs-utils\ \|\ grep\ -E\ \'\^\(install\|hold\)\ ok\ installed\$\'
I've run the exact same test using serverspec and it works fine.
Here's the contents of my Gemfile.lock
GEM
remote: https://rubygems.org/
specs:
ansible_spec (0.2.21)
hostlist_expression
inifile
oj
serverspec (>= 2.0.0)
winrm
builder (3.2.3)
diff-lcs (1.3)
erubis (2.7.0)
ffi (1.9.18)
gssapi (1.2.0)
ffi (>= 1.0.1)
gyoku (1.3.1)
builder (>= 2.1.2)
hostlist_expression (0.2.1)
httpclient (2.8.3)
inifile (3.0.0)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
multi_json (1.12.1)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (4.1.0)
net-telnet (0.1.1)
nori (2.6.0)
oj (3.3.5)
rspec (3.6.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
rspec-mocks (~> 3.6.0)
rspec-core (3.6.0)
rspec-support (~> 3.6.0)
rspec-expectations (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-its (1.2.0)
rspec-core (>= 3.0.0)
rspec-expectations (>= 3.0.0)
rspec-mocks (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-support (3.6.0)
rubyntlm (0.6.2)
serverspec (2.40.0)
multi_json
rspec (~> 3.0)
rspec-its
specinfra (~> 2.68)
sfl (2.3)
specinfra (2.71.1)
net-scp
net-ssh (>= 2.7, < 5.0)
net-telnet
sfl
winrm (2.2.3)
builder (>= 2.1.2)
erubis (~> 2.7)
gssapi (~> 1.2)
gyoku (~> 1.0)
httpclient (~> 2.2, >= 2.2.0.2)
logging (>= 1.6.1, < 3.0)
nori (~> 2.0)
rubyntlm (~> 0.6.0, >= 0.6.1)
PLATFORMS
ruby
DEPENDENCIES
ansible_spec
BUNDLED WITH
1.15.4
Configs like
[defaults]
roles_path: ../../../roles:../../../foo-roles:../../../bar-roles
which are especially useful when unit testing roles fail since roles_patch is currently hardcoded to roles/. I can look into cooking a patch if the other PRs look o.k.
I want to use either of PLAYBOOK
or INVENTORY
.
Example:
$ PLAYBOOK=site.yml rake serverspec:Ansible-Sample-TDD
or
$ INVENTORY=hosts rake serverspec:Ansible-Sample-TDD
I'm using a dynamic inventory: ec2.py
ec2.py --list
contains the following:
"tag_Name_server1": [
"1.2.3.4"
],
"tag_Name_server2": [
"1.2.3.5"
],
My playbook contains:
- name: servers
hosts: tag_Name_server[1:2]
roles:
- server
rake -T
includes:
...
NoMethodError: undefined method`each' for "tag_Name_server[1:2]":String
expected:
rake serverspec:server
should run specs against serves ["1.2.3.4","1.2.3.5"]NoMethodError
above
This ansible variable causes an error in version 0.2.25 of ansible_spec but was working ok in version 0.2.24 and below:
value: '\.(?:gz)$'
Error trace:
On host `localhost'
Failure/Error: vars = AnsibleSpec.get_variables(host, group_idx)
Psych::SyntaxError:
(<unknown>): found unknown escape character while parsing a quoted scalar at line 7 column 14
# /usr/local/rvm/gems/ruby-2.3.0/gems/ansible_spec-0.2.25/lib/ansible_spec/load_ansible.rb:486:in `resolve_variables'
# /usr/local/rvm/gems/ruby-2.3.0/gems/ansible_spec-0.2.25/lib/ansible_spec/load_ansible.rb:551:in `get_variables'
I am using my ansible .ini file as the inventory file specified in .ansiplespec. However I have a structure in my .ini like:
[atlanta]
host1
[raleigh]
host2
[southeast:children]
atlanta
raleigh
[usa:children]
southeast
The southeast group resolves properly, but the usa group does not. I believe there is an issue in the get_parent method in load_ansible.rb.
The host all
is currently not supported:
- name: foo
hosts: all
user: root
gather_facts: True
roles:
- foo
[root@server ansible]# rake -T --trace
rake aborted!
NoMethodError: undefined method `each' for "all":String
/etc/ansible/Rakefile:12:in `block (2 levels) in <top (required)>'
/etc/ansible/Rakefile:11:in `each'
/etc/ansible/Rakefile:11:in `block in <top (required)>'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/task_manager.rb:209:in `in_namespace'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/dsl_definition.rb:147:in `namespace'
/etc/ansible/Rakefile:10:in `<top (required)>'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/rake_module.rb:28:in `load'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/rake_module.rb:28:in `load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:689:in `raw_load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:94:in `block in load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:176:in `standard_exception_handling'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:93:in `load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:77:in `block in run'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:176:in `standard_exception_handling'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:75:in `run'
/opt/rh/rh-ruby22/root/usr/bin/rake:33:in `<main>'
REF: https://github.com/volanja/ansible_spec/blob/master/lib/ansible_spec/load_ansible.rb#L314-L360
It's necessary use any recursive merge (a.k.a deep_merge) in order to solve problems like this:
-> In roles/#{role}/defaults/main.yml
var_a: val_a
var_b:
var_b1: val_b1
var_b2: val_b2
var_b3: val_b3
-> In #{inventory}/group_vars/all
var_c: val_c
var_b:
var_b4: val_b4
var_b5: val_b5
var_b6: val_b6
var_d: val_d
The result must be:
var_a: val_a
var_b:
var_b1: val_b1
var_b2: val_b2
var_b3: val_b3
var_b4: val_b4
var_b5: val_b5
var_b6: val_b6
var_c: val_c
var_d: val_d
But at this moment the result of this function is:
var_a: val_a
var_b:
var_b4: val_b4
var_b5: val_b5
var_b6: val_b6
var_c: val_c
var_d: val_d
I found an issue where when I declare a variable in site.yml, the value that was being passed to my test was nil. I looked into it more and discovered that in the get_variables method in load_ansible file, p[group_idx]['vars'] was an Array that had a Hash in it (I had only declared one variable in site.yml). The merge_variables method, however, accepts a Hash as a parameter. I would like to change the get_variables so that if p[group_idx]['vars'] is an Array, it loops through the Hashes in the Array and calls merge for each.
I need to want to load host_vars and group_vars from inventory directory.
--- lib/ansible_spec/load_ansible.rb 2021-01-04 08:50:28.897320256 +0000
+++ lib/ansible_spec/load_ansible.rb 2021-01-04 09:04:27.855975284 +0000
@@ -529,13 +529,15 @@
vars_dirs_path = "#{vars_dirs_path}/"
end
+ playbook, inventoryfile = load_ansiblespec
# all group
vars = load_vars_file(vars ,"#{vars_dirs_path}group_vars/all", true)
+ # all group on inventory directory
+ vars = load_vars_file(vars ,File.dirname(inventoryfile) + "/group_vars/all", true)
# each group vars
if p[group_idx].has_key?('group')
# get groups parent child relationships
- playbook, inventoryfile = load_ansiblespec
groups_rels = load_targets(inventoryfile, return_type='groups_parent_child_relationships')
# get parental lineage
g = p[group_idx]['group']
@@ -548,11 +550,15 @@
groups_parents_then_child = groups_stack.reverse.flatten
groups_parents_then_child.each{|group|
vars = load_vars_file(vars ,"#{vars_dirs_path}group_vars/#{group}", true)
+ # get var on inventory directory
+ vars = load_vars_file(vars ,File.dirname(inventoryfile) + "/group_vars/#{group}", true)
}
end
# each host vars
vars = load_vars_file(vars ,"#{vars_dirs_path}host_vars/#{host}", true)
+ # each host vars on inventory directory
+ vars = load_vars_file(vars ,File.dirname(inventoryfile) + "/host_vars/#{host}", true)
# site vars
if p[group_idx].has_key?('vars')
In Ansible you can define hosts as expressions.
host-[1-3]
would expand into:
host-1
host-2
host-3
When reading the same inventory files this should be covered in ansible_spec
.
I'm currently working with your great approach and just implemented this here. I released a gem which will make it easy for you to implement it in ansible_spec:
https://github.com/udondan/hostlist_expression-ruby
https://rubygems.org/gems/hostlist_expression
By default, the Rakefile
generated by ansiblespec-init
assumes that groups will be declared in the Ansible inventory. This inventory file works fine:
server ansible_ssh_host=127.0.0.1 ansible_ssh_port=2202 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='.vagrant/machines/server/virtualbox/private_key'
client ansible_ssh_host=127.0.0.1 ansible_ssh_port=2203 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='.vagrant/machines/client/virtualbox/private_key'
[server]
server
[client]
client
This inventory file, however, fails with an error:
server ansible_ssh_host=127.0.0.1 ansible_ssh_port=2202 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='.vagrant/machines/server/virtualbox/private_key'
client ansible_ssh_host=127.0.0.1 ansible_ssh_port=2203 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='.vagrant/machines/client/virtualbox/private_key'
The only difference is the lack of group declarations. The error is:
rake aborted!
NoMethodError: undefined method `each' for "server":String
There are two workarounds here. If using vagrant, simply declare ansible.groups
in the provisioner block. That's excessive for some setups, so a more durable solution is to ensure that the property["hosts"]
attribute in the Rakefile
is a list:
namespace :serverspec do
properties.each do |property|
# Ensure "hosts" is a list. If no groups were specified, "hosts"
# will be a string, which will throw an error when using .each.
property["hosts"] = [*property["hosts"]] # add this line
property["hosts"].each do |host|
desc "Run serverspec for #{property["name"]}"
RSpec::Core::RakeTask.new(property["name"].to_sym) do |t|
Adding the above line will ensure that ansible_spec
interprets the host list correctly. You may wish to update the default Rakefile
created to include the above line, since it works with and without group memberships.
Is it possible to write and run tests that would test playbooks that have 3rd party roles and custom tasks? Assumption with ansible_spec seems to be that all the specs are within roles.
Link #32
If hosts
on playbook don't match group on inventoryfile, puts fail message.
fail "no hosts matched"
Now, puts NoMethodError
$ rake -T --trace
rake aborted!
NoMethodError: undefined method `each' for "xxx":String
/Users/Adr/Development/vagrant_list/ansible-Redmine/Rakefile:12:in `block (2 levels) in <top (required)>'
/Users/Adr/Development/vagrant_list/ansible-Redmine/Rakefile:11:in `each'
/Users/Adr/Development/vagrant_list/ansible-Redmine/Rakefile:11:in `block in <top (required)>'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/task_manager.rb:209:in `in_namespace'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/dsl_definition.rb:146:in `namespace'
/Users/Adr/Development/vagrant_list/ansible-Redmine/Rakefile:10:in `<top (required)>'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/rake_module.rb:28:in `load'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/rake_module.rb:28:in `load_rakefile'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:687:in `raw_load_rakefile'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:94:in `block in load_rakefile'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:176:in `standard_exception_handling'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:93:in `load_rakefile'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:77:in `block in run'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:176:in `standard_exception_handling'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/lib/rake/application.rb:75:in `run'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.3.2/bin/rake:33:in `<top (required)>'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/bin/rake:23:in `load'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/bin/rake:23:in `<main>'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/bin/ruby_executable_hooks:15:in `eval'
/Users/Adr/.rvm/gems/ruby-2.0.0-p353/bin/ruby_executable_hooks:15:in `<main>'
Test sample
https://github.com/serverspec/specinfra
https://github.com/serverspec/specinfra/blob/master/spec/backend/ssh/build_command_spec.rb
Use double. Create Dummy Object.
require 'rspec/mocks/standalone'
Raketask read ENV["PLAYBOOK"] & ENV["INVENTORY"]
I prioritize ENV more than .ansiblespec
Example:
$ PLAYBOOK=site.yml INVENTORY=hosts rake serverspec:Ansible-Sample-TDD
2.0.0-p247
$ ansiblespec-init
/Users/Adr/.rvm/gems/ruby-2.0.0-p247/gems/ansible_spec-0.0.1/lib/ansible_spec.rb:141:in `safe_mkdir': uninitialized constant AnsibleSpec::FileUtils (NameError)
from /Users/Adr/.rvm/gems/ruby-2.0.0-p247/gems/ansible_spec-0.0.1/lib/ansible_spec.rb:52:in `safe_create_spec_helper'
from /Users/Adr/.rvm/gems/ruby-2.0.0-p247/gems/ansible_spec-0.0.1/lib/ansible_spec.rb:11:in `main'
from /Users/Adr/.rvm/gems/ruby-2.0.0-p247/gems/ansible_spec-0.0.1/bin/ansiblespec-init:5:in `<top (required)>'
from /Users/Adr/.rvm/gems/ruby-2.0.0-p247/bin/ansiblespec-init:23:in `load'
from /Users/Adr/.rvm/gems/ruby-2.0.0-p247/bin/ansiblespec-init:23:in `<main>'
http://docs.ansible.com/intro_inventory.html#list-of-behavioral-inventory-parameters
Hello,
When doing a double reference to a variable, ansible_spec only get the first reference then the test fail:
In the playbook:
- name: foo
hosts: server_foo
roles:
- foo
vars:
myvar: "{{ myvar_ingroupvar }}"
In group_vars:
myvar_ingroupvar: 192.168.0.0
Then when we run the test, we have the following error:
1) File "/etc/foo/foo.conf" should contain "{{ myvar_ingroupvar }}"
On host `server_foo'
Failure/Error: it { should contain(property['myvar']).after(/^MY_VAR=/) }
expected File "/etc/foo/foo.conf" to contain "{{ myvar_ingroupvar }}"
When actually "{{ myvar_ingroupvar }}" should be interpreted as 192.168.0.0:
File "/etc/foo/foo.conf" should contain "192.168.0.0"
On host `server_foo'
...
Hello,
I'm using kitchen-test with serverspec and my directory tree for spec files is
roles/myrole/test/integration/(default|somethingelse)/serverspec
If I do a symlink as roles/myroles/spec, ansiblespec is working fine.
is it possible to add a configuration option to specfiles: test/integration/default/serverspec/*_spec.rb ?
Thanks
I need to set sudo password with ansible_spec.
So, I tried following command.
$ ASK_SUDO_PASSWORD=1 bundle exec rake all
But the below error appeared.
Please set sudo password to Specinfra.configuration.sudo_password.
Therefore, I cheked spec/spec_helper.rb and I found below lines.
if ENV['ASK_BECOME_PASSWORD']
begin
require 'highline/import'
rescue LoadError
fail "highline is not available. Try installing it."
end
set :become_password, ask("Enter become password: ") { |q| q.echo = false }
else
set :become_password, ENV['BECOME_PASSWORD']
end
There are some differences from serverspec.
set become_password
is defined instead of set :sudo_password
in ansible_spec.
So, I fixed as follows by reference to serverspec.
- if ENV['ASK_BECOME_PASSWORD']
+ if ENV['ASK_SUDO_PASSWORD']
begin
require 'highline/import'
rescue LoadError
fail "highline is not available. Try installing it."
end
- #set :become_password, ask("Enter become password: ") { |q| q.echo = false }
+ set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false }
else
- #set :become_password, ENV['BECOME_PASSWORD']
+ set :sudo_password, ENV['SUDO_PASSWORD']
end
Now, I have been able to execute it with following command.
$ ASK_SUDO_PASSWORD=1 bundle exec rake all
or
$ export SUDO_PASSWORD=xxxx
$ bundle exec rake all
Why is the function implemented with different way from serverspec?
Which is the better way to set sudo password?
Best regards
http://docs.ansible.com/ansible/intro_configuration.html
Changes can be made and used in a configuration file which will be processed in the following order:
* ANSIBLE_CONFIG (an environment variable)
* ansible.cfg (in the current directory)
* .ansible.cfg (in the home directory)
* /etc/ansible/ansible.cfg
link #32
vars_dirs_path is single target.
So, we can not use ./group_vars, ./host_vars and inventories/A/[group_vars,host_vars]/ using vars_dirs_path.
vars_dirs_path:
- group_vars
- host_vars
- inventories/staging/
Do you have a good idea?
I would like to add a feature where the get_variables method will also get variables from the parent of a host recursively, if the variable is not already defined.
Do you plan to support discovery for tests written in the inspec format, as well as serverspec? Since you've already done so much work on parsing the Ansible inventory and variable files in Ruby, I'd hate to see inspec support relegated to project separate from ansible_spec.
Inspec seems to offer backward compatibility with serverspec tests, but without the need for a lot of spec_helper/Rakefile boilerplate.
Ansible allows multiple ways to define roles in playbooks (see here):
Right now, only this way is supported by ansible_spec:
- name: foo
hosts: server_foo
gather_facts: True
roles:
- foo_role
These two do not work:
- name: foo
hosts: server_foo
gather_facts: True
roles:
- roles: foo_role
- name: foo
hosts: server_foo
gather_facts: True
roles:
- { role: foo_app_instance, dir: '/opt/b', port: 5001 }
Would ne nice if this could be supported!
rake aborted!
NameError: uninitialized constant AnsibleSpec::Open3
/usr/local/lib/ruby/gems/2.2.0/gems/ansible_spec-0.1/lib/ansible_spec/load_ansible.rb:84:in `get_dynamic_inventory'
/usr/local/lib/ruby/gems/2.2.0/gems/ansible_spec-0.1/lib/ansible_spec/load_ansible.rb:10:in `load_targets'
/usr/local/lib/ruby/gems/2.2.0/gems/ansible_spec-0.1/lib/ansible_spec/load_ansible.rb:170:in `get_properties'
/root/ansible/Rakefile:6:in `<top (required)>'
/usr/local/lib/ruby/2.2.0/rake/rake_module.rb:28:in `load'
/usr/local/lib/ruby/2.2.0/rake/rake_module.rb:28:in `load_rakefile'
/usr/local/lib/ruby/2.2.0/rake/application.rb:689:in `raw_load_rakefile'
/usr/local/lib/ruby/2.2.0/rake/application.rb:94:in `block in load_rakefile'
/usr/local/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling'
/usr/local/lib/ruby/2.2.0/rake/application.rb:93:in `load_rakefile'
/usr/local/lib/ruby/2.2.0/rake/application.rb:77:in `block in run'
/usr/local/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling'
/usr/local/lib/ruby/2.2.0/rake/application.rb:75:in `run'
/usr/local/bin/rake:33:in `<main>'
The ec2.py dynamic inventory returns a json object with structure like:
{
"_meta": {
"hostvars": {
"some_key1": {
"ec2_something_something": false,
...
},
"some_key2": {
"ec2_something_something": true,
...
}
...
}
},
"tag_some_other_key1": [
"host-1",
"host-2"
],
"some_other_key2": [
"host-1"
],
...
}
Resulting in the get_dynamic_inventory method to fail with this error:
TypeError: no implicit conversion of String into Integer
/Users/Phil/.rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.1/lib/ansible_spec/load_ansible.rb:95:in `[]'
/Users/Phil/.rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.1/lib/ansible_spec/load_ansible.rb:95:in `block in get_dynamic_inventory'
/Users/Phil/.rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.1/lib/ansible_spec/load_ansible.rb:91:in `each'
/Users/Phil/.rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.1/lib/ansible_spec/load_ansible.rb:91:in `get_dynamic_inventory'
/Users/Phil/.rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.1/lib/ansible_spec/load_ansible.rb:11:in `load_targets'
/Users/Phil/.rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.1/lib/ansible_spec/load_ansible.rb:198:in `get_properties'
I can understand that it's not possible to interpret every dynamic inventory (since you can make it return whatever you want), however it would be great if ansible_spec could at least work with the standard ec2.py.
Hello,
Could you support different output format, most notably json?
It would permit integration with other tools like monitoring as shown here
http://www.slideshare.net/m_richardson/serverspec-and-sensu-testing-and-monitoring-collide
Thanks
before(:all)/after(:all)は全テストの前後で実行される。
テスト毎のファイル生成/削除処理を(:all)内で行うのは、誤ったファイルを使う可能性があるので行うべきではない。
Example host inventory of ansible
[HOGE]
host1
host2
host3
host4
host5
host2 has a space before string like '[space]host2'.
host3 has a space after string like 'host3[space] '.
host4 has a tab before string like '[tab]host4'.
host5 has a tab after string like 'host5[tab]'.
Ansible strips space/tab when loading hosts.
$ ansible-inventory -i hosts --list
--- snip ---
"HOGE": {
"hosts": [
"host1",
"host2",
"host3",
"host4",
"host5"
]
},
But ansible_spec does not strip space/tabs.
"[HOGE]"
"host1"
" host2"
"host3 "
"\thost4"
"\thost5\t "
This causes "no implicit conversion of nil into Array" Error when process get_parent method.
Example host inventory of ansible:
[HOGE]
hoge1
hoge2
hoge3
[HOGEHOGE:children]
HOGE
Exception:
no implicit conversion of nil into Array
It will be solved by following change, use "strip" insead of "chomp" in load_ansible.rb.
--- load_ansible.rb.old 2019-05-10 11:02:44.126640188 +0900
+++ load_ansible.rb 2019-05-10 11:03:11.118040115 +0900
@@ -26,7 +26,7 @@
hosts = Hash.new
hosts.default = Hash.new
f.each_line{|line|
- line = line.chomp
+ line = line.strip
# skip
next if line.start_with?('#') #comment
next if line.empty? == true #null
Thanks
When excluding hosts from the playbook, ansible_spec throws an error:
- name: foo
hosts: server_foo:!other_host
user: root
gather_facts: True
roles:
- foo
[root@server ansible]# rake -T --trace
rake aborted!
NoMethodError: undefined method `each' for #<String:0x00000001751a38>
/etc/ansible/Rakefile:12:in `block (2 levels) in <top (required)>'
/etc/ansible/Rakefile:11:in `each'
/etc/ansible/Rakefile:11:in `block in <top (required)>'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/task_manager.rb:209:in `in_namespace'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/dsl_definition.rb:147:in `namespace'
/etc/ansible/Rakefile:10:in `<top (required)>'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/rake_module.rb:28:in `load'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/rake_module.rb:28:in `load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:689:in `raw_load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:94:in `block in load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:176:in `standard_exception_handling'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:93:in `load_rakefile'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:77:in `block in run'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:176:in `standard_exception_handling'
/opt/rh/rh-ruby22/root/usr/share/gems/gems/rake-10.4.2/lib/rake/application.rb:75:in `run'
/opt/rh/rh-ruby22/root/usr/bin/rake:33:in `<main>'
Hello:
Sorry for my ignorance, so please bear with me.
Thank you in advance for your help.
Do I need to expect ruby on the target nodes ?
Do I need install spec_helper.rb on the target nodes ?
or
this tool will parse thru my playbooks and roles and generate a diff set of test playbooks ?
Sorry for my ignorance but I am trying to get a handle on this.
-Narahari
If for some reason the roles list for a host is empty, ansible_spec dies with NoMethodError: undefined method
each' for nil:NilClass`
Here is an example that produces the error
{"name"=>"No-roles-playbook", "hosts"=>["127.0.0.1"], "roles"=>[], "sudo"=>true}
rake aborted!
NoMethodError: undefined method `each' for nil:NilClass
/usr/local/rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.2/lib/ansible_spec/load_ansible.rb:203:in `flatten_role'
/usr/local/rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.2/lib/ansible_spec/load_ansible.rb:185:in `block in load_playbook'
/usr/local/rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.2/lib/ansible_spec/load_ansible.rb:184:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.2/lib/ansible_spec/load_ansible.rb:184:in `load_playbook'
/usr/local/rvm/gems/ruby-2.0.0-p643/gems/ansible_spec-0.2.2/lib/ansible_spec/load_ansible.rb:233:in `get_properties'
I'm using the ec2.py dynamic inventory which creates the following ansible_spec properties from AnsibleSpec.get_properties
{"name"=>"deploy-webserver", "hosts"=>["1.2.3.4"], "user"=>"ec2-user", "sudo"=>true, "roles"=>["webserver"]}
using the generated Rakefile from ansiblespec-init, the ENV['TARGET_HOST']
and ENV['TARGET_PORT']
are not set correctly (both empty) since hosts contains a simple string.
If an Ansible variable is declared in terms of another variable; for example:
user: foo
base_folder: /home/{{user}}/bar
Then the property expansion of 'base_folder' (e.g. file(property['base_folder'])
) only resolves one level, i.e. to /home/{{user}}/bar
when ansible itself would resolve this to /home/foo/bar
.
I am using ansible_spec 0.2.17
The following error is occured.
Used playbooks is hico-horiuchi/jedi-ansible .
I use ruby 2.0.0
and ansible 2.0.2.0
.
/Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/ansible_spec-0.2.13/lib/ansible_spec/load_ansible.rb:408:in `get_variables': undefined method `size' for nil:NilCl
ass (NoMethodError)
from /Users/hiconyan/src/jedi-ansible/spec/spec_helper.rb:13:in `<top (required)>'
from /Users/hiconyan/src/jedi-ansible/roles/common/spec/apt_spec.rb:1:in `require'
from /Users/hiconyan/src/jedi-ansible/roles/common/spec/apt_spec.rb:1:in `<top (required)>'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `load'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `block in load_spec_files'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `each'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `load_spec_files'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:106:in `setup'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:92:in `run'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/hiconyan/src/jedi-ansible/vendor/bundler/ruby/2.0.0/gems/rspec-core-3.4.4/exe/rspec:4:in `<main>'
@aWebprogrammer
said:
ansible provisioner of vagrant export this.
ansible_user='user'
this idiom is not written on Ansible Doc.
According to Ansible Doc, should not use single single.
ansible_user=user
But ansible-inventory
is cut out single quotation.
So, @aWebprogrammer
think that ansible_spec
should cut out single quotation.
The failure condition for ansible_spec when no hosts are matched in the inventory is a problem for my use case.
I am using an ec2 dynamic inventory for a complex system that has 9 different ansible groups with matching playbooks.
In a development environment it is common to create only the servers which are necessary for testing, leaving some of groups without any hosts. This is especially the case if we are trying to test our ansible playbooks with serverspec.
For this reason I changed
fail "no hosts matched"
to
puts "no hosts matched for #{var["hosts"]}"
which is a preferable output, allowing us to proceed with testing.
Currently, if no user is specified in the playbook, tries to connect with an empty user:
[root@server ansible]# rake serverspec:foo
Run serverspec for foo to server
/opt/rh/rh-ruby22/root/usr/bin/ruby -I/opt/rh/rh-ruby22/root/usr/local/share/gems/gems/rspec-support-3.3.0/lib:/opt/rh/rh-ruby22/root/usr/local/share/gems/gems/rspec-core-3.3.1/lib /opt/rh/rh-ruby22/root/usr/local/share/gems/gems/rspec-core-3.3.1/exe/rspec --pattern roles/\{snmpd\}/spec/\*_spec.rb
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
@server's password:
If no user is provided in the playbook, ansible_spec should use current user or the user from the ansible.cfg:
# default user to use for playbooks if user is not specified
# (/usr/bin/ansible will use current user as default)
#remote_user = root
reference
ChangeLog を支える英語
The following error occurs when running rake -T. The Rakefile is unchanged.
[localhost]# rake -T --trace
(in /etc/ansible/roles/snmpd)
rake aborted!
undefined method `to_sym' for nil:NilClass
/etc/ansible/roles/snmpd/Rakefile:14
/etc/ansible/roles/snmpd/Rakefile:12:in `each'
/etc/ansible/roles/snmpd/Rakefile:12
/etc/ansible/roles/snmpd/Rakefile:11:in `each'
/etc/ansible/roles/snmpd/Rakefile:11
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1881:in `in_namespace'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:909:in `namespace'
/etc/ansible/roles/snmpd/Rakefile:10
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2382:in `load'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2382:in `raw_load_rakefile'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2016:in `load_rakefile'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2067:in `standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2015:in `load_rakefile'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1999:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2067:in `standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1997:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19
Here are the installed gems:
[localhost]# gem list --local
*** LOCAL GEMS ***
ansible_spec (0.2)
diff-lcs (1.2.5)
hostlist_expression (0.2.1)
json (1.4.6)
multi_json (1.11.2)
net-scp (1.2.1)
net-ssh (2.9.2)
net-telnet (0.1.1)
oj (2.12.9)
rake (0.8.7)
rspec (3.3.0)
rspec-core (3.3.1)
rspec-expectations (3.3.0)
rspec-its (1.2.0)
rspec-mocks (3.3.1)
rspec-support (3.3.0)
safe_yaml (0.9.4)
serverspec (2.19.0)
specinfra (2.36.14)
OS is:
RHEL 6.6
Linunx 2.6.32-431.20.3.el6.x86_64 #1 SMP Fri Jun 6 18:30:54 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.