Home

Awesome

rspec-puppet-osmash

Build Status

The purpose of this gem is to generate a library of operating system facts (an osmash library) from a Puppet Module metadata file (metadata.json) with some tools, functions and methods for use with rspec-puppet.

Usage

Initialising an osmash library

It is recommend that the osmash library for a Puppet module be initialised in spec/rspec_helper.rb and should automatically find metadata.json relative to this location. The osmash library needs to be a global variable so it is visible to the test scripts that will use it.

$osmash = Rspec_puppet_osmash.new

Adding expectations

This should then be run through something to attach some expectations to each operating system, these expectations should be added using rules rather than explicitly. These rules will most likely be very similar to the operating system selection logic used in the Puppet module itself. A working example can be seen in the Aethylred/puppet-postfix module.

# Adding expectations to the supported operating systems
$osmash.supported.map! do | os |
  # These expectations are shared across all supported OSes
  expectations = {
    'sendmail_package'   => 'sendmail',
    'sendmailcf_package' => 'sendmail-cf',
    'sendmail_service'   => 'sendmail'
  }

  # These cases merges in the OS specific expectations
  # The selection structure should be similar to what is used in the module
  case os['osfamily']
  when 'Debian'
    expectations.merge!( {
      'sendmail_ensure'  => 'purged',
      'package'          => 'postfix',
      'service'          => 'postfix',
      'config_file'      => '/etc/postfix/main.cf'
    } )
  when 'RedHat'
    expectations.merge!( {
      'sendmail_ensure'  => 'absent',
      'package'          => 'postfix',
      'service'          => 'postfix',
      'config_file'      => '/etc/postfix/main.cf'
    } )
  end

  # The expectations are then merged with the OS and passed back up to the map
  os.merge( { 'expectations' => expectations } )
end

Using an osmash library in tests

Operating system specific tests now take the form of iterating over the osmash library of supported operating systems (or the unsupported operating systems for extreme thoroughness). A complete example is given in Aethylred/puppet-postfix module, from which a partial implementation is shown below.

# spec_helper populates $osmash consistently for every script
require 'spec_helper'

describe 'postfix', :type => :class do
  $osmash.supported.each do |os|
    context "on #{os['name']}" do
      let :facts do
        {
          :osfamily => os['osfamily'],
        }
      end
      it { should contain_class('postfix::params') }
      it { should contain_package(os['expectations']['package']) }
      it { should contain_service(os['expectations']['service']) }

      describe 'with no parameters' do
        it { should_not contain_service(os['expectations']['sendmail_service']) }
        it { should_not contain_package(os['expectations']['sendmail_package']) }
        it { should_not contain_package(os['expectations']['sendmailcf_package']) }
      end

      describe 'when removing sendmail' do
        let :params do
          { :remove_sendmail => true }
        end
        it { should contain_service(os['expectations']['sendmail_service']).with_ensure('stopped') }
        it { should contain_package(os['expectations']['sendmail_package']).with_ensure(os['expectations']['sendmail_ensure']) }
        it { should contain_package(os['expectations']['sendmailcf_package']).with_ensure(os['expectations']['sendmail_ensure']) }
      end

      describe 'when leaving sendmail alone' do
        let :params do
          { :remove_sendmail => false }
        end
        it { should_not contain_service(os['expectations']['sendmail_service']) }
        it { should_not contain_package(os['expectations']['sendmail_package']) }
        it { should_not contain_package(os['expectations']['sendmailcf_package']) }
      end
    end
  end
  
  context 'on a Unkown OS' do
    let :facts do
      {
        :osfamily => 'Unknown',
      }
    end
    it { should raise_error(Puppet::Error,
      %r{The postfix module does not support the Unknown family of operating systems.}
    ) }
  end

end

Class rspec_puppet_osmash

This class is front-loaded so that the initialiser loads the module metadata and osmash library and processes all the results immediately. This should reduce access time for the resulting output and minimise recalculation.

Initialise

The initialiser takes two optional parameters:

osmash = Rspec_puppet_osmash.new(metadata_file_path,osmash_library_path)

metadata_file_path

Sets the path to the metadata.json file for the Puppet Module

osmash_library_path

Sets the path to a osmash library stored as a JSON file. A default osmash library is included and will be used if none is provided. This library contains a collection of operating systems with facts as expected from facter.

Accessors

The values returned by the access methods are determined when first initialised, and just pull the processed data via access methods.

rspec_puppet_osmash.all

Outputs the loaded osmash OS library as an array of hashes.

rspec_puppet_osmash.supported

Outputs an osmash library as array of hashes for all the operating systems from the loaded osmash library that are named as being supported in the metadata.json file for the Puppet module.

rspec_puppet_osmash.unsupported

Outputs an osmash library as array of hashes for all the operating systems from the loaded osmash OS library that are not named as being supported in the metadata.json file for the Puppet module.

rspec_puppet_osmash.known

Outputs the loaded osmash OS library as an array of hashes. (Note: This seems to replicate rspec_puppet_osmash.all it needs checking.)

rspec_puppet_osmash.unknown

Outputs the supported operating system metadata loaded from a module's metadata.json as a hash, but only those OSes that can not be found in the loaded osmash library. (WARNING: It's not reliably doing operating system by release yet.)

rspec_puppet_osmash.metadata

Outputs a hash of the metadata loaded from the metadata.json file for the Puppet module.

rspec_puppet_osmash.osmetadata

Outputs a hash of all the supported operating system metadata loaded from the metadata.json file for the Puppet module.

Writing an osmash library file

An osmash library file is an array of hashes stored in a JSON file. Each hash in the array represents a collection of facts about an operating system. There are a couple of examples provided in the source code:

Required key-value pairs

operatingsystem

This label is used explicitly by osmash to match each operating system. This label must match the operatingsystem lable given in the Puppet Module metadata in order for it to match. It should match the operatingsystem fact given by facter.

release

This label is used explicitly by osmash to match each operating system release. This label must match the operatingsystemrelease lable given in the Puppet Module metadata in order for it to match. However, the mapping to facter facts is dependent on which operating system is being evaluated.

releasetype

This is used to map the release key value to a facter fact. (NOTE: the default library might not be consistent with this. See issue [#1])

Recommended key-value pairs

codename

The codename is a name for the operating system release, e.g. the codename for Ubuntu 14.04 is Trusty Tahr

key

This is just a unique identifier for each OS, e.g. el4 for RedHat Enterprise Linux 4 or ubuntu1404 for Ubuntu 14.04. This can be used as a primary key for quickly referencing a specific operating system hash. (Note: There's no current check that key is actually unique.)

Generated key-value pairs

name

The name key-value pair is generated using the operatingsystem, codename, and release key value pairs when rspec_puppet_osmash is initialised, unless it has already been defined in the osmash library JSON file.

Licensing

This file is part of the rspec-puppet-osmash gem.

Licensed under the Apache License, Version 2.0