Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to store environment variables as facts #13

Merged
merged 2 commits into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 65 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,7 @@ require 'voxpupuli/acceptance/spec_helper'
configure_beaker
```

It is also possible to do per host configuration

```ruby
require 'voxpupuli/acceptance/spec_helper_acceptance'

configure_beaker do |host|
if fact_on(host, 'os.name') == 'CentOS'
install_package(host, 'epel-release')
end
end
```
# Running tests

This module provides no rake helpers but leaves that to [puppetlabs_spec_helper](https://github.com/puppetlabs/puppetlabs_spec_helper). Commonly invoked as:

Expand All @@ -46,9 +36,31 @@ Other common environment variables:
* `BEAKER_destroy` can be set to `no` to avoid destroying the box after completion. Useful to inspect failures
* `BEAKER_provision` can be set to `no` to reuse a box. Note that the box must exist already. See `BEAKER_destroy`

# Modules
Since it's still plain [RSpec](https://rspec.info/), it is also possible to call an individual test file:

```bash
BEAKER_setfile=centos7-64 bundle exec rspec spec/acceptance/my_test.rb
```

# Customizing host configuration

## Per host configuration

It is also possible to do per host configuration by providing a block:

```ruby
require 'voxpupuli/acceptance/spec_helper_acceptance'

configure_beaker do |host|
if fact_on(host, 'os.name') == 'CentOS'
install_package(host, 'epel-release')
end
end
```

## Installing Puppet Modules

## Metadata
### Metadata

By default the module uses [beaker-module_install_helper](https://github.com/puppetlabs/beaker-module_install_helper). Its approach is copying the module and then install every dependency as listed in the module's metadata.json. This is a slow process and if the latest modules aren't accepted, it can lead to problems.

Expand All @@ -57,7 +69,7 @@ By default the module uses [beaker-module_install_helper](https://github.com/pup
configure_beaker(modules: :metadata)
```

## Fixtures
### Fixtures

An alternative is to use the fixtures:

Expand All @@ -72,9 +84,47 @@ This will switch to use [puppet-modulebuilder](https://github.com/puppetlabs/pup
task :beaker => "spec_prep"
```

## None
### None

It's also possible to skip module installation altogether, giving the module developer complete freedom to handle this.
```ruby
configure_beaker(modules: nil)
```

## Environment variables to facts

It can be useful to provide facts via environment variables. A possible use is run the test suite with version 1.0 and 1.1. Often it's much easier to run the entire suite with version 1.0 and run it with 1.1 in a complete standalone fashion.

Voxpupuli-acceptance converts all environment variables starting with `BEAKER_FACTER_` and stores them in `/etc/facter/facts.d/voxpupuli-acceptance-env.json` on the target machine. All environment variables are converted to lowercase.

Given following `spec_helper_acceptance.rb` is used:

```ruby
require 'voxpupuli/acceptance/spec_helper_acceptance'

MANIFEST = <<PUPPET
class { 'mymodule':
version => fact('mymodule_version'),
}
PUPPET

configure_beaker do |host|
apply_manifest_on(host, MANIFEST, catch_failures: true)
end
```

Then it can be tested with:
```bash
BEAKER_FACTER_MYMODULE_VERSION=1.0 bundle exec rake beaker
BEAKER_FACTER_MYMODULE_VERSION=1.1 bundle exec rake beaker
```

Many CI systems make it easy to build a matrix with this.

If no environment variables are present, the file is removed. It is not possible to store structured facts.

This behavior can be disabled altogether:

```ruby
configure_beaker(configure_facts_from_env: false)
```
31 changes: 30 additions & 1 deletion lib/voxpupuli/acceptance/spec_helper_acceptance.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
def configure_beaker(modules: :metadata, &block)
ENV_VAR_PREFIX = 'BEAKER_FACTER_'
FACT_FILE = '/etc/facter/facts.d/voxpupuli-acceptance-env.json'

def beaker_facts_from_env
facts = {}

ENV.each do |var, value|
next unless var.start_with?(ENV_VAR_PREFIX)

fact = var.sub(ENV_VAR_PREFIX, '').downcase
facts[fact] = value
end

facts
end

def write_beaker_facts_on(hosts)
beaker_facts = beaker_facts_from_env

if beaker_facts.any?
require 'json'
on(hosts, "mkdir -p #{File.dirname(FACT_FILE)} && cat <<VOXPUPULI_BEAKER_ENV_VARS > #{FACT_FILE}\n#{beaker_facts.to_json}\nVOXPUPULI_BEAKER_ENV_VARS")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

took me a little while to wrap my head round this bash heredoc, but it does look correct.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a bit obscure. However, the alternative was using scp_to and that wasn't great either. Ideally beaker would have something like write_to_file(destination, content).

else
on(hosts, "rm -f #{FACT_FILE}")
end
end

def configure_beaker(modules: :metadata, configure_facts_from_env: true, &block)
ENV['PUPPET_INSTALL_TYPE'] ||= 'agent'
ENV['BEAKER_PUPPET_COLLECTION'] ||= 'puppet6'
ENV['BEAKER_debug'] ||= 'true'
Expand Down Expand Up @@ -33,6 +60,8 @@ def configure_beaker(modules: :metadata, &block)
Voxpupupli::Acceptance::Fixtures.install_fixture_modules_on(hosts, fixture_modules)
end

write_beaker_facts_on(hosts) if configure_facts_from_env

if block
hosts.each do |host|
yield host
Expand Down