inspec-iggy 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +5 -9
- data/README.md +29 -61
- data/inspec-iggy.gemspec +3 -3
- data/lib/inspec-iggy.rb +2 -10
- data/lib/inspec-iggy/cloudformation/cli_command.rb +4 -9
- data/lib/inspec-iggy/cloudformation/parser.rb +14 -27
- data/lib/inspec-iggy/file_helper.rb +40 -0
- data/lib/inspec-iggy/inspec_helper.rb +21 -20
- data/lib/inspec-iggy/plugin.rb +2 -15
- data/lib/inspec-iggy/{profile.rb → profile_helper.rb} +3 -8
- data/lib/inspec-iggy/terraform/cli_command.rb +12 -16
- data/lib/inspec-iggy/terraform/parser.rb +86 -85
- data/lib/inspec-iggy/version.rb +3 -7
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2fda35bc2132112d64bad18dab4c2082adb075b9e9a4f9e809297dcba8f34512
|
4
|
+
data.tar.gz: 3ece40720d734afcb5af8acd8eb54e193dc70c28ca4c87d38bf6d62bcb7c9637
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e34a5bee669e7e63948af184efe3395c45cc46e270d0ed929a8a3d11787d3a5c14f0827ab911050a0a9e1b8be00e32fca212d303b31f46e45c80d4b1119ccc1
|
7
|
+
data.tar.gz: 99ef09d4c2fd5d30896b934b7eda623f37ff24f018bc143dcb1f87f19ba13d70b6f6f620feb38dc44d99eac042baf801e48c77c6203cae796850bb4e316a8925
|
data/Gemfile
CHANGED
@@ -3,15 +3,11 @@ source 'http://rubygems.org'
|
|
3
3
|
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
# follows InSpec's versions
|
6
7
|
group :test do
|
7
|
-
gem '
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
gem 'rubocop' # Needed for style linting
|
8
|
+
gem 'minitest', '~> 5.5'
|
9
|
+
gem 'rake', '>= 10'
|
10
|
+
gem 'rubocop', '= 0.49.1'
|
11
11
|
gem 'm'
|
12
|
-
|
13
|
-
|
14
|
-
group :tools do
|
15
|
-
gem 'github_changelog_generator'
|
16
|
-
gem 'rb-readline'
|
12
|
+
gem 'pry-byebug'
|
17
13
|
end
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Description #
|
2
2
|
|
3
|
-
[![Build Status Master](https://travis-ci.org/
|
3
|
+
[![Build Status Master](https://travis-ci.org/mattray/inspec-iggy.svg?branch=master)](https://travis-ci.org/mattray/inspec-iggy)
|
4
4
|
|
5
5
|
InSpec-Iggy (InSpec Generate -> "IG" -> "Iggy") is an [InSpec](https://inspec.io) plugin for generating compliance controls and profiles from [Terraform](https://terraform.io) `tfstate` files and [AWS CloudFormation](https://aws.amazon.com/cloudformation/) templates. Iggy generates InSpec controls by mapping Terraform and CloudFormation resources to InSpec resources and exports a profile that may be used from the `inspec` CLI or uploaded to [Chef Automate](https://automate.chef.io/).
|
6
6
|
|
@@ -10,32 +10,34 @@ InSpec-Iggy (InSpec Generate -> "IG" -> "Iggy") is an [InSpec](https://inspec.io
|
|
10
10
|
|
11
11
|
Iggy was originally a stand-alone CLI inspired by Christoph Hartmann's [inspec-verify-provision](https://github.com/chris-rock/inspec-verify-provision) and the blog post on testing [InSpec for provisioning testing: Verify Terraform setups with InSpec](http://lollyrock.com/articles/inspec-terraform/).
|
12
12
|
|
13
|
-
The [CHANGELOG.md](https://github.com/
|
13
|
+
The [CHANGELOG.md](https://github.com/mattray/iggy/blob/master/CHANGELOG.md) covers current, previous and future development milestones and contains the features backlog.
|
14
14
|
|
15
15
|
1. [Requirements](#requirements)
|
16
|
-
2. [
|
17
|
-
3. [
|
18
|
-
4. [InSpec Terraform
|
16
|
+
2. [Support](#support)
|
17
|
+
3. [Installation](#installation)
|
18
|
+
4. [InSpec Terraform Generate](#itg)
|
19
19
|
5. [InSpec Cloudformation Generate](#icg)
|
20
|
-
6. [Testing](#
|
20
|
+
6. [Development and Testing](#development)
|
21
|
+
|
22
|
+
# Support<a name="support"></a>
|
23
|
+
|
24
|
+
InSpec-Iggy is a community-driven plugin that is not officially supported by Chef. We welcome patches, suggestions, and issues.
|
21
25
|
|
22
26
|
# Requirements <a name="requirements"></a>
|
23
27
|
|
24
|
-
Iggy generates compliance profiles for InSpec 2.3 and later, which includes the AWS and Azure resources. Because resources are continuing to be added to InSpec, you may want the latest version to support as
|
28
|
+
Iggy generates compliance profiles for InSpec 2.3 and later, which includes the AWS and Azure resources. Because resources are continuing to be added to InSpec, you may want the latest version to support as much resource coverage as possible. It has currently been tested primarily with AWS but other InSpec-supported platforms should work as well.
|
25
29
|
|
26
|
-
Written and tested with Ruby 2.
|
30
|
+
Written and tested with Ruby 2.6.
|
27
31
|
|
28
32
|
# Installation <a name="installation"></a>
|
29
33
|
|
30
34
|
`inspec-iggy` is a plugin for InSpec. InSpec 2.3 or later is required. To install, use:
|
31
35
|
|
32
|
-
|
33
|
-
$ inspec plugin install inspec-iggy
|
34
|
-
```
|
36
|
+
$ inspec plugin install inspec-iggy
|
35
37
|
|
36
38
|
# InSpec Terraform Generate<a name="itg"></a>
|
37
39
|
|
38
|
-
|
40
|
+
inspec terraform generate --tfstate terraform.tfstate --name myprofile
|
39
41
|
|
40
42
|
Iggy dynamically pulls the available AWS resources from InSpec and attempts to map them to Terraform resources, producing an InSpec profile. ```inspec terraform generate --help``` will show all available options.
|
41
43
|
|
@@ -45,7 +47,6 @@ Iggy dynamically pulls the available AWS resources from InSpec and attempts to m
|
|
45
47
|
|
46
48
|
-n, --name=NAME Name of profile to be generated (required)
|
47
49
|
-t, [--tfstate=TFSTATE] Specify path to the input terraform.tfstate (default: .)
|
48
|
-
[--debug], [--no-debug] Verbose debugging messages
|
49
50
|
[--copyright=COPYRIGHT] Name of the copyright holder (default: The Authors)
|
50
51
|
[--email=EMAIL] Email address of the author (default: you@example.com)
|
51
52
|
[--license=LICENSE] License for the profile (default: Apache-2.0)
|
@@ -54,37 +55,9 @@ Iggy dynamically pulls the available AWS resources from InSpec and attempts to m
|
|
54
55
|
[--title=TITLE] Human-readable name for the profile (default: InSpec Profile)
|
55
56
|
[--version=VERSION] Specify the profile version (default: 0.1.0)
|
56
57
|
[--overwrite], [--no-overwrite] Overwrites existing profile directory
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
inspec terraform extract --tfstate terraform.tfstate
|
61
|
-
|
62
|
-
## Tagging Profiles for Extract ##
|
63
|
-
|
64
|
-
Compliance profiles are added to the Terraform Resource to be tested. The current 2 options are the ```aws_vpc``` or the ```aws_instance```. By tagging the ```aws_vpc``` you are specifying that the test is against the AWS API rather than individual machines. AWS instances tagged with compliance profiles will attempt to form command lines for ```inspec exec``` against them.
|
65
|
-
|
66
|
-
### Tagging Format ###
|
67
|
-
|
68
|
-
Given there is not support for lists within AWS tags, we use the convention of starting our tag names with ```inspec_name_``` and ```inspec_url_```. These are extracted and split to identify the relevant compliance profiles to run.
|
69
|
-
|
70
|
-
```
|
71
|
-
tags {
|
72
|
-
iggy_name_apache_baseline = "apache-baseline",
|
73
|
-
iggy_url_apache_baseline = "https://github.com/dev-sec/apache-baseline",
|
74
|
-
iggy_name_linux_baseline = "linux-baseline",
|
75
|
-
iggy_url_linux_baseline = "https://github.com/dev-sec/linux-baseline"
|
76
|
-
}
|
77
|
-
```
|
78
|
-
|
79
|
-
### Potential Enhancements ###
|
80
|
-
|
81
|
-
The current tagging for extraction implementation is directly tied to AWS. Other platforms such as Azure undoubtedly behave differently. Longterm this functionality should probably be turned into a Terraform Provider with predefined outputs.
|
82
|
-
|
83
|
-
Subnet might be a better choice for tagging than VPCs, given they list the AZ.
|
84
|
-
|
85
|
-
Currently it only supports URL-based compliance profiles. InSpec supports other formats (git, path, supermarket, compliance).
|
86
|
-
|
87
|
-
inspec exec https://github.com/dev-sec/linux-baseline -t ssh://clckwrk@52.33.203.34 -i ~/.ssh/mattray-apac
|
58
|
+
[--debug], [--no-debug] Verbose debugging messages
|
59
|
+
[--log-level=LOG_LEVEL] Set the log level: info (default), debug, warn, error
|
60
|
+
[--log-location=LOG_LOCATION] Location to send diagnostic log messages to. (default: STDOUT or Inspec::Log.error)
|
88
61
|
|
89
62
|
# InSpec CloudFormation Generate<a name="icg"></a>
|
90
63
|
|
@@ -99,7 +72,6 @@ Iggy supports AWS CloudFormation templates by mapping the AWS resources to InSpe
|
|
99
72
|
-n, --name=NAME Name of profile to be generated (required)
|
100
73
|
-s, --stack=STACK Specify stack name or unique stack ID associated with the CloudFormation template
|
101
74
|
-t, --template=TEMPLATE Specify path to the input CloudFormation template
|
102
|
-
[--debug], [--no-debug] Verbose debugging messages
|
103
75
|
[--copyright=COPYRIGHT] Name of the copyright holder (default: The Authors)
|
104
76
|
[--email=EMAIL] Email address of the author (default: you@example.com)
|
105
77
|
[--license=LICENSE] License for the profile (default: Apache-2.0)
|
@@ -108,48 +80,44 @@ Iggy supports AWS CloudFormation templates by mapping the AWS resources to InSpe
|
|
108
80
|
[--title=TITLE] Human-readable name for the profile (default: InSpec Profile)
|
109
81
|
[--version=VERSION] Specify the profile version (default: 0.1.0)
|
110
82
|
[--overwrite], [--no-overwrite] Overwrites existing profile directory
|
83
|
+
[--debug], [--no-debug] Verbose debugging messages
|
84
|
+
[--log-level=LOG_LEVEL] Set the log level: info (default), debug, warn, error
|
85
|
+
[--log-location=LOG_LOCATION] Location to send diagnostic log messages to. (default: STDOUT or Inspec::Log.error)
|
111
86
|
|
112
|
-
# Development
|
87
|
+
# Development and Testing<a name="development"></a>
|
88
|
+
|
89
|
+
The [DESIGN.md](DESIGN.md) file outlines how the code is structured if you wish to extend functionality. We welcome patches, suggestions, and issues.
|
113
90
|
|
114
91
|
## Installation
|
115
92
|
|
116
93
|
To point `inspec` at a local copy of `inspec-iggy` for development, use:
|
117
94
|
|
118
|
-
|
119
|
-
$ inspec plugin install path/to/your/inspec-iggy/lib/inspec-iggy.rb
|
120
|
-
```
|
121
|
-
|
122
|
-
# Testing Iggy<a name="testing"></a>
|
95
|
+
$ inspec plugin install path/to/your/inspec-iggy/lib/inspec-iggy.rb
|
123
96
|
|
97
|
+
## Testing Iggy
|
124
98
|
|
125
99
|
Unit, Functional, and Integration tests are provided, though more are welcome. Iggy uses the Minitest library for testing, using the classic `def test...` syntax. Because Iggy loads InSpec into memory, and InSpec uses RSpec internally, Spec-style testing breaks.
|
126
100
|
|
127
101
|
To run all tests, run
|
128
102
|
|
129
|
-
|
130
|
-
$ bundle exec rake test
|
131
|
-
```
|
103
|
+
$ bundle exec rake test
|
132
104
|
|
133
105
|
Linting is also provided via Rubocop.
|
134
106
|
|
135
107
|
To check for code style issues, run:
|
136
108
|
|
137
|
-
|
138
|
-
$ bundle exec rake lint
|
139
|
-
```
|
109
|
+
$ bundle exec rake lint
|
140
110
|
|
141
111
|
You can auto-correct many issues:
|
142
112
|
|
143
|
-
|
144
|
-
$ bundle exec rubocop -a
|
145
|
-
```
|
113
|
+
$ bundle exec rake lint:auto_correct
|
146
114
|
|
147
115
|
# License and Author #
|
148
116
|
|
149
117
|
| | |
|
150
118
|
|:---------------|:------------------------------------------|
|
151
119
|
| **Author** | Matt Ray (<matt@chef.io>) |
|
152
|
-
| **Copyright:** | Copyright (c) 2017-
|
120
|
+
| **Copyright:** | Copyright (c) 2017-2019 Chef Software Inc.|
|
153
121
|
| **License:** | Apache License, Version 2.0 |
|
154
122
|
|
155
123
|
Licensed under the Apache License, Version 2.0 (the "License");
|
data/inspec-iggy.gemspec
CHANGED
@@ -9,9 +9,9 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = InspecPlugins::Iggy::VERSION
|
10
10
|
spec.authors = ['Matt Ray']
|
11
11
|
spec.email = ['matt@chef.io']
|
12
|
-
spec.summary = 'InSpec plugin to generate InSpec compliance profiles from Terraform.'
|
13
|
-
spec.description = '
|
14
|
-
spec.homepage = 'https://github.com/
|
12
|
+
spec.summary = 'InSpec plugin to generate InSpec compliance profiles from Terraform and CloudFormation.'
|
13
|
+
spec.description = 'InSpec plugin to generate InSpec compliance profiles from Terraform and CloudFormation.'
|
14
|
+
spec.homepage = 'https://github.com/mattray/inspec-iggy'
|
15
15
|
spec.license = 'Apache-2.0'
|
16
16
|
|
17
17
|
spec.files = %w{
|
data/lib/inspec-iggy.rb
CHANGED
@@ -1,15 +1,7 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# This file is known as the "entry point."
|
4
|
-
# This is the file InSpec will try to load if it
|
5
|
-
# thinks your plugin is installed.
|
6
|
-
|
7
|
-
# The *only* thing this file should do is setup the
|
8
|
-
# load path, then load the plugin definition file.
|
9
|
-
|
10
1
|
# Next two lines simply add the path of the gem to the load path.
|
11
2
|
# This is not needed when being loaded as a gem; but when doing
|
12
|
-
# plugin development, you may need it.
|
3
|
+
# plugin development, you may need it. Either way, it's harmless.
|
4
|
+
|
13
5
|
libdir = File.dirname(__FILE__)
|
14
6
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
15
7
|
|
@@ -1,20 +1,15 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
6
|
-
#
|
1
|
+
# CloudFormation CLI command and options
|
7
2
|
|
8
3
|
require 'inspec/plugin/v2'
|
9
4
|
|
10
5
|
require 'inspec-iggy/version'
|
11
|
-
require 'inspec-iggy/
|
6
|
+
require 'inspec-iggy/profile_helper'
|
12
7
|
require 'inspec-iggy/cloudformation/parser'
|
13
8
|
|
14
9
|
module InspecPlugins::Iggy
|
15
10
|
module CloudFormation
|
16
11
|
class CliCommand < Inspec.plugin(2, :cli_command)
|
17
|
-
subcommand_desc 'cloudformation SUBCOMMAND ...', 'Generate InSpec from CloudFormation'
|
12
|
+
subcommand_desc 'cloudformation SUBCOMMAND ...', 'Generate an InSpec profile from CloudFormation'
|
18
13
|
|
19
14
|
# Thor.map(Hash) allows you to make aliases for commands.
|
20
15
|
map('-v' => 'version') # Treat `inspec terraform -v`` as `inspec terraform version`
|
@@ -84,7 +79,7 @@ module InspecPlugins::Iggy
|
|
84
79
|
# hash of generated controls
|
85
80
|
generated_controls = InspecPlugins::Iggy::CloudFormation::Parser.parse_generate(options[:template])
|
86
81
|
printable_controls = InspecPlugins::Iggy::InspecHelper.cfn_controls(options[:title], generated_controls, options[:stack])
|
87
|
-
InspecPlugins::Iggy::
|
82
|
+
InspecPlugins::Iggy::ProfileHelper.render_profile(self, options, options[:template], printable_controls)
|
88
83
|
exit 0
|
89
84
|
end
|
90
85
|
end
|
@@ -1,35 +1,22 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
5
|
-
#
|
1
|
+
# parses CloudFormation JSON files
|
6
2
|
|
7
|
-
require 'json'
|
8
3
|
require 'inspec/objects/control'
|
9
4
|
require 'inspec/objects/ruby_helper'
|
10
5
|
require 'inspec/objects/describe'
|
11
6
|
|
7
|
+
require 'inspec-iggy/file_helper'
|
12
8
|
require 'inspec-iggy/inspec_helper'
|
13
9
|
|
14
10
|
module InspecPlugins::Iggy::CloudFormation
|
15
11
|
class Parser
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
STDERR.puts "ERROR: #{file} is an invalid file, please check your path."
|
21
|
-
exit(-1)
|
22
|
-
end
|
23
|
-
template = JSON.parse(File.read(file))
|
24
|
-
rescue JSON::ParserError => e
|
25
|
-
STDERR.puts e.message
|
26
|
-
STDERR.puts "ERROR: Parsing error in #{file}."
|
27
|
-
exit(-1)
|
28
|
-
end
|
29
|
-
absolutename = File.absolute_path(file)
|
12
|
+
# parse through the JSON and generate InSpec controls
|
13
|
+
def self.parse_generate(cfn_template) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
|
14
|
+
template = InspecPlugins::Iggy::FileHelper.parse_json(cfn_template)
|
15
|
+
absolutename = File.absolute_path(cfn_template)
|
30
16
|
|
31
17
|
# InSpec controls generated
|
32
18
|
generated_controls = []
|
19
|
+
|
33
20
|
# iterate over the resources
|
34
21
|
cfn_resources = template['Resources']
|
35
22
|
cfn_resources.keys.each do |cfn_res|
|
@@ -46,7 +33,7 @@ module InspecPlugins::Iggy::CloudFormation
|
|
46
33
|
|
47
34
|
# does this match an InSpec resource?
|
48
35
|
if InspecPlugins::Iggy::InspecHelper::RESOURCES.include?(cfn_res_type)
|
49
|
-
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type}
|
36
|
+
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} MATCHED"
|
50
37
|
|
51
38
|
# insert new control based off the resource's ID
|
52
39
|
ctrl = Inspec::Control.new
|
@@ -72,31 +59,31 @@ module InspecPlugins::Iggy::CloudFormation
|
|
72
59
|
attr_split = attr.split(/(?=[A-Z])/)
|
73
60
|
property = attr_split.join('_').downcase
|
74
61
|
if inspec_properties.member?(property)
|
75
|
-
Inspec::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property}
|
62
|
+
Inspec::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property} MATCHED"
|
76
63
|
value = cfn_resources[cfn_res]['Properties'][attr]
|
77
64
|
if (value.is_a? Hash) || (value.is_a? Array)
|
78
65
|
# these get replaced at inspec exec
|
79
66
|
if property.eql?('vpc_id') # rubocop:disable Metrics/BlockNesting
|
80
67
|
vpc = cfn_resources[cfn_res]['Properties'][attr].values.first
|
81
68
|
# https://github.com/inspec/inspec/issues/3173
|
82
|
-
describe.add_test(property, '
|
69
|
+
describe.add_test(property, 'cmp', "resources[#{vpc}]") unless cfn_res_type.eql?('aws_route_table') # rubocop:disable Metrics/BlockNesting
|
83
70
|
# AMI is a Ref into Parameters
|
84
71
|
elsif property.eql?('image_id') # rubocop:disable Metrics/BlockNesting
|
85
72
|
amiref = cfn_resources[cfn_res]['Properties'][attr].values.first
|
86
73
|
ami = template['Parameters'][amiref]['Default']
|
87
|
-
describe.add_test(property, '
|
74
|
+
describe.add_test(property, 'cmp', ami)
|
88
75
|
end
|
89
76
|
else
|
90
|
-
describe.add_test(property, '
|
77
|
+
describe.add_test(property, 'cmp', value)
|
91
78
|
end
|
92
79
|
else
|
93
|
-
Inspec::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property}
|
80
|
+
Inspec::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property} SKIPPED"
|
94
81
|
end
|
95
82
|
end
|
96
83
|
ctrl.add_test(describe)
|
97
84
|
generated_controls.push(ctrl)
|
98
85
|
else
|
99
|
-
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type}
|
86
|
+
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} SKIPPED"
|
100
87
|
end
|
101
88
|
end
|
102
89
|
Inspec::Log.debug "CloudFormation.parse_generate generated_controls = #{generated_controls}"
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# helper methods for retrieving and parsing files
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
module InspecPlugins
|
7
|
+
module Iggy
|
8
|
+
class FileHelper
|
9
|
+
# boilerplate JSON parsing
|
10
|
+
def self.parse_json(file)
|
11
|
+
Inspec::Log.debug "Iggy::FileHelper.parse_json file = #{file}"
|
12
|
+
lfile = fetch(file)
|
13
|
+
begin
|
14
|
+
unless File.file?(lfile)
|
15
|
+
STDERR.puts "ERROR: #{lfile} is an invalid file, please check your path."
|
16
|
+
exit(-1)
|
17
|
+
end
|
18
|
+
JSON.parse(File.read(lfile))
|
19
|
+
rescue JSON::ParserError => e
|
20
|
+
STDERR.puts e.message
|
21
|
+
STDERR.puts "ERROR: Parsing error in #{lfile}."
|
22
|
+
exit(-1)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.fetch(url)
|
27
|
+
# if this is a file, just return it
|
28
|
+
return url if File.exist?(url)
|
29
|
+
|
30
|
+
begin
|
31
|
+
URI.parse(url).open
|
32
|
+
rescue OpenURI::HTTPError => e
|
33
|
+
STDERR.puts e.message
|
34
|
+
STDERR.puts "ERROR: Parsing error from URL #{url}"
|
35
|
+
exit(-1)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,8 +1,4 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
5
|
-
#
|
1
|
+
# constants and helpers for working with InSpec
|
6
2
|
|
7
3
|
require 'inspec'
|
8
4
|
|
@@ -15,10 +11,14 @@ module InspecPlugins
|
|
15
11
|
# translate Terraform resource name to InSpec
|
16
12
|
TRANSLATED_RESOURCES = {
|
17
13
|
'aws_instance' => 'aws_ec2_instance',
|
14
|
+
'aws_v_p_c' => 'aws_vpc', # CFN
|
15
|
+
'azurerm_resource_group' => 'azure_resource_group',
|
16
|
+
'azurerm_virtual_machine' => 'azure_virtual_machine'
|
17
|
+
# "azure_virtual_machine_data_disk",
|
18
18
|
# 'aws_route' => 'aws_route_table' # needs route_table_id instead of id
|
19
19
|
}.freeze
|
20
20
|
|
21
|
-
#
|
21
|
+
# there really should be some way to get this directly from InSpec's resources
|
22
22
|
def self.resource_properties(resource)
|
23
23
|
# remove the common methods, in theory only leaving only unique InSpec properties
|
24
24
|
inspec_properties = Inspec::Resource.registry[resource].instance_methods - COMMON_PROPERTIES
|
@@ -29,20 +29,6 @@ module InspecPlugins
|
|
29
29
|
inspec_properties
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.print_commands(extracted_profiles)
|
33
|
-
extracted_profiles.keys.each do |cmd|
|
34
|
-
type = extracted_profiles[cmd]['type']
|
35
|
-
url = extracted_profiles[cmd]['url']
|
36
|
-
key_name = extracted_profiles[cmd]['key_name']
|
37
|
-
if type == 'aws_instance'
|
38
|
-
ip = extracted_profiles[cmd]['public_ip']
|
39
|
-
puts "inspec exec #{url} -t ssh://#{ip} -i #{key_name}"
|
40
|
-
else
|
41
|
-
puts "inspec exec #{url} -t aws://us-west-2"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
32
|
def self.tf_controls(title, generated_controls)
|
47
33
|
content = "# encoding: utf-8\n#\n\n"
|
48
34
|
|
@@ -77,5 +63,20 @@ module InspecPlugins
|
|
77
63
|
COMMON_PROPERTIES = Inspec::Resource.registry['aws_subnet'].instance_methods &
|
78
64
|
Inspec::Resource.registry['directory'].instance_methods
|
79
65
|
end
|
66
|
+
|
67
|
+
# disabled extract functionality
|
68
|
+
# def self.print_commands(extracted_profiles)
|
69
|
+
# extracted_profiles.keys.each do |cmd|
|
70
|
+
# type = extracted_profiles[cmd]['type']
|
71
|
+
# url = extracted_profiles[cmd]['url']
|
72
|
+
# key_name = extracted_profiles[cmd]['key_name']
|
73
|
+
# if type == 'aws_instance'
|
74
|
+
# ip = extracted_profiles[cmd]['public_ip']
|
75
|
+
# puts "inspec exec #{url} -t ssh://#{ip} -i #{key_name}"
|
76
|
+
# else
|
77
|
+
# puts "inspec exec #{url} -t aws://us-west-2"
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
# end
|
80
81
|
end
|
81
82
|
end
|
data/lib/inspec-iggy/plugin.rb
CHANGED
@@ -1,30 +1,17 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# Plugin Definition file
|
4
|
-
# The purpose of this file is to declare to InSpec what plugin_types (capabilities)
|
5
|
-
# are included in this plugin, and provide hooks that will load them as needed.
|
6
|
-
|
7
|
-
# It is important that this file load successfully and *quickly*.
|
8
|
-
# Your plugin's functionality may never be used on this InSpec run; so we keep things
|
9
|
-
# fast and light by only loading heavy things when they are needed.
|
10
|
-
|
11
1
|
require 'inspec/plugin/v2'
|
12
2
|
|
13
3
|
# The InspecPlugins namespace is where all plugins should declare themselves.
|
14
4
|
# The 'Inspec' capitalization is used throughout the InSpec source code; yes, it's
|
15
5
|
# strange.
|
16
6
|
module InspecPlugins
|
17
|
-
# Pick a reasonable namespace here for your plugin. A reasonable choice
|
18
|
-
# would be the CamelCase version of your plugin gem name.
|
19
7
|
module Iggy
|
20
8
|
class Plugin < ::Inspec.plugin(2)
|
21
9
|
# Internal machine name of the plugin. InSpec will use this in errors, etc.
|
22
10
|
plugin_name :'inspec-iggy'
|
23
11
|
|
24
12
|
cli_command :terraform do
|
25
|
-
# Calling this hook doesn't mean iggy is being executed - just
|
26
|
-
#
|
27
|
-
# functionality.
|
13
|
+
# Calling this hook doesn't mean iggy is being executed - just that we
|
14
|
+
# should be ready to do so. So, load the file that defines the functionality.
|
28
15
|
# For example, InSpec will activate this hook when `inspec help` is
|
29
16
|
# executed, so that this plugin's usage message will be included in the help.
|
30
17
|
require 'inspec-iggy/terraform/cli_command'
|
@@ -1,15 +1,10 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
6
|
-
#
|
1
|
+
# renders the profile from the parsed files
|
7
2
|
|
8
3
|
require 'yaml'
|
9
4
|
|
10
5
|
module InspecPlugins
|
11
6
|
module Iggy
|
12
|
-
class
|
7
|
+
class ProfileHelper
|
13
8
|
# match the output of 'inspec init profile'
|
14
9
|
def self.render_profile(cli_ui, options, source_file, controls)
|
15
10
|
name = options[:name]
|
@@ -61,7 +56,7 @@ module InspecPlugins
|
|
61
56
|
f.close
|
62
57
|
end
|
63
58
|
|
64
|
-
# * Create file controls/
|
59
|
+
# * Create file controls/controls.rb
|
65
60
|
def self.render_controls_rb(cli_ui, name, controls)
|
66
61
|
render_file = "#{name}/controls/controls.rb"
|
67
62
|
cli_ui.li "Create file #{cli_ui.mark_text(render_file)}"
|
@@ -1,20 +1,15 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
6
|
-
#
|
1
|
+
# Terraform CLI command and options
|
7
2
|
|
8
3
|
require 'inspec/plugin/v2'
|
9
4
|
|
10
5
|
require 'inspec-iggy/version'
|
11
|
-
require 'inspec-iggy/
|
6
|
+
require 'inspec-iggy/profile_helper'
|
12
7
|
require 'inspec-iggy/terraform/parser'
|
13
8
|
|
14
9
|
module InspecPlugins::Iggy
|
15
10
|
module Terraform
|
16
11
|
class CliCommand < Inspec.plugin(2, :cli_command)
|
17
|
-
subcommand_desc 'terraform SUBCOMMAND ...', '
|
12
|
+
subcommand_desc 'terraform SUBCOMMAND ...', 'Generate an InSpec profile from Terraform'
|
18
13
|
|
19
14
|
# Thor.map(Hash) allows you to make aliases for commands.
|
20
15
|
map('-v' => 'version') # Treat `inspec terraform -v`` as `inspec terraform version`
|
@@ -78,17 +73,18 @@ module InspecPlugins::Iggy
|
|
78
73
|
Inspec::Log.level = :debug if options[:debug]
|
79
74
|
generated_controls = InspecPlugins::Iggy::Terraform::Parser.parse_generate(options[:tfstate])
|
80
75
|
printable_controls = InspecPlugins::Iggy::InspecHelper.tf_controls(options[:title], generated_controls)
|
81
|
-
InspecPlugins::Iggy::
|
76
|
+
InspecPlugins::Iggy::ProfileHelper.render_profile(self, options, options[:tfstate], printable_controls)
|
82
77
|
exit 0
|
83
78
|
end
|
84
79
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
80
|
+
# disabled extract functionality
|
81
|
+
# desc 'extract [options]', 'Extract tagged InSpec profiles from terraform.tfstate'
|
82
|
+
# def extract
|
83
|
+
# Inspec::Log.level = :debug if options[:debug]
|
84
|
+
# extracted_profiles = InspecPlugins::Iggy::Terraform::Parser.parse_extract(options[:tfstate])
|
85
|
+
# puts InspecPlugins::Iggy::InspecHelper.print_commands(extracted_profiles)
|
86
|
+
# exit 0
|
87
|
+
# end
|
92
88
|
end
|
93
89
|
end
|
94
90
|
end
|
@@ -1,91 +1,23 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
5
|
-
#
|
6
|
-
|
7
|
-
require 'json'
|
1
|
+
# parses Terraform d.tfstate files
|
8
2
|
|
9
3
|
require 'inspec/objects/control'
|
10
4
|
require 'inspec/objects/ruby_helper'
|
11
5
|
require 'inspec/objects/describe'
|
12
6
|
|
7
|
+
require 'inspec-iggy/file_helper'
|
13
8
|
require 'inspec-iggy/inspec_helper'
|
14
9
|
|
15
10
|
module InspecPlugins::Iggy::Terraform
|
16
11
|
class Parser
|
12
|
+
# disabled extract functionality
|
17
13
|
# makes it easier to change out later
|
18
|
-
TAG_NAME = 'iggy_name_'.freeze
|
19
|
-
TAG_URL = 'iggy_url_'.freeze
|
20
|
-
|
21
|
-
# boilerplate tfstate parsing
|
22
|
-
def self.parse_tfstate(file)
|
23
|
-
Inspec::Log.debug "Iggy::Terraform.parse_tfstate file = #{file}"
|
24
|
-
begin
|
25
|
-
unless File.file?(file)
|
26
|
-
STDERR.puts "ERROR: #{file} is an invalid file, please check your path."
|
27
|
-
exit(-1)
|
28
|
-
end
|
29
|
-
JSON.parse(File.read(file))
|
30
|
-
rescue JSON::ParserError => e
|
31
|
-
STDERR.puts e.message
|
32
|
-
STDERR.puts "ERROR: Parsing error in #{file}."
|
33
|
-
exit(-1)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# parse through the JSON for the tagged Resources
|
38
|
-
def self.parse_extract(file) # rubocop:disable Metrics/AbcSize
|
39
|
-
tfstate = parse_tfstate(file)
|
40
|
-
# InSpec profiles extracted
|
41
|
-
extracted_profiles = {}
|
42
|
-
|
43
|
-
# iterate over the resources
|
44
|
-
tf_resources = tfstate['modules'][0]['resources']
|
45
|
-
tf_resources.keys.each do |tf_res|
|
46
|
-
tf_res_id = tf_resources[tf_res]['primary']['id']
|
47
|
-
|
48
|
-
# get the attributes, see if any of them have a tagged profile attached
|
49
|
-
tf_resources[tf_res]['primary']['attributes'].keys.each do |attr|
|
50
|
-
next unless attr.start_with?('tags.' + TAG_NAME)
|
51
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract tf_res = #{tf_res} attr = #{attr} MATCHED TAG"
|
52
|
-
# get the URL and the name of the profiles
|
53
|
-
name = attr.split(TAG_NAME)[1]
|
54
|
-
url = tf_resources[tf_res]['primary']['attributes']["tags.#{TAG_URL}#{name}"]
|
55
|
-
if tf_res.start_with?('aws_vpc') # should this be VPC or subnet?
|
56
|
-
# if it's a VPC, store it as the VPC id + name
|
57
|
-
key = tf_res_id + ':' + name
|
58
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract aws_vpc tagged with InSpec #{key}"
|
59
|
-
extracted_profiles[key] = {
|
60
|
-
'type' => 'aws_vpc',
|
61
|
-
'az' => 'us-west-2',
|
62
|
-
'url' => url,
|
63
|
-
}
|
64
|
-
elsif tf_res.start_with?('aws_instance')
|
65
|
-
# if it's a node, get information about the IP and SSH/WinRM
|
66
|
-
key = tf_res_id + ':' + name
|
67
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract aws_instance tagged with InSpec #{key}"
|
68
|
-
extracted_profiles[key] = {
|
69
|
-
'type' => 'aws_instance',
|
70
|
-
'public_ip' => tf_resources[tf_res]['primary']['attributes']['public_ip'],
|
71
|
-
'key_name' => tf_resources[tf_res]['primary']['attributes']['key_name'],
|
72
|
-
'url' => url,
|
73
|
-
}
|
74
|
-
else
|
75
|
-
# should generic AWS just be the default except for instances?
|
76
|
-
STDERR.puts "ERROR: #{file} #{tf_res_id} has an InSpec-tagged resource but #{tf_res} is currently unsupported."
|
77
|
-
exit(-1)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract extracted_profiles = #{extracted_profiles}"
|
82
|
-
extracted_profiles
|
83
|
-
end
|
14
|
+
# TAG_NAME = 'iggy_name_'.freeze
|
15
|
+
# TAG_URL = 'iggy_url_'.freeze
|
84
16
|
|
85
17
|
# parse through the JSON and generate InSpec controls
|
86
|
-
def self.parse_generate(
|
87
|
-
tfstate =
|
88
|
-
absolutename = File.absolute_path(
|
18
|
+
def self.parse_generate(tf_file) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
|
19
|
+
tfstate = InspecPlugins::Iggy::FileHelper.parse_json(tf_file)
|
20
|
+
absolutename = File.absolute_path(tf_file)
|
89
21
|
|
90
22
|
# InSpec controls generated
|
91
23
|
generated_controls = []
|
@@ -104,7 +36,7 @@ module InspecPlugins::Iggy::Terraform
|
|
104
36
|
|
105
37
|
# does this match an InSpec resource?
|
106
38
|
if InspecPlugins::Iggy::InspecHelper::RESOURCES.include?(tf_res_type)
|
107
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type}
|
39
|
+
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type} MATCHED"
|
108
40
|
tf_res_id = tf_resources[tf_res]['primary']['id']
|
109
41
|
|
110
42
|
# insert new control based off the resource's ID
|
@@ -115,33 +47,102 @@ module InspecPlugins::Iggy::Terraform
|
|
115
47
|
ctrl.impact = '1.0'
|
116
48
|
|
117
49
|
describe = Inspec::Describe.new
|
118
|
-
# describes the
|
119
|
-
|
50
|
+
# describes the resource with the name as argument
|
51
|
+
# this is a hack for azure, we need a better longterm solution
|
52
|
+
if tf_res_type.start_with?('azure_')
|
53
|
+
name = tf_res_id.split('/').last
|
54
|
+
else
|
55
|
+
name = tf_res_id
|
56
|
+
end
|
120
57
|
|
121
|
-
#
|
122
|
-
|
58
|
+
# describes the resource with the id as argument
|
59
|
+
# going to need to move the special Azure code out, and add helpers for each provider
|
60
|
+
if tf_res_type.start_with?('azure_')
|
61
|
+
if tf_res_type.eql?('azure_resource_group')
|
62
|
+
describe.qualifier.push([tf_res_type, name: name])
|
63
|
+
else
|
64
|
+
resource_group = tf_res_id.split('resourceGroups/').last.split('/').first
|
65
|
+
describe.qualifier.push([tf_res_type, name: name, group_name: resource_group])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
describe.qualifier.push([tf_res_type, tf_res_id])
|
69
|
+
end
|
70
|
+
|
71
|
+
# ensure the resource exists unless Azure, which currently doesn't support it as of InSpec 2.2
|
72
|
+
describe.add_test(nil, 'exist', nil) unless tf_res_type.start_with?('azure_')
|
123
73
|
|
124
74
|
# if there's a match, see if there are matching InSpec properties
|
125
75
|
inspec_properties = InspecPlugins::Iggy::InspecHelper.resource_properties(tf_res_type)
|
76
|
+
# push stuff back into inspec_properties?
|
77
|
+
inspec_properties.push('name') if tf_res_type.start_with?('azure_')
|
126
78
|
tf_resources[tf_res]['primary']['attributes'].keys.each do |attr|
|
127
79
|
if inspec_properties.member?(attr)
|
128
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate #{tf_res_type} inspec_property = #{attr}
|
80
|
+
Inspec::Log.debug "Iggy::Terraform.parse_generate #{tf_res_type} inspec_property = #{attr} MATCHED"
|
129
81
|
value = tf_resources[tf_res]['primary']['attributes'][attr]
|
130
|
-
describe.add_test(attr, '
|
82
|
+
describe.add_test(attr, 'cmp', value)
|
131
83
|
else
|
132
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate #{tf_res_type} inspec_property = #{attr}
|
84
|
+
Inspec::Log.debug "Iggy::Terraform.parse_generate #{tf_res_type} inspec_property = #{attr} SKIPPED"
|
133
85
|
end
|
134
86
|
end
|
135
87
|
|
136
88
|
ctrl.add_test(describe)
|
137
89
|
generated_controls.push(ctrl)
|
138
90
|
else
|
139
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type}
|
91
|
+
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type} SKIPPED"
|
140
92
|
end
|
141
93
|
end
|
142
94
|
end
|
143
95
|
Inspec::Log.debug "Iggy::Terraform.parse_generate generated_controls = #{generated_controls}"
|
144
96
|
generated_controls
|
145
97
|
end
|
98
|
+
|
99
|
+
# disabled extract functionality
|
100
|
+
# # parse through the JSON for the tagged Resources
|
101
|
+
# def self.parse_extract(file)
|
102
|
+
# tfstate = parse_tfstate(file)
|
103
|
+
# # InSpec profiles extracted
|
104
|
+
# extracted_profiles = {}
|
105
|
+
|
106
|
+
# # iterate over the resources
|
107
|
+
# tf_resources = tfstate['modules'][0]['resources']
|
108
|
+
# tf_resources.keys.each do |tf_res|
|
109
|
+
# tf_res_id = tf_resources[tf_res]['primary']['id']
|
110
|
+
|
111
|
+
# # get the attributes, see if any of them have a tagged profile attached
|
112
|
+
# tf_resources[tf_res]['primary']['attributes'].keys.each do |attr|
|
113
|
+
# next unless attr.start_with?('tags.' + TAG_NAME)
|
114
|
+
# Inspec::Log.debug "Iggy::Terraform.parse_extract tf_res = #{tf_res} attr = #{attr} MATCHED TAG"
|
115
|
+
# # get the URL and the name of the profiles
|
116
|
+
# name = attr.split(TAG_NAME)[1]
|
117
|
+
# url = tf_resources[tf_res]['primary']['attributes']["tags.#{TAG_URL}#{name}"]
|
118
|
+
# if tf_res.start_with?('aws_vpc') # should this be VPC or subnet?
|
119
|
+
# # if it's a VPC, store it as the VPC id + name
|
120
|
+
# key = tf_res_id + ':' + name
|
121
|
+
# Inspec::Log.debug "Iggy::Terraform.parse_extract aws_vpc tagged with InSpec #{key}"
|
122
|
+
# extracted_profiles[key] = {
|
123
|
+
# 'type' => 'aws_vpc',
|
124
|
+
# 'az' => 'us-west-2',
|
125
|
+
# 'url' => url,
|
126
|
+
# }
|
127
|
+
# elsif tf_res.start_with?('aws_instance')
|
128
|
+
# # if it's a node, get information about the IP and SSH/WinRM
|
129
|
+
# key = tf_res_id + ':' + name
|
130
|
+
# Inspec::Log.debug "Iggy::Terraform.parse_extract aws_instance tagged with InSpec #{key}"
|
131
|
+
# extracted_profiles[key] = {
|
132
|
+
# 'type' => 'aws_instance',
|
133
|
+
# 'public_ip' => tf_resources[tf_res]['primary']['attributes']['public_ip'],
|
134
|
+
# 'key_name' => tf_resources[tf_res]['primary']['attributes']['key_name'],
|
135
|
+
# 'url' => url,
|
136
|
+
# }
|
137
|
+
# else
|
138
|
+
# # should generic AWS just be the default except for instances?
|
139
|
+
# STDERR.puts "ERROR: #{file} #{tf_res_id} has an InSpec-tagged resource but #{tf_res} is currently unsupported."
|
140
|
+
# exit(-1)
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
# Inspec::Log.debug "Iggy::Terraform.parse_extract extracted_profiles = #{extracted_profiles}"
|
145
|
+
# extracted_profiles
|
146
|
+
# end
|
146
147
|
end
|
147
148
|
end
|
data/lib/inspec-iggy/version.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
6
|
-
#
|
1
|
+
# provide the version for the plugin
|
2
|
+
|
7
3
|
module InspecPlugins
|
8
4
|
module Iggy
|
9
|
-
VERSION = '0.
|
5
|
+
VERSION = '0.5.0'.freeze
|
10
6
|
end
|
11
7
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec-iggy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Ray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inspec
|
@@ -30,8 +30,8 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 4.0.0
|
33
|
-
description:
|
34
|
-
|
33
|
+
description: InSpec plugin to generate InSpec compliance profiles from Terraform and
|
34
|
+
CloudFormation.
|
35
35
|
email:
|
36
36
|
- matt@chef.io
|
37
37
|
executables: []
|
@@ -44,13 +44,14 @@ files:
|
|
44
44
|
- lib/inspec-iggy.rb
|
45
45
|
- lib/inspec-iggy/cloudformation/cli_command.rb
|
46
46
|
- lib/inspec-iggy/cloudformation/parser.rb
|
47
|
+
- lib/inspec-iggy/file_helper.rb
|
47
48
|
- lib/inspec-iggy/inspec_helper.rb
|
48
49
|
- lib/inspec-iggy/plugin.rb
|
49
|
-
- lib/inspec-iggy/
|
50
|
+
- lib/inspec-iggy/profile_helper.rb
|
50
51
|
- lib/inspec-iggy/terraform/cli_command.rb
|
51
52
|
- lib/inspec-iggy/terraform/parser.rb
|
52
53
|
- lib/inspec-iggy/version.rb
|
53
|
-
homepage: https://github.com/
|
54
|
+
homepage: https://github.com/mattray/inspec-iggy
|
54
55
|
licenses:
|
55
56
|
- Apache-2.0
|
56
57
|
metadata: {}
|
@@ -69,9 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
70
|
- !ruby/object:Gem::Version
|
70
71
|
version: '0'
|
71
72
|
requirements: []
|
72
|
-
|
73
|
-
rubygems_version: 2.6.13
|
73
|
+
rubygems_version: 3.0.3
|
74
74
|
signing_key:
|
75
75
|
specification_version: 4
|
76
|
-
summary: InSpec plugin to generate InSpec compliance profiles from Terraform.
|
76
|
+
summary: InSpec plugin to generate InSpec compliance profiles from Terraform and CloudFormation.
|
77
77
|
test_files: []
|