Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Add Doctor Checks to Driver and Verifier (#494)
Browse files Browse the repository at this point in the history
* Fix README links

* Add driver doctor

* Check for empty systems with doctor

* Fix references to Test Kitchen

* Add note about familiarity with Test Kitchen

* Add note about `kitchen doctor` command

* Ensure doctor checks driver and verifier

* Clarify doctor output

* Add kitchen doctor acceptance test

* Add doctor to changelog

---------

Co-authored-by: Aaron Lane <2400330-aaron-lane@users.noreply.gitlab.com>
  • Loading branch information
aaron-lane and Aaron Lane authored Feb 2, 2023
1 parent 463ec19 commit 694e621
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 28 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,21 @@ jobs:
run: |
chmod 400 ./test/terraform/$VERSION_MATCHER/backend-ssh/id_ed25519
rake test:kitchen:backend-ssh-ubuntu
- name: Run Kitchen doctor
run: |
status=0
output="$(kitchen doctor doctor)"
if [[ $output != *"${{ matrix.operating-system }}.driver.client"* ]]
then
echo "kitchen doctor did not detect driver.client error"
status=1
fi
if [[ $output != *"${{ matrix.operating-system }}.verifier.systems"* ]]
then
echo "kitchen doctor did not detect verifier.systems error"
status=1
fi
exit $status
release:
name: "Release"
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to
### Added

- Support for Inspec < 6.0
- Support for `kitchen doctor` command: initially validates driver.client and verifier.systems

### Changed

Expand Down
52 changes: 26 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# ![Kitchen-Terraform Logo][kitchen-terraform-logo] Kitchen-Terraform

> Kitchen-Terraform enables verification of infrastructure systems provisioned with Terraform.
Expand All @@ -7,17 +6,16 @@
[![Gem downloads version][gem-downloads-version-shield]][kitchen-terraform-gem]
[![Gem downloads total][gem-downloads-total-shield]][kitchen-terraform-gem]

[![Kitchen tests workflow][kitchen-tests-workflow-shield]][kitchen-tests-workflow]
[![RSpec tests workflow][rspec-tests-workflow-shield]][rspec-tests-workflow]
[![Delivery][delivery-shield]][delivery-workflow]
[![Pages Build and Deployment][pages-build-deployment-shield]][pages-build-deployment-workflow]
[![Code coverage][code-coverage-shield]][code-coverage]
[![Maintainability][maintainability-shield]][maintainability]
[![Technical debt][technical-debt-shield]][technical-debt]
[![Dependencies][hakiri-shield]][hakiri]

[![Gitter chat][gitter-shield]][gitter]

Kitchen-Terraform provides a set of [Kitchen][kitchen] plugins
which enable the use of Kitchen to converge a [Terraform][terraform]
Kitchen-Terraform provides a set of [Test Kitchen][test-kitchen] plugins
which enable the use of Test Kitchen to converge a [Terraform][terraform]
configuration and verify the resulting infrastructure systems with
[InSpec][inspec] controls.

Expand Down Expand Up @@ -75,21 +73,25 @@ the semantic versioning of the Ruby gem.
> Defining Kitchen-Terraform as a dependency for Bundler in a Gemfile
---

```ruby
source "https://rubygems.org/" do
gem "kitchen-terraform", "~> 6.1"
end
```

---

Second, run the following command.

> Installing Kitchen-Terraform with Bundler
---

```sh
bundle install
```

---

The preceding command will create a `Gemfile.lock` comprising a list
Expand All @@ -107,9 +109,11 @@ example.
> Installing Kitchen-Terraform with RubyGems
---

```sh
gem install kitchen-terraform --version 6.1.0
```

---

This approach is not recommended as it requires more effort to install
Expand All @@ -131,11 +135,13 @@ Ed25519-type SSH keys.

## Usage

A familiarity with [Test Kitchen][test-kitchen] workflows and commands is required to use Kitchen-Terraform.

### Configuration

Kitchen-Terraform provides three Test Kitchen plugins which must be
configured in a
[Kitchen configuration file][kitchen-configuration-file] in
[Test Kitchen configuration file][kitchen-configuration-file] in
order to successfully test Terraform configuration.

The [Terraform driver][terraform-driver] manages the state of the
Expand All @@ -150,6 +156,9 @@ Terraform state.
More information can be found in the
[Ruby gem documentation][ruby-gem-documentation].

The `kitchen doctor` command can be used to validate the system and the
configuration file.

### Caveats

Versions of Terraform in the 0.11 series may cause `kitchen test` to
Expand All @@ -166,7 +175,7 @@ Several tutorials are available on the

The integration tests for Kitchen-Terraform can also be viewed as
examples of how it works. The
[integration test Kitchen configuration file][int-kitchen-config]
[integration test Test Kitchen configuration file][int-kitchen-config]
and the [integration test directory][test-directory] provide several
functional examples which exercise various features of
Kitchen-Terraform.
Expand Down Expand Up @@ -233,47 +242,37 @@ Kitchen-Terraform is distributed under the [Apache License][license].

<!-- Markdown links and image definitions -->

[appveyor-build-status-shield]: https://ci.appveyor.com/api/projects/status/8d7t014gij5grk5r/branch/master?svg=true
[appveyor-build-status]: https://ci.appveyor.com/project/aaron-lane/kitchen-terraform/branch/master
[bundler-getting-started]: https://bundler.io/#getting-started
[bundler-in-depth]: https://bundler.io/gemfile.html
[bundler]: https://bundler.io/index.html#getting-started
[changelog]: https://github.com/newcontext-oss/kitchen-terraform/blob/master/CHANGELOG.md
[code-coverage-shield]: https://img.shields.io/codeclimate/coverage/newcontext-oss/kitchen-terraform.svg
[code-coverage]: https://codeclimate.com/github/newcontext-oss/kitchen-terraform/
[contributing-document]: https://github.com/newcontext-oss/kitchen-terraform/blob/master/CONTRIBUTING.md
[contributors]: https://github.com/newcontext-oss/kitchen-terraform/graphs/contributors
[docker]: https://www.docker.com/
[docker-community-edition]: https://store.docker.com/editions/community/docker-ce-server-ubuntu
[docker-provider]: https://www.terraform.io/docs/providers/docker/index.html
[copado-github]: https://github.com/CopadoSolutions
[copado-linkedin]: https://www.linkedin.com/company/copado-solutions-s.l
[copado-twitter]: https://twitter.com/CopadoSolutions
[copado]: https://copado.com/
[delivery-shield]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/delivery.yml/badge.svg
[delivery-workflow]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/delivery.yml
[gem-downloads-total-shield]: https://img.shields.io/gem/dt/kitchen-terraform.svg
[gem-downloads-version-shield]: https://img.shields.io/gem/dtv/kitchen-terraform.svg
[gem-version-shield]: https://img.shields.io/gem/v/kitchen-terraform.svg
[gitter-shield]: https://img.shields.io/gitter/room/kitchen-terraform/Lobby.svg
[gitter]: https://gitter.im/kitchen-terraform/Lobby
[hakiri-shield]: https://hakiri.io/github/newcontext-oss/kitchen-terraform/master.svg
[hakiri]: https://hakiri.io/github/newcontext-oss/kitchen-terraform/
[inspec]: https://www.inspec.io/
[int-kitchen-config]: https://github.com/newcontext-oss/kitchen-terraform/blob/master/kitchen.yml
[issue-271]: https://github.com/newcontext-oss/kitchen-terraform/issues/271
[kitchen]: http://kitchen.ci/index.html
[kitchen-configuration-file]: https://docs.chef.io/config_yml_kitchen.html
[kitchen-terraform-gem]: https://rubygems.org/gems/kitchen-terraform
[kitchen-terraform-logo]: https://raw.githubusercontent.com/newcontext-oss/kitchen-terraform/master/assets/logo.png
[kitchen-terraform-tutorials]: https://newcontext-oss.github.io/kitchen-terraform/tutorials/
[kitchen-tests-workflow]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/kitchen-tests.yml
[kitchen-tests-workflow-shield]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/kitchen-tests.yml/badge.svg
[license]: https://github.com/newcontext-oss/kitchen-terraform/blob/master/LICENSE
[maintainability-shield]: https://img.shields.io/codeclimate/maintainability-percentage/newcontext-oss/kitchen-terraform.svg
[maintainability]: https://codeclimate.com/github/newcontext-oss/kitchen-terraform/
[copado-github]: https://github.com/CopadoSolutions
[copado-linkedin]: https://www.linkedin.com/company/copado-solutions-s.l
[copado-twitter]: https://twitter.com/CopadoSolutions
[copado]: https://copado.com/
[pages-build-deployment-shield]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/pages/pages-build-deployment/badge.svg
[pages-build-deployment-workflow]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/pages/pages-build-deployment
[rbenv]: https://github.com/rbenv/rbenv
[rbnacl-installation]: https://github.com/crypto-rb/rbnacl/tree/v4.0.2#installation
[rspec-tests-workflow]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/rspec-tests.yml
[rspec-tests-workflow-shield]: https://github.com/newcontext-oss/kitchen-terraform/actions/workflows/rspec-tests.yml/badge.svg
[ruby-branches]: https://www.ruby-lang.org/en/downloads/branches/
[ruby-gem-documentation]: http://www.rubydoc.info/github/newcontext-oss/kitchen-terraform/
[ruby-gems-what-is]: http://guides.rubygems.org/ruby-gems-what-is/index.html
Expand All @@ -289,4 +288,5 @@ Kitchen-Terraform is distributed under the [Apache License][license].
[terraform-verifier]: http://www.rubydoc.info/github/newcontext-oss/kitchen-terraform/Kitchen/Verifier/Terraform
[terraform]: https://www.terraform.io/
[test-directory]: https://github.com/newcontext-oss/kitchen-terraform/tree/master/test
[test-kitchen]: http://kitchen.ci/
[tfenv]: https://github.com/kamatama41/tfenv
5 changes: 5 additions & 0 deletions kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ suites:
shell_command: /bin/sh
shell_options: -x
user: root
- name: doctor
driver:
client: /nonexistent/pathname
verifier:
systems: []
- name: plug-ins
driver:
plugin_directory: test/terraform/PlugIns/PlugInDirectory
Expand Down
15 changes: 15 additions & 0 deletions lib/kitchen/driver/terraform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
require "kitchen/terraform/configurable"
require "kitchen/terraform/driver/create"
require "kitchen/terraform/driver/destroy"
require "kitchen/terraform/driver/doctor"
require "kitchen/terraform/version_verifier"
require "rubygems"
require "shellwords"
Expand Down Expand Up @@ -191,6 +192,20 @@ def destroy(_state)
action_failed.call message: error.message
end

# doctor checks the system and configuration for common errors.
#
# @param state [Hash] the mutable Kitchen instance state.
# @return [Boolean] +true+ if any errors are found; +false+ if no errors are found.
def doctor(state)
driver_errors = ::Kitchen::Terraform::Driver::Doctor.new(
instance_name: instance.name,
logger: logger
).call config: config
verifier_errors = instance.verifier.doctor state

driver_errors or verifier_errors
end

# #finalize_config! invokes the super implementation and then initializes the strategies.
#
# @param instance [Kitchen::Instance] an associated instance.
Expand Down
59 changes: 59 additions & 0 deletions lib/kitchen/terraform/driver/doctor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

# Copyright 2016-2021 Copado NCS LLC
#
# 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.

module Kitchen
module Terraform
module Driver
# Doctor checks for driver configuration errors.
class Doctor
# #call executes the action.
#
# @param config [Hash] the configuration of the driver.
# @return [Boolean] +true+ if any errors are found; +false+ if no errors are found.
def call(config:)
errors = false
client = config.fetch :client

if !::File.exist? client
errors = true
logger.error "#{instance_name}.driver.client '#{client}' does not exist"
end
if !::File.executable? client
errors = true
logger.error "#{instance_name}.driver.client '#{client}' is not executable"
end

errors
end

# #initialize prepares a new instance of the class.
#
# @param instance_name [String] the name of the Kitchen instance.
# @param logger [Kitchen::Logger] a logger for logging messages.
# @option config [String] :client the pathname of the Terraform client.
# @return [Kitchen::Terraform::Driver::Doctor]
def initialize(instance_name:, logger:)
self.instance_name = instance_name
self.logger = logger
end

private

attr_accessor :logger, :instance_name
end
end
end
end
55 changes: 55 additions & 0 deletions lib/kitchen/terraform/verifier/doctor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

# Copyright 2016-2021 Copado NCS LLC
#
# 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.

module Kitchen
module Terraform
module Verifier
# Doctor checks for verifier configuration errors.
class Doctor
# #call executes the action.
#
# @param config [Hash] the configuration of the verifier.
# @return [Boolean] +true+ if any errors are found; +false+ if no errors are found.
def call(config:)
errors = false
systems = config.fetch :systems

if systems.empty?
errors = true
logger.error "#{instance_name}.verifier.systems is empty"
end

errors
end

# #initialize prepares a new instance of the class.
#
# @param instance_name [String] the name of the Kitchen instance.
# @param logger [Kitchen::Logger] a logger for logging messages.
# @option config [String] :client the pathname of the Terraform client.
# @return [Kitchen::Terraform::Verifier::Doctor]
def initialize(instance_name:, logger:)
self.instance_name = instance_name
self.logger = logger
end

private

attr_accessor :logger, :instance_name
end
end
end
end
4 changes: 2 additions & 2 deletions lib/kitchen/verifier/terraform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
require "kitchen/terraform/systems_verifier_factory"
require "kitchen/terraform/outputs_manager"
require "kitchen/terraform/variables_manager"
require "kitchen/terraform/verifier/doctor"

module Kitchen
# This namespace is defined by Kitchen.
Expand Down Expand Up @@ -118,9 +119,8 @@ def call(state)
#
# @param _state [Hash] the mutable Kitchen instance state.
# @return [Boolean] +true+ if any errors are found; +false+ if no errors are found.
# @see https://github.com/test-kitchen/test-kitchen/blob/v1.21.2/lib/kitchen/verifier/base.rb#L85-L91
def doctor(_state)
false
::Kitchen::Terraform::Verifier::Doctor.new(instance_name: instance.name, logger: logger).call config: config
end

# #initialize prepares a new instance of the class.
Expand Down
14 changes: 14 additions & 0 deletions spec/lib/kitchen/driver/terraform_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,18 @@
end
end
end

describe "#doctor" do
let :kitchen_instance_state do
{}
end

before do
subject.finalize_config! kitchen_instance
end

specify "should return true" do
expect(subject.doctor(kitchen_instance_state)).to be_truthy
end
end
end
Loading

0 comments on commit 694e621

Please sign in to comment.