Skip to content

Commit

Permalink
v4.6.0: add fail_fast attribute to verifier (#331)
Browse files Browse the repository at this point in the history
* Add fail_fast config attr to verifier

* Queue errors if fail fast is disabled

* Disable fail fast behaviour in integration tests

* Add Changelog entry

* Add link to 4.6.0

* Update version to 4.6.0

* Refactor system design

* Refactor #verify

* Update release date
  • Loading branch information
aaron-lane authored Apr 11, 2019
1 parent 4b4c8e3 commit 36b8392
Show file tree
Hide file tree
Showing 17 changed files with 281 additions and 88 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased][unreleased]

## [4.6.0] - 2019-04-11

### Added

- The verifier gained a `fail_fast` attribute which toggles fail fast
behaviour when verifying systems; refer to the updated
[Terraform Verifier documentation][terraform-verifier] for more details.

## [4.5.0] - 2019-04-10

### Changed
Expand Down Expand Up @@ -618,7 +626,8 @@ Gandalf the Free-As-In-Beer

- Initial release

[unreleased]: https://github.com/newcontext/kitchen-terraform/compare/v4.5.0...HEAD
[unreleased]: https://github.com/newcontext/kitchen-terraform/compare/v4.6.0...HEAD
[4.6.0]: https://github.com/newcontext/kitchen-terraform/compare/v4.5.0...v4.6.0
[4.5.0]: https://github.com/newcontext/kitchen-terraform/compare/v4.4.0...v4.5.0
[4.4.0]: https://github.com/newcontext/kitchen-terraform/compare/v4.3.0...v4.4.0
[4.3.0]: https://github.com/newcontext/kitchen-terraform/compare/v4.2.1...v4.3.0
Expand Down
1 change: 1 addition & 0 deletions kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ provisioner:
name: terraform
verifier:
name: terraform
fail_fast: false
platforms:
- name: linux
- name: osx
Expand Down
38 changes: 38 additions & 0 deletions lib/kitchen/terraform/config_attribute/fail_fast.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

# Copyright 2016 New Context Services, Inc.
#
# 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.

require "kitchen"
require "kitchen/terraform/config_attribute"
require "kitchen/terraform/config_schemas/boolean"

# This attribute toggles fail fast behaviour when verifying systems.
#
# If fail fast behaviour is enabled then Kitchen will halt on the first error raised by a system during verification;
# else errors raised by systems will be queued until all systems have attempted verification.
#
# Type:: {http://www.yaml.org/spec/1.2/spec.html#id2803629 Boolean}
# Required:: False
# Default:: <code>true</code>
# Example:: <code>fail_fast: false</code>
module ::Kitchen::Terraform::ConfigAttribute::FailFast
::Kitchen::Terraform::ConfigAttribute.new(
attribute: :fail_fast,
default_value: lambda do
true
end,
schema: ::Kitchen::Terraform::ConfigSchemas::Boolean,
).apply config_attribute: self
end
1 change: 1 addition & 0 deletions lib/kitchen/terraform/inspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def logger=(logger)

# #exec executes InSpec.
#
# @raise [::Kitchen::Terraform::Error] if executing InSpec fails.
# @return [self]
def exec
@runner.run.tap do |exit_code|
Expand Down
88 changes: 54 additions & 34 deletions lib/kitchen/terraform/system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

require "kitchen/terraform/error"
require "kitchen/terraform/inspec_with_hosts"
require "kitchen/terraform/inspec_without_hosts"
require "kitchen/terraform/system_attrs_resolver"
require "kitchen/terraform/system_hosts_resolver"

module Kitchen
module Terraform
Expand Down Expand Up @@ -53,32 +56,6 @@ def each_host
self
end

# #resolve_attrs resolves the attributes of the system which are contained in Terraform outputs.
#
# @param system_attrs_resolver [::Kitchen::Terraform::SystemAttrsResolver] the resolver.
# @return [self]
def resolve_attrs(system_attrs_resolver:)
system_attrs_resolver.resolve attrs_outputs_keys: @attrs_outputs.keys,
attrs_outputs_values: @attrs_outputs.values, system: self

self
end

# #resolve_hosts resolves the hosts of the system which are contained a Terraform output.
#
# @param system_hosts_resolver [::Kitchen::Terraform::SystemHostsResolver] the resolver.
# @return [self]
def resolve_hosts(system_hosts_resolver:)
system_hosts_resolver.resolve(
hosts_output: @mapping.fetch(:hosts_output) do
return self
end,
system: self,
)

self
end

# #to_s returns a string representation of the system.
#
# @return [::String] the name of the system.
Expand All @@ -91,20 +68,23 @@ def to_s
# @param inspec_options [::Hash] the options to be passed to InSpec.
# @param inspec_profile_path [::String] the path to the profile which InSpec will execute.
# @return [self]
def verify(inspec_options:, inspec_profile_path:)
if @hosts.empty?
::Kitchen::Terraform::InSpecWithoutHosts
else
::Kitchen::Terraform::InSpecWithHosts
end
.new(options: inspec_options.merge(attributes: @attributes), profile_path: inspec_profile_path)
.exec(system: self)
def verify(inspec_options:, inspec_profile_path:, outputs:)
resolve outputs: outputs
execute_inspec options: inspec_options, profile_path: inspec_profile_path

self
rescue => error
raise ::Kitchen::Terraform::Error, "#{self}: #{error.message}"
end

private

def execute_inspec(options:, profile_path:)
inspec.new(options: options_with_attributes(options: options), profile_path: profile_path).exec(
system: self
)
end

def initialize(mapping:)
@attributes = {}
@attrs_outputs = mapping.fetch :attrs_outputs do
Expand All @@ -115,6 +95,46 @@ def initialize(mapping:)
end
@mapping = mapping
end

def inspec
if @hosts.empty?
::Kitchen::Terraform::InSpecWithoutHosts
else
::Kitchen::Terraform::InSpecWithHosts
end
end

def options_with_attributes(options:)
options.merge attributes: @attributes
end

def resolve(outputs:)
resolve_attrs outputs: outputs
resolve_hosts outputs: outputs
end

def resolve_attrs(outputs:)
::Kitchen::Terraform::SystemAttrsResolver.new(outputs: outputs).resolve(
attrs_outputs_keys: @attrs_outputs.keys,
attrs_outputs_values: @attrs_outputs.values,
system: self
)

self
end

def resolve_hosts(outputs:)
if !@mapping.key? :hosts_output
return self
end

::Kitchen::Terraform::SystemHostsResolver.new(outputs: outputs).resolve(
hosts_output: @mapping.fetch(:hosts_output),
system: self,
)

self
end
end
end
end
3 changes: 1 addition & 2 deletions lib/kitchen/terraform/system_attrs_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ def resolve(attrs_outputs_keys:, attrs_outputs_values:, system:)

self
rescue ::KeyError => key_error
raise ::Kitchen::Terraform::Error,
"Resolving the attrs of system #{system} failed\n#{key_error}"
raise ::Kitchen::Terraform::Error, "Resolving attrs failed\n#{key_error}"
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/kitchen/terraform/system_hosts_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class SystemHostsResolver
def resolve(hosts_output:, system:)
system.add_hosts hosts: @outputs.fetch(hosts_output).fetch("value")
rescue ::KeyError => key_error
raise ::Kitchen::Terraform::Error, "Resolving the hosts of system #{system} failed\n#{key_error}"
raise ::Kitchen::Terraform::Error, "Resolving hosts failed\n#{key_error}"
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/kitchen/terraform/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def temporarily_override(version:)

# @api private
def value
self.value = ::Gem::Version.new "4.5.0" if not @value
self.value = ::Gem::Version.new "4.6.0" if not @value
@value
end

Expand Down
48 changes: 31 additions & 17 deletions lib/kitchen/verifier/terraform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@

require "kitchen"
require "kitchen/terraform/config_attribute/color"
require "kitchen/terraform/config_attribute/fail_fast"
require "kitchen/terraform/config_attribute/systems"
require "kitchen/terraform/configurable"
require "kitchen/terraform/error"
require "kitchen/terraform/inspec_options_mapper"
require "kitchen/terraform/system_attrs_resolver"
require "kitchen/terraform/system_hosts_resolver"

module Kitchen
# This namespace is defined by Kitchen.
Expand Down Expand Up @@ -59,6 +58,10 @@ module Verifier
#
# {include:Kitchen::Terraform::ConfigAttribute::Color}
#
# ==== fail_fast
#
# {include:Kitchen::Terraform::ConfigAttribute::FailFast}
#
# ==== systems
#
# {include:Kitchen::Terraform::ConfigAttribute::Systems}
Expand All @@ -71,6 +74,7 @@ class Terraform
include ::Kitchen::Configurable
include ::Kitchen::Logging
include ::Kitchen::Terraform::ConfigAttribute::Color
include ::Kitchen::Terraform::ConfigAttribute::FailFast
include ::Kitchen::Terraform::ConfigAttribute::Systems
include ::Kitchen::Terraform::Configurable
@api_version = 2
Expand All @@ -84,8 +88,9 @@ class Terraform
# @return [void]
def call(_kitchen_state)
load_outputs
config_systems.each do |system|
verify system: system
verify_systems
if !@error_messages.empty?
raise ::Kitchen::ActionFailed, @error_messages.join("\n\n")
end
rescue ::Kitchen::Terraform::Error => error
raise ::Kitchen::ActionFailed, error.message
Expand Down Expand Up @@ -113,6 +118,14 @@ def finalize_config!(kitchen_instance)

private

def handle_error(message:)
if config_fail_fast
raise ::Kitchen::Terraform::Error, message
else
@error_messages.push message
end
end

def load_outputs
instance.driver.retrieve_outputs do |outputs:|
@outputs.replace ::Kitchen::Util.stringified_hash outputs
Expand All @@ -121,6 +134,7 @@ def load_outputs

def initialize(configuration = {})
init_config configuration
@error_messages = []
@inspec_options = { "distinct_exit" => false }
@outputs = {}
end
Expand All @@ -141,24 +155,24 @@ def load_needed_dependencies!
raise ::Kitchen::ClientError, load_error.message
end

def system_attrs_resolver
@system_attrs_resolver ||= ::Kitchen::Terraform::SystemAttrsResolver.new outputs: @outputs
end

def system_hosts_resolver
@system_hosts_resolver ||= ::Kitchen::Terraform::SystemHostsResolver.new outputs: @outputs
end

def system_inspec_options(system:)
::Kitchen::Terraform::InSpecOptionsMapper.new(system: system).map options: @inspec_options.dup
end

def verify(system:)
::Kitchen::Terraform::System
.new(mapping: system)
.resolve_attrs(system_attrs_resolver: system_attrs_resolver)
.resolve_hosts(system_hosts_resolver: system_hosts_resolver)
.verify(inspec_options: system_inspec_options(system: system), inspec_profile_path: inspec_profile_path)
::Kitchen::Terraform::System.new(mapping: system).verify(
inspec_options: system_inspec_options(system: system),
inspec_profile_path: inspec_profile_path,
outputs: @outputs
)
rescue => error
handle_error message: error.message
end

def verify_systems
config_systems.each do |system|
verify system: system
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion ruby-2.3/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GIT
PATH
remote: ..
specs:
kitchen-terraform (4.5.0)
kitchen-terraform (4.6.0)
dry-types (~> 0.14.0)
dry-validation (= 0.13.0)
inspec (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion ruby-2.4/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GIT
PATH
remote: ..
specs:
kitchen-terraform (4.5.0)
kitchen-terraform (4.6.0)
dry-types (~> 0.14.0)
dry-validation (= 0.13.0)
inspec (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion ruby-2.5/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GIT
PATH
remote: ..
specs:
kitchen-terraform (4.5.0)
kitchen-terraform (4.6.0)
dry-types (~> 0.14.0)
dry-validation (= 0.13.0)
inspec (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion ruby-2.6/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GIT
PATH
remote: ..
specs:
kitchen-terraform (4.5.0)
kitchen-terraform (4.6.0)
dry-types (~> 0.14.0)
dry-validation (= 0.13.0)
inspec (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/kitchen/terraform/version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
end

let :version do
::Gem::Version.new "4.5.0"
::Gem::Version.new "4.6.0"
end

describe ".assign_plugin_version" do
Expand Down
Loading

0 comments on commit 36b8392

Please sign in to comment.