Kitchen Inspector
Kitchen Inspector is a CLI utility to check a cookbook's dependency status using a Chef server and a Repository Manager.
In particular, this tool checks whether the dependencies specified in a cookbook's metadata are up to date or not. It also shows whether one of the servers must be aligned.
By default, dependencies are recursively analyzed and transitive dependencies are shown indented.
It assumes that your kitchen is composed by:
- a Chef server containing the cookbooks to be used
- a Repository Manager hosting cookbook's development
Note: at this stage GitLab and GitHub are supported.
Installation
Install it from RubyGems.org with:
$ gem install kitchen-inspector
Or with Rake:
[kitchen-inspector_clone_dir]$ rake install
Repository Managers are loaded dynamically, so you should also install specific gems.
If you plan to use Kitchen Inspector with:
- GitHub:
gem install octokit
- GitLab:
gem install gitlab
Usage
A valid configuration must be provided in order to configure the Chef Server and the Repository Manager.
See Configuration for details.
From inside the cookbook's directory, type kitchen-inspector
to inspect your kitchen.
It's also possible to specify a target directory with kitchen-inspector inspect PATH
.
Cookbook's metadata.rb
is parsed to obtain the dependencies, then the configured Chef server and Repository Manager are queried to define which versions are available.
Note: The Chef server's version is the one that defines the used version.
When a usable version is not found, Repository Manager's latest tag is used to analyze transitive dependencies.
It will display a table that contains the following rows:
-
Name
- The name of the cookbook -
Requirement
- The version requirement specified in the metadata -
Used
- The final version used based on the requirement constraint -
Chef Latest
- The latest version available on the Chef server -
Repository Latest
- The latest version available on the Repository Manager -
Requirement Status
- The status of the cookbook:- up-to-date (a green tick mark): the right version is picked
- warning-req (a yellow esclamation point): a newer version could be used
- error (a red x mark): no versions could be found
-
Chef Server Status
- The status of the chef server:- up-to-date (a green tick mark): the server is up to date
- warning-chef (a blue 'i'): on the Repository Manager there's a newer version
- error (a red x mark): no versions could be found
-
Repository Status
- The status of the Repository Manager:- up-to-date (a green tick mark): the server is up to date
- warning-repomanager (two yellow esclamation points): on Chef there's a newer version
- error (a red x mark): no versions could be found
-
Remarks
- human readable descriptions of warnings/errors
The overall status will also be displayed in the bottom of the table.
Display Format
Two display formats are supported: table and json
- The table format will display the dependency status as an ASCII table
- The json format will display the dependency status as a JSON object
Examples
+------------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------------+-------------+-------+--------+------------+-------------+-------------+------------+
| apache2 | = 1.8.2 | 1.8.2 | 1.8.2 | 1.8.4 | ✔ | i | ✔ |
| mysql | = 1.1.2 | 1.1.2 | 1.1.3 | 1.1.4 | ! | i | ✔ |
| database | = 1.5.3 | 1.5.3 | 1.5.3 | 1.5.2 | ✔ | ✔ | !! |
| postgresql | = 3.1.0 | | 3.0.5 | 3.1.0 | ✖ | i | ✔ |
| activemq | = 1.1.0 | 1.1.0 | 1.1.1 | 1.1.1 | ! | ✔ | ✔ |
| yum | = 2.3.4 | 2.3.4 | 2.3.4 | 2.3.4 | ✔ | ✔ | ✔ |
| ssh-keys | = 1.0.0 | 1.0.0 | 1.0.0 | | ✔ | ✔ | ✖ |
| selinux | = 0.5.6 | 0.5.6 | 0.5.6 | 0.5.6 | ✔ | ✔ | ✔ |
| › keytool | ~> 1.0.0 | 1.0.1 | 1.0.1 | 1.0.1 | ✔ | ✔ | ✔ |
+------------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: err (✖)
Note: The option --remarks provides more verbose descriptions for errors/warnings
$ kitchen-inspector --remarks
+------------------+-------------+--------+--------+------------+-------------+-------------+------------+---------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository | Remarks |
| | | | Latest | Latest | Status | Status | Status | |
+------------------+-------------+--------+--------+------------+-------------+-------------+------------+---------+
| apache2 | = 1.8.2 | 1.8.2 | 1.8.2 | 1.8.2 | ✔ | ✔ | ! | 1 |
| mysql | = 1.1.3 | 1.1.3 | 1.1.3 | 1.1.4 | ✔ | i | ✔ | 2 |
| postgresql | = 3.0.5 | 3.0.5 | 3.0.5 | 3.0.5 | ✔ | ✔ | ! | 3 |
| build-essential | ~> 1.4.2 | 1.4.2 | 1.4.2 | 1.4.2 | ✔ | ✔ | ✔ | |
| database | >= 0.0.0 | 1.5.3 | 1.5.3 | 1.5.2 | ✔ | ✔ | !! | 4 |
+------------------+-------------+--------+--------+------------+-------------+-------------+------------+---------+
Status: warn-outofdate-repo (!!)
Remarks:
[1]: GitLab's last tag is 1.8.4 but found 1.8.2 in metadata.rb
[2]: A new version might appear on Chef server
[3]: GitLab's last tag is 3.1.0 but found 3.0.5 in metadata.rb
[4]: GitLab out-of-date!
Recursive dependencies
In order to turn off recursive analysis, simply use --recursive false.
Configuration
By default ${HOME}/.chef/kitchen_inspector.rb is picked, but --config can be used to override that setting.
Valid Repository Manager and Chef Server configurations must be provided.
When a Chef Server configuration is not specified in kitchen_inspector.rb it fallbacks to ${HOME}/.chef/knife.rb, if present.
$ kitchen-inspector --config config_example.rb
Chef server
Example:
# Chef Server configuration
chef_server :url => "https://chefsrv.example.org",
:username => "chef_usename",
:client_pem => "/path/to/chef_client_pem"
GitLab
GitLab access can be configured specifying a token and a base_url.
Example:
# Repository Manager configuration
repository_manager :type => "GitLab",
:base_url => "http://gitlab.example.org",
:token => "gitlab_token" # (GitLab > Profile > Account)
GitHub
GitHub access can be configured specifying a token and a list of allowed users that host the cookbooks you're interested in.
PLEASE NOTE that GitHub has a strict rate limit on the calls you can make.
So, even though a token is not strictly required, it's better to configure it as well.
From GitHub's Applications page go to "Personal Access Tokens" and generate a new token.
Due to the huge search space, searches against GitHub are restricted to profiles owned by allowed_users (aka GitHub usernames). Cookbooks are thus searched only within those users' repositories, comparing cookbooks' names with repositories' names (Pattern "one repo per cookbook").
Example:
# Repository Manager configuration
repository_manager :type => "GitHub",
:token => "github_token",
:allowed_users => ["opscode-cookbooks"]
CI/CD Integration
Kitchen Inspector can be used in a Continuous Integration/Continuous Building/etc process, in order to validate cookbooks.
These are the available exit codes (see common.rb):
- 0 (:up_to_date): everything is OK!
- Errors
- 100 (:err_req): a valid version could not be found
- 101 (:err_repo): an error related to the Repository Manager
- 102 (:err_config): configuration error
- 103 (:err_notacookbok): the specified directory is not a Cookbook
- Warnings
- 200 (:warn_req): a newer version could be used
- 201 (:warn_mismatch_repo): metadata.rb's version and tag doesn't match
- 202 (:warn_outofdate_repo): a newer version exists on Chef Server
- 203 (:warn_chef): a newer version exists on Repository Manager
Checks
In this section are listed the checks applied.
Everything is up to date
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | 1.0.1 | 1.0.1 | 1.0.1 | ✔ | ✔ | ✔ |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: up-to-date (✔)
Repository Manager doesn't contain any versions
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | 1.0.1 | 1.0.1 | | ✔ | ✔ | ✖ |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: err-repo (✖)
Repository Manager contains a mismatched tag/metadata's version
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | 1.0.1 | 1.0.1 | 1.0.0 | ✔ | ✔ | ! |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: warn-mismatch-repo (!)
Repository Manager doesn't contain the last version
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | 1.0.1 | 1.0.1 | 1.0.0 | ✔ | ✔ | !! |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: warn-outofdate-repo (!!)
Chef Server doesn't contain the last version
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | 1.0.0 | 1.0.0 | 1.0.1 | ✔ | i | ✔ |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: warn-chef (i)
#### Metadata doesn't use the last version
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
| Test | = 1.0.0 | 1.0.0 | 1.0.1 | 1.0.1 | ! | ✔ | ✔ |
+------+-------------+-------+--------+------------+-------------+-------------+------------+
Status: warn-req (!)
Metadata refers to a version not existing on Chef Server
+------+-------------+------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | | 1.1.0 | 1.1.0 | ✖ | ✔ | ✔ |
+------+-------------+------+--------+------------+-------------+-------------+------------+
Status: err (✖)
Chef Server doesn't contain any versions
+------+-------------+------+--------+------------+-------------+-------------+------------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository |
| | | | Latest | Latest | Status | Status | Status |
+------+-------------+------+--------+------------+-------------+-------------+------------+
| Test | ~> 1.0.0 | | | 1.0.1 | ✖ | ✖ | ✔ |
+------+-------------+------+--------+------------+-------------+-------------+------------+
Status: err (✖)
Repository Manager contains two or more projects with the same name
Note: In this situation is not possible to decide which version generated the one on the Chef Server.
+----------+-------------+-------+--------+------------+-------------+-------------+------------+---------+
| Name | Requirement | Used | Chef | Repository | Requirement | Chef Server | Repository | Remarks |
| | | | Latest | Latest | Status | Status | Status | |
+----------+-------------+-------+--------+------------+-------------+-------------+------------+---------+
| database | >= 0.0.0 | 1.5.2 | 1.5.2 | 1.5.2 | ✔ | ✔ | ? | 1 |
| database | >= 0.0.0 | 1.5.2 | 1.5.2 | 1.1.0 | ✔ | ✔ | ? | 2 |
+----------+-------------+-------+--------+------------+-------------+-------------+------------+---------+
Status: warn-notunique-repo (?)
Remarks:
[1]: Not unique on GitHub (this is github.com/opscode-cookbooks/database)
[2]: Not unique on GitHub (this is github.com/cookbooks/database)
Testing
Kitchen Inspector is tested using RSpec. You can run tests using:
$ rake test
LICENSE
Author:: Stefano Tortarolo (stefano.tortarolo@gmail.com)
Copyright:: Copyright (c) 2013-2014 License:: MIT License
CREDITS
This code was heavily inspired by Kannan Manickam's chef-taste
Special thanks to Marco Boschetti for the huge amount of suggestions given.