Adoptable Cookbooks List

Looking for a cookbook to adopt? You can now see a list of cookbooks available for adoption!
List of Adoptable Cookbooks

Supermarket Belongs to the Community

Supermarket belongs to the community. While Chef has the responsibility to keep it running and be stewards of its functionality, what it does and how it works is driven by the community. The chef/supermarket repository will continue to be where development of the Supermarket application takes place. Come be part of shaping the direction of Supermarket by opening issues and pull requests or by joining us on the Chef Mailing List.

Select Badges

Select Supported Platforms

RSS

chef_vault_testfixtures (2) Versions 0.1.1

Sets up testing fixtures for cookbooks using chef-vault

Berkshelf/Librarian
Policyfile
Knife
cookbook 'chef_vault_testfixtures', '= 0.1.1'
cookbook 'chef_vault_testfixtures', '= 0.1.1', :supermarket
knife cookbook site install chef_vault_testfixtures
knife cookbook site download chef_vault_testfixtures
README
Dependencies
Changelog
Quality 0%

chef_vault_testfixtures

Description

chef_vault_testfixtures is a testing-only cookbook that works with the chef-vault-testfixtures gem to make integration testing of a cookbook that uses chef-vault easier.

The gem provides an RSpec shared context to give you automagical stubs for your unit tests. You create plugins with valid sample data for the vaults you use in your cookbook, and when your cookbook requests data from the vault the stub provides the sample data instead.

When integration testing a cookbook with Test Kitchen, you can't use stubs, so this cookbook creates real encrypted vaults using the same sample data. The secrets are encrypted during the compile phase, using the public key of the dynamically created node under test.

If you've ever had to create pre-encrypted secrets in test/integration/data_bags/vaultname/itemname.json along with a private key in test/integration/clients/username.pem, or twisted your setup to fall back to an unencrypted data bag only when running under test, then this cookbook is for you.

Usage

THIS COOKBOOK SHOULD NEVER BE IN A NODE'S RUN LIST!

THIS COOKBOOK SHOULD NEVER BE REFERENCED AS A DEPENDENCY IN metadata.rb!

The chef_vault_testfixtures cookbook only belongs in the run-list of node under test with Test Kitchen. For the remainder of this document, we assume you are using Berkshelf for cookbook dependency management.

In your Berksfile, add a snippet that pulls this cookbook into a test group:

group :test do
  cookbook 'chef_vault_testfixtures', '~> 0.2'
end

In your .kitchen.yml, add this cookbook to the run list for each suite and which fixture data plugins to install:

suites:
  - name: default
    run_list:
      - recipe[chef_vault_testfixtures]
      - recipe[your_normal_cookbook_here]
    attributes:
      chef_vault_testfixtures:
        install_gems:
          chef-vault-testfixtures-myapp:
            install_type: git
            repository: https://github.com/myusername/chef-vault-testfixtures-myapp.git

When Test Kitchen converges your cookbook, it will create a new client identity (including a public/private keypair). This cookbook will then create a vaultitem for each plugin that it finds.

Recipes

default

The default recipe uses the chef_vault_testfixtures LWRP to create a vault item for every plugin installed on the test box.

It installs any plugin gems described by the attributes, then iterates over all vault plugins it can find. Each plugin represents a vault, and each public method in the plugin is a vault item.

Attributes

The attributes defined by this recipe are organized under the node['chef_vault_testfixtures'] namespace.

Attribute Description Type Default
plugins List of plugins to load Array
disregard_plugin List of plugins to not load Array []
install_gems Hash of plugin gems to install Hash see below
gem_version constrain chef-vault-testfixtures gem version String ~> 0.2

Specifying Plugins

chef-vault-testfixtures relies on plugins containing sample data being installed. You provide a list of these by overriding attributes in this cookbook in .kitchen.yml:

suites:
  - name: default
    run_list:
      - recipe[chef_vault_testfixtures]
      - recipe[your_normal_cookbook_here]
    attributes:
      chef_vault_testfixtures:
        install_gems:
          chef-vault-testfixtures-db: {}
          chef-vault-testfixtures-rmq:
            install_type: git
            repository: https://github.com/myusername/chef-vault-testfixtures-rmq.git
            revision: my_fix_branch

The install_gems attribute is a hash. The keys are the names of the vault plugins to install and the values tell the cookbook how to install the plugin.

Note that the name of the vault plugin in .kitchen.yml must match the name of the gem (on Rubygems or in the gemspec in a git repo).

The value is a Hash that can contain the following keys:

  • install_type: 'chef_gem' or 'git'; if not given defaults to 'chef_gem'
  • version: used by the 'chef_gem' install type to restrict the version of the gem to install
  • options: used by the 'chef_gem' install type to change how the gem is installed
  • repository: used by the 'git' install type to point to the repo to clone the gem from
  • revision: used by the 'git' install type to checkout a specific branch or tag before building the gem

Because the install type defaults to 'chef_gem', if you are installing a plugin from Rubygems, you can pass an empty hash, as in the my_vault_plugin_db example above.

chef_gem installation method

The install type chef_gem installs a plugin using the chef_gem resource.

You can also provide keys named version, source and options to pass those to the underlying chef_gem resource, which allows you to do things like use an internal Geminabox server:

attributes:
  chef_vault_testfixtures:
    install_gems:
      chef-vault-testfixtures-db:
        options: --clear-sources --no-rdoc --no-ri --source https://gems.mycompany.int

git installation method

For the installation type git, the value is a Hash with two keys: repository and revision, which tell the cookbook where to clone the gem from and what reference to check out before building and installing the gem. This can be used to use a forked copy of a plugin gem:

attributes:
  chef_vault_testfixtures:
    install_gems:
      db:
        install_type: git
        repository: https://github.com/otheruser/my_chef_vault_rmq_plugin.git
        revision: fix_for_something_or_other

Whitelisting and Disregarding Plugins

If desired, you can whitelist and disregard plugins in the same fashion as described in the gem documentation by overriding the plugins and disregard_plugins attributes:

suites:
  - name: default
    run_list:
      - recipe[chef_vault_testfixtures]
      - recipe[your_normal_cookbook_here]
    attributes:
      chef_vault_testfixtures:
        plugins: [ db ]
        disregard_plugin: [ rmq ]

Though in practice this is unnecessary because the only plugins that will be available inside of the Test Kitchen box will be the ones you reference using install_gems.

You may find these useful If you use a Vagrant image or AMI that has your secret plugin gems 'baked' into the embedded chef-client ruby.

Uploading your cookbook using berks upload

If you use berks upload to upload your cookbook to your Chef server, you should add a switch to exclude the test cookbooks:

berks upload --except test

If you don't do this, this cookbook will be uploaded, which shouldn't be a problem (because it's not in the run list of any nodes), but it adds clutter to your server.

Resources

If you prefer, you can use the resources directly rather than using the default recipe.

Because this requires a recipe context that comes before the cookbook you're testing, this requires that you write a 'fixture cookbook' that appears in the run list in .kitchen.yml before the cookbook under test.

chef_vault_testfixture_plugin

Installs a plugin gem that provides data for the chef-vault-testfixtures gem to use.

Example

# default install type is 'chef_gem'
c = chef_vault_testfixture_plugin 'my_vault_fixture_plugin' do
  action :nothing
  version '1.2.3'
  options '--no-rdoc --no-ri --clear-sources --source https://gems.mycompany.int'
end
c.run_action(:install)

# using the 'git' install type
chef_vault_testfixture_plugin 'my_vault_fixture_plugin' do
  action :nothing
  install_type 'git'
  repository 'https://git.mycompany.int/scm/gems/my_vault_fixture_plugin.git'
  revision 'v1.2.3'
end
c.run_action(:install)

Parameters

  • gem_name: the gem to install. Defaults to the name of the resource.
  • action: the only (and thus default) action for this resource is :install
  • install_type: 'chef_gem' (which uses the like-named chef resource) or 'git'. Defaults to 'git'
  • version: the version of the gem to install. If not set, the gem command will choose the newest version available. Only used for 'chef_gem' install type.
  • options: options to pass to the gem command. Only used for the 'chef_gem' install type.
  • source: the local path of a gem to install. Only used for the 'chef_gem' install type.
  • repository: the git URL to clone the gem from. Only used for the 'git' install type.
  • revision: the git reference to checkout before building the gem from source. Only used for the 'git' install type.

chef_vault_testfixtures

Creates a vault item for all chef-vault-testfixtures plugins that can be found chef-vault-testfixtures gem. It does this by dynamically creating chef_vault_testfixture_vault resources (see below)

Example

c = chef_vault_testfixtures 'all' do
  action :nothing
  plugins %w(foo)
  disregard_plugins %w(bar)
end
c.run_action(:create)

Parameters

  • name: you can provide any name (this is required by chef)
  • action: the only (and thus default) action for this resource is :create
  • plugins: an array of plugins to load. By default, this is empty, which means 'load all plugins matching ChefVault::TestFixtures::. If set, only the named plugins will be used.
  • disregard_plugins: an array of plugins to not load. This prevents certain plugins from being loaded when the plugins attribute is empty.

chef_vault_testfixture_vault

Creates a single vault item using fixture data from the named plugin.

This is generally not used directly; it is the workhorse for the chef_vault_testfixtures resource.

Example

c = chef_vault_testfixture_vault 'db'
  action :nothing
end
c.run_action(:create)

Parameters

  • plugin: the test fixture plugin name. Defaults to the name of the resource.
  • action: the only action for this resource is :create

Compile-Time Resources

When you set up a vault for production use, you typically do so by hand as an administrator before the recipe is converged on the server. Because the vault exists, you can make calls to ChefVault::Item.load at compile time rather than converge time.

Because of this expectation on the part of cookbook authors, this cookbook has to run its resources at compile time as well - otherwise the cookbook under test might try to call ChefVault::Item.load before we had created the vault item.

If you use the resources directly instead of via the default recipe, you should ensure that they run at compile time as shown in the examples, unless you are certain that your cookbook under test never attempts to call ChefVault::Item.load from a recipe. Calling it from provider or library code should be fine.

Errors when Converging Twice

When Test Kitchen first converges a node, it runs chef-client with a validator key. This causes chef-client to create a new client identity and create a client.pem file as well as node and client objects in /tmp/kitchen.

On a second converge, the node and client should again be available, but Test Kitchen blows away the clients directory in /tmp/kitchen. Because the client.pem file is retained, chef-client does not re-create the client object containing the public key for the node.

When chef-vault attempts to load the public key for the node, it fails, preventing this cookbook from re-creating the testing vault. This manifests as this error on the second converge:

ChefVault::Exceptions::ClientNotFound
-------------------------------------
default-ubuntu-1404 is not a valid chef client and/or node

This problem is explained in detail here. Until the underlying issue is resolved, you must run the following command before performing a second converge:

kitchen exec -c 'sudo rm -rf /tmp/kitchen'

This removes the entire Test Kitchen chef repo directory, forcing the process to start over and create a new node, client, and keypair.

Supported Platforms

This cookbook is tested under Test Kitchen for the following platforms and chef-client combinations:

  • ubuntu-12.04
    • chef-client 11.10.4
    • chef-client 11.12.8
    • chef-client 11.14.6
    • chef-client 11.16.4
    • chef-client 11.18.6
    • chef-client latest
  • ubuntu-14.04
    • chef-client latest
  • centos-6.6
    • chef-client 11.10.4
    • chef-client 11.12.8
    • chef-client 11.14.6
    • chef-client 11.16.4
    • chef-client 11.18.6
    • chef-client latest
  • centos-7.0
    • chef-client latest

Author

James FitzGibbon - james.i.fitzgibbon@nordstrom.com - @jf647

License

Copyright (c) 2015 Nordstrom, Inc., All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Dependent cookbooks

This cookbook has no specified dependencies.

Contingent cookbooks

There are no cookbooks that are contingent upon this one.

Revision History for chef_vault_testfixtures cookbook

0.1.1

  • ensure that the chef-vault-testfixtures gem is installed in the provider code before it is required
  • use --conservative when installing chef-vault-testfixtures gem so as not to kick off an upgrade of chef
  • expand test kitchen platforms to include chef-clients back to 11.10.x

0.1.0

  • initial version

Foodcritic Metric
            

0.1.1 failed this metric

FC031: Cookbook without metadata file: /tmp/cook/03da54fdf5765bdfa3edaa43/chef_vault_testfixtures/metadata.rb:1
FC045: Consider setting cookbook name in metadata: /tmp/cook/03da54fdf5765bdfa3edaa43/chef_vault_testfixtures/metadata.rb:1