inspec-iggy 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +19 -0
- data/README.md +34 -3
- data/inspec-iggy.gemspec +2 -2
- data/lib/inspec-iggy/cloudformation/cli_command.rb +3 -3
- data/lib/inspec-iggy/cloudformation/{parser.rb → generate.rb} +9 -9
- data/lib/inspec-iggy/inspec_helper.rb +443 -27
- data/lib/inspec-iggy/platforms/aws_helper.rb +42 -0
- data/lib/inspec-iggy/platforms/azure_helper.rb +38 -0
- data/lib/inspec-iggy/platforms/gcp_helper.rb +168 -0
- data/lib/inspec-iggy/profile_helper.rb +50 -29
- data/lib/inspec-iggy/terraform/cli_command.rb +74 -49
- data/lib/inspec-iggy/terraform/generate.rb +130 -0
- data/lib/inspec-iggy/terraform/negative.rb +112 -0
- data/lib/inspec-iggy/version.rb +1 -1
- metadata +12 -8
- data/lib/inspec-iggy/terraform/parser.rb +0 -148
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 937720e2817669251c145140bb5a1a7c168fd2afa66a02fe3313028facbee416
|
4
|
+
data.tar.gz: 787196902a3ce2826b11498a38b7ddad33ba7f28e73f37d32c1924889fd51f48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e10cdd048643efe66f40c294f97297eaad4f0652d59951f7a77afa7859d27990e32feee91cc841e261a9b30b5af1b1b12a8b712f412ad02011faf5826478907
|
7
|
+
data.tar.gz: bc13bd1ab48457f3c335f839454aa4605aa146c8e0c0393da051709af8fb8b92f0e5ecc8c1d7c286bb54d78b5efe36a40e63f44cbd236a97a0af137dcfac5289
|
data/Gemfile
CHANGED
@@ -11,3 +11,22 @@ group :test do
|
|
11
11
|
gem 'm'
|
12
12
|
gem 'pry-byebug'
|
13
13
|
end
|
14
|
+
|
15
|
+
group :aws do
|
16
|
+
# gem 'aws-sdk', '~> 3'
|
17
|
+
gem 'aws-sdk-autoscaling', '~> 1'
|
18
|
+
gem 'aws-sdk-cloudtrail', '~> 1'
|
19
|
+
gem 'aws-sdk-cloudwatch', '~> 1'
|
20
|
+
gem 'aws-sdk-cloudwatchlogs', '~> 1'
|
21
|
+
gem 'aws-sdk-configservice', '~> 1'
|
22
|
+
gem 'aws-sdk-ec2', '~> 1'
|
23
|
+
gem 'aws-sdk-ecs', '~> 1'
|
24
|
+
gem 'aws-sdk-eks', '~> 1'
|
25
|
+
gem 'aws-sdk-elasticloadbalancing', '~> 1'
|
26
|
+
gem 'aws-sdk-iam', '~> 1'
|
27
|
+
gem 'aws-sdk-organizations', '~> 1'
|
28
|
+
gem 'aws-sdk-rds', '~> 1'
|
29
|
+
gem 'aws-sdk-s3', '~> 1'
|
30
|
+
gem 'aws-sdk-sns', '~> 1'
|
31
|
+
gem 'aws-sdk-sqs', '~> 1'
|
32
|
+
end
|
data/README.md
CHANGED
@@ -16,8 +16,9 @@ The [CHANGELOG.md](https://github.com/mattray/iggy/blob/master/CHANGELOG.md) cov
|
|
16
16
|
2. [Support](#support)
|
17
17
|
3. [Installation](#installation)
|
18
18
|
4. [InSpec Terraform Generate](#itg)
|
19
|
-
5. [InSpec
|
20
|
-
6. [
|
19
|
+
5. [InSpec Terraform Negative](#itn)
|
20
|
+
6. [InSpec Cloudformation Generate](#icg)
|
21
|
+
7. [Development and Testing](#development)
|
21
22
|
|
22
23
|
# Support<a name="support"></a>
|
23
24
|
|
@@ -39,7 +40,7 @@ Written and tested with Ruby 2.6.
|
|
39
40
|
|
40
41
|
inspec terraform generate --tfstate terraform.tfstate --name myprofile
|
41
42
|
|
42
|
-
Iggy dynamically pulls the available
|
43
|
+
Iggy dynamically pulls the available Cloud resources from InSpec and attempts to map them to Terraform resources, producing an InSpec profile. ```inspec terraform generate --help``` will show all available options.
|
43
44
|
|
44
45
|
## Usage
|
45
46
|
|
@@ -58,6 +59,36 @@ Iggy dynamically pulls the available AWS resources from InSpec and attempts to m
|
|
58
59
|
[--debug], [--no-debug] Verbose debugging messages
|
59
60
|
[--log-level=LOG_LEVEL] Set the log level: info (default), debug, warn, error
|
60
61
|
[--log-location=LOG_LOCATION] Location to send diagnostic log messages to. (default: STDOUT or Inspec::Log.error)
|
62
|
+
[--platform=gcp|aws|azure] Cloud provider name
|
63
|
+
[--resourcepath=INSPEC_CLOUD_RESOURCE_PATH] Location of inspec-gcp|inspec-aws|inspec-azure resources
|
64
|
+
Note: --resourcepath should point to the directory where inspec-<cloud_provider> resource pack is downloaded/cloned from Github.
|
65
|
+
|
66
|
+
# InSpec Terraform Negative<a name="itn"></a>
|
67
|
+
|
68
|
+
inspec terraform negative --tfstate terraform.tfstate --name myprofile
|
69
|
+
|
70
|
+
Iggy dynamically pulls the available Cloud resources from InSpec and attempts to map them to Terraform resources, producing an InSpec profile which are not part of tfstate file. It informs the user that these resources are not part of tfstate file and can be deleted if not needed.```inspec terraform negative --help``` will show all available options.
|
71
|
+
|
72
|
+
## Usage
|
73
|
+
|
74
|
+
inspec terraform negative [options] -n, --name=NAME
|
75
|
+
|
76
|
+
-n, --name=NAME Name of profile to be generated (required)
|
77
|
+
-t, [--tfstate=TFSTATE] Specify path to the input terraform.tfstate (default: .)
|
78
|
+
[--copyright=COPYRIGHT] Name of the copyright holder (default: The Authors)
|
79
|
+
[--email=EMAIL] Email address of the author (default: you@example.com)
|
80
|
+
[--license=LICENSE] License for the profile (default: Apache-2.0)
|
81
|
+
[--maintainer=MAINTAINER] Name of the copyright holder (default: The Authors)
|
82
|
+
[--summary=SUMMARY] One line summary for the profile (default: An InSpec Compliance Profile)
|
83
|
+
[--title=TITLE] Human-readable name for the profile (default: InSpec Profile)
|
84
|
+
[--version=VERSION] Specify the profile version (default: 0.1.0)
|
85
|
+
[--overwrite], [--no-overwrite] Overwrites existing profile directory
|
86
|
+
[--debug], [--no-debug] Verbose debugging messages
|
87
|
+
[--log-level=LOG_LEVEL] Set the log level: info (default), debug, warn, error
|
88
|
+
[--log-location=LOG_LOCATION] Location to send diagnostic log messages to. (default: STDOUT or Inspec::Log.error)
|
89
|
+
[--platform=gcp|aws|azure] Cloud provider name
|
90
|
+
[--resourcepath=INSPEC_CLOUD_RESOURCE_PATH] Location of inspec-gcp|inspec-aws|inspec-azure resources
|
91
|
+
Note: --resourcepath should point to the directory where inspec-<cloud_provider> resource pack is downloaded/cloned from Github.
|
61
92
|
|
62
93
|
# InSpec CloudFormation Generate<a name="icg"></a>
|
63
94
|
|
data/inspec-iggy.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ['Matt Ray']
|
11
11
|
spec.email = ['matt@chef.io']
|
12
12
|
spec.summary = 'InSpec plugin to generate InSpec compliance profiles from Terraform and CloudFormation.'
|
13
|
-
spec.description = 'InSpec plugin to generate InSpec
|
13
|
+
spec.description = 'InSpec plugin to generate InSpec profiles from Terraform and CloudFormation to ensure automatic compliance coverage.'
|
14
14
|
spec.homepage = 'https://github.com/mattray/inspec-iggy'
|
15
15
|
spec.license = 'Apache-2.0'
|
16
16
|
|
@@ -22,5 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
|
-
spec.add_dependency 'inspec', '>=2.3', '<
|
25
|
+
spec.add_dependency 'inspec', '>=2.3', '<5'
|
26
26
|
end
|
@@ -4,7 +4,7 @@ require 'inspec/plugin/v2'
|
|
4
4
|
|
5
5
|
require 'inspec-iggy/version'
|
6
6
|
require 'inspec-iggy/profile_helper'
|
7
|
-
require 'inspec-iggy/cloudformation/
|
7
|
+
require 'inspec-iggy/cloudformation/generate'
|
8
8
|
|
9
9
|
module InspecPlugins::Iggy
|
10
10
|
module CloudFormation
|
@@ -77,9 +77,9 @@ module InspecPlugins::Iggy
|
|
77
77
|
def generate
|
78
78
|
Inspec::Log.level = :debug if options[:debug]
|
79
79
|
# hash of generated controls
|
80
|
-
generated_controls = InspecPlugins::Iggy::CloudFormation::
|
80
|
+
generated_controls = InspecPlugins::Iggy::CloudFormation::Generate.parse_generate(options[:template])
|
81
81
|
printable_controls = InspecPlugins::Iggy::InspecHelper.cfn_controls(options[:title], generated_controls, options[:stack])
|
82
|
-
InspecPlugins::Iggy::ProfileHelper.render_profile(
|
82
|
+
InspecPlugins::Iggy::ProfileHelper.render_profile(ui, options, options[:template], printable_controls)
|
83
83
|
exit 0
|
84
84
|
end
|
85
85
|
end
|
@@ -8,7 +8,7 @@ require 'inspec-iggy/file_helper'
|
|
8
8
|
require 'inspec-iggy/inspec_helper'
|
9
9
|
|
10
10
|
module InspecPlugins::Iggy::CloudFormation
|
11
|
-
class
|
11
|
+
class Generate
|
12
12
|
# parse through the JSON and generate InSpec controls
|
13
13
|
def self.parse_generate(cfn_template) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
|
14
14
|
template = InspecPlugins::Iggy::FileHelper.parse_json(cfn_template)
|
@@ -27,13 +27,13 @@ module InspecPlugins::Iggy::CloudFormation
|
|
27
27
|
|
28
28
|
# add translation layer
|
29
29
|
if InspecPlugins::Iggy::InspecHelper::TRANSLATED_RESOURCES.key?(cfn_res_type)
|
30
|
-
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} #{InspecPlugins::Iggy::InspecHelper::TRANSLATED_RESOURCES[cfn_res_type]} TRANSLATED"
|
30
|
+
Inspec::Log.debug "CloudFormation::Generate.parse_generate cfn_res_type = #{cfn_res_type} #{InspecPlugins::Iggy::InspecHelper::TRANSLATED_RESOURCES[cfn_res_type]} TRANSLATED"
|
31
31
|
cfn_res_type = InspecPlugins::Iggy::InspecHelper::TRANSLATED_RESOURCES[cfn_res_type]
|
32
32
|
end
|
33
33
|
|
34
34
|
# does this match an InSpec resource?
|
35
|
-
if InspecPlugins::Iggy::InspecHelper
|
36
|
-
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} MATCHED"
|
35
|
+
if InspecPlugins::Iggy::InspecHelper.available_resources.include?(cfn_res_type)
|
36
|
+
Inspec::Log.debug "CloudFormation::Generate.parse_generate cfn_res_type = #{cfn_res_type} MATCHED"
|
37
37
|
|
38
38
|
# insert new control based off the resource's ID
|
39
39
|
ctrl = Inspec::Control.new
|
@@ -53,13 +53,13 @@ module InspecPlugins::Iggy::CloudFormation
|
|
53
53
|
describe.add_test(nil, 'be_running', nil) if cfn_res_type.eql?('aws_ec2_instance')
|
54
54
|
|
55
55
|
# if there's a match, see if there are matching InSpec properties
|
56
|
-
inspec_properties = InspecPlugins::Iggy::InspecHelper.resource_properties(cfn_res_type)
|
56
|
+
inspec_properties = InspecPlugins::Iggy::InspecHelper.resource_properties(cfn_res_type, 'aws')
|
57
57
|
cfn_resources[cfn_res]['Properties'].keys.each do |attr|
|
58
58
|
# insert '_' on the CamelCase to get camel_case
|
59
59
|
attr_split = attr.split(/(?=[A-Z])/)
|
60
60
|
property = attr_split.join('_').downcase
|
61
61
|
if inspec_properties.member?(property)
|
62
|
-
Inspec::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property} MATCHED"
|
62
|
+
Inspec::Log.debug "CloudFormation::Generate.parse_generate #{cfn_res_type} inspec_property = #{property} MATCHED"
|
63
63
|
value = cfn_resources[cfn_res]['Properties'][attr]
|
64
64
|
if (value.is_a? Hash) || (value.is_a? Array)
|
65
65
|
# these get replaced at inspec exec
|
@@ -77,16 +77,16 @@ module InspecPlugins::Iggy::CloudFormation
|
|
77
77
|
describe.add_test(property, 'cmp', value)
|
78
78
|
end
|
79
79
|
else
|
80
|
-
Inspec::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property} SKIPPED"
|
80
|
+
Inspec::Log.debug "CloudFormation::Generate.parse_generate #{cfn_res_type} inspec_property = #{property} SKIPPED"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
ctrl.add_test(describe)
|
84
84
|
generated_controls.push(ctrl)
|
85
85
|
else
|
86
|
-
Inspec::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} SKIPPED"
|
86
|
+
Inspec::Log.debug "CloudFormation::Generate.parse_generate cfn_res_type = #{cfn_res_type} SKIPPED"
|
87
87
|
end
|
88
88
|
end
|
89
|
-
Inspec::Log.debug "CloudFormation.parse_generate generated_controls = #{generated_controls}"
|
89
|
+
Inspec::Log.debug "CloudFormation::Generate.parse_generate generated_controls = #{generated_controls}"
|
90
90
|
generated_controls
|
91
91
|
end
|
92
92
|
end
|
@@ -2,11 +2,19 @@
|
|
2
2
|
|
3
3
|
require 'inspec'
|
4
4
|
|
5
|
+
require 'inspec-iggy/platforms/aws_helper'
|
6
|
+
require 'inspec-iggy/platforms/azure_helper'
|
7
|
+
require 'inspec-iggy/platforms/gcp_helper'
|
8
|
+
|
5
9
|
module InspecPlugins
|
6
10
|
module Iggy
|
7
11
|
class InspecHelper
|
8
|
-
|
9
|
-
|
12
|
+
@inspec_resources = Inspec::Resource.registry.keys
|
13
|
+
|
14
|
+
# list of resources available from InSpec
|
15
|
+
def self.available_resources
|
16
|
+
@inspec_resources
|
17
|
+
end
|
10
18
|
|
11
19
|
# translate Terraform resource name to InSpec
|
12
20
|
TRANSLATED_RESOURCES = {
|
@@ -18,10 +26,429 @@ module InspecPlugins
|
|
18
26
|
# 'aws_route' => 'aws_route_table' # needs route_table_id instead of id
|
19
27
|
}.freeze
|
20
28
|
|
29
|
+
def self.available_resource_qualifiers(platform)
|
30
|
+
case platform
|
31
|
+
when 'aws'
|
32
|
+
InspecPlugins::Iggy::Platforms::AwsHelper::AWS_RESOURCE_QUALIFIERS
|
33
|
+
when 'azure'
|
34
|
+
InspecPlugins::Iggy::Platforms::AzureHelper::AZURE_RESOURCE_QUALIFIERS
|
35
|
+
when 'gcp'
|
36
|
+
InspecPlugins::Iggy::Platforms::GcpHelper::GCP_RESOURCE_QUALIFIERS
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.available_resource_iterators(platform)
|
41
|
+
case platform
|
42
|
+
when 'aws'
|
43
|
+
InspecPlugins::Iggy::Platforms::AwsHelper::AWS_RESOURCE_ITERATORS
|
44
|
+
when 'azure'
|
45
|
+
InspecPlugins::Iggy::Platforms::AzureHelper::AZURE_RESOURCE_ITERATORS
|
46
|
+
when 'gcp'
|
47
|
+
InspecPlugins::Iggy::Platforms::GcpHelper::GCP_RESOURCE_ITERATORS
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# manually maintained common methods we don't want to test InSpec properties
|
52
|
+
REMOVED_COMMON_PROPERTIES = [
|
53
|
+
:!,
|
54
|
+
:!=,
|
55
|
+
:!~,
|
56
|
+
:<=>,
|
57
|
+
:==,
|
58
|
+
:===,
|
59
|
+
:=~,
|
60
|
+
:__binding__,
|
61
|
+
:__id__,
|
62
|
+
:__send__,
|
63
|
+
:check_supports,
|
64
|
+
:class,
|
65
|
+
:clone,
|
66
|
+
:dclone,
|
67
|
+
:define_singleton_method,
|
68
|
+
:display,
|
69
|
+
:dup,
|
70
|
+
:enum_for,
|
71
|
+
:eql?,
|
72
|
+
:equal?,
|
73
|
+
:extend,
|
74
|
+
:fail_resource,
|
75
|
+
:freeze,
|
76
|
+
:frozen?,
|
77
|
+
:hash,
|
78
|
+
:inspec,
|
79
|
+
:inspect,
|
80
|
+
:instance_eval,
|
81
|
+
:instance_exec,
|
82
|
+
:instance_of?,
|
83
|
+
:instance_variable_defined?,
|
84
|
+
:instance_variable_get,
|
85
|
+
:instance_variable_set,
|
86
|
+
:instance_variables,
|
87
|
+
:is_a?,
|
88
|
+
:itself,
|
89
|
+
:kind_of?,
|
90
|
+
:method,
|
91
|
+
:methods,
|
92
|
+
:nil?,
|
93
|
+
:object_id,
|
94
|
+
:pretty_inspect,
|
95
|
+
:pretty_print,
|
96
|
+
:pretty_print_cycle,
|
97
|
+
:pretty_print_inspect,
|
98
|
+
:pretty_print_instance_variables,
|
99
|
+
:private_methods,
|
100
|
+
:protected_methods,
|
101
|
+
:pry,
|
102
|
+
:public_method,
|
103
|
+
:public_methods,
|
104
|
+
:public_send,
|
105
|
+
:remove_instance_variable,
|
106
|
+
:resource_exception_message,
|
107
|
+
:resource_failed?,
|
108
|
+
:resource_skipped?,
|
109
|
+
:respond_to?,
|
110
|
+
:send,
|
111
|
+
:should,
|
112
|
+
:should_not,
|
113
|
+
:singleton_class,
|
114
|
+
:singleton_method,
|
115
|
+
:singleton_methods,
|
116
|
+
:skip_resource,
|
117
|
+
:taint,
|
118
|
+
:tainted?,
|
119
|
+
:tap,
|
120
|
+
:then,
|
121
|
+
:to_enum,
|
122
|
+
:to_json,
|
123
|
+
:to_s,
|
124
|
+
:to_yaml,
|
125
|
+
:trust,
|
126
|
+
:untaint,
|
127
|
+
:untrust,
|
128
|
+
:untrusted?,
|
129
|
+
:yield_self
|
130
|
+
].freeze
|
131
|
+
|
132
|
+
# properties are often dynamically generated, making it hard to determine
|
133
|
+
# their existence without instantiating them. Because of this, we will
|
134
|
+
# maintain a manual list for now
|
135
|
+
ADDITIONAL_COMMON_PROPERTIES = [
|
136
|
+
# :backend_service, # documented but undefined
|
137
|
+
# :id, #disabled for GCP
|
138
|
+
# :ip_version, # documented but undefined
|
139
|
+
# :network, # documented but undefined
|
140
|
+
# :subnetwork, # documented but undefined
|
141
|
+
:addons_config,
|
142
|
+
:address_type,
|
143
|
+
:address,
|
144
|
+
:aggregation_alignment_period,
|
145
|
+
:aggregation_cross_series_reducer,
|
146
|
+
:aggregation_per_series_aligner,
|
147
|
+
:allowed,
|
148
|
+
:archive_size_bytes,
|
149
|
+
:auto_create_subnetworks,
|
150
|
+
:available_cpu_platforms,
|
151
|
+
:available_memory_mb,
|
152
|
+
:backend_service,
|
153
|
+
:backup_pool,
|
154
|
+
:base_instance_name,
|
155
|
+
:can_ip_forward,
|
156
|
+
:check_interval_sec,
|
157
|
+
:cluster_ipv4_cidr,
|
158
|
+
:combiner,
|
159
|
+
:common_instance_metadata,
|
160
|
+
:condition_threshold_value,
|
161
|
+
:conditions,
|
162
|
+
:config,
|
163
|
+
:cpu_platform,
|
164
|
+
:create_time_date,
|
165
|
+
:create_time,
|
166
|
+
:creation_record,
|
167
|
+
:creation_timestamp_date,
|
168
|
+
:creation_timestamp,
|
169
|
+
:crypto_key_name,
|
170
|
+
:crypto_key_url,
|
171
|
+
:current_actions,
|
172
|
+
:current_master_version,
|
173
|
+
:current_node_count,
|
174
|
+
:current_node_version,
|
175
|
+
:custom_features,
|
176
|
+
:dataset_id,
|
177
|
+
:dataset,
|
178
|
+
:default_exempted_members,
|
179
|
+
:default_service_account,
|
180
|
+
:default_types,
|
181
|
+
:deletion_protection,
|
182
|
+
:description,
|
183
|
+
:detailed_status,
|
184
|
+
:direction,
|
185
|
+
:disabled,
|
186
|
+
:disk_encryption_key,
|
187
|
+
:disk_size_gb,
|
188
|
+
:disks,
|
189
|
+
:display_name,
|
190
|
+
:dns_name,
|
191
|
+
:dnssec_config,
|
192
|
+
:enabled_features,
|
193
|
+
:enabled,
|
194
|
+
:endpoint,
|
195
|
+
:entry_point,
|
196
|
+
:environment_variables,
|
197
|
+
:etag,
|
198
|
+
:expire_time,
|
199
|
+
:failover_ratio,
|
200
|
+
:family,
|
201
|
+
:filename,
|
202
|
+
:filter,
|
203
|
+
:fingerprint,
|
204
|
+
:friendly_name,
|
205
|
+
:gateway_address,
|
206
|
+
:guest_accelerators,
|
207
|
+
:guest_os_features,
|
208
|
+
:health_check,
|
209
|
+
:healthy_threshold,
|
210
|
+
:host,
|
211
|
+
:ignored_files,
|
212
|
+
:ike_version,
|
213
|
+
:included_files,
|
214
|
+
:included_permissions,
|
215
|
+
:initial_cluster_version,
|
216
|
+
:initial_node_count,
|
217
|
+
:instance_group_urls,
|
218
|
+
:instance_group,
|
219
|
+
:instance_template,
|
220
|
+
:ip_address,
|
221
|
+
:ip_cidr_range,
|
222
|
+
:ip_protocol,
|
223
|
+
:ip_version,
|
224
|
+
:key_ring_name,
|
225
|
+
:key_ring_url,
|
226
|
+
:key_signing_key_algorithm,
|
227
|
+
:kind,
|
228
|
+
:kms_key_name,
|
229
|
+
:label_fingerprint,
|
230
|
+
:label_value_by_key,
|
231
|
+
:labels_keys,
|
232
|
+
:labels_values,
|
233
|
+
:labels,
|
234
|
+
:last_attach_timestamp,
|
235
|
+
:last_detach_timestamp,
|
236
|
+
:last_modified_time,
|
237
|
+
:legacy_abac,
|
238
|
+
:licenses,
|
239
|
+
:lifecycle_state,
|
240
|
+
:load_balancing_scheme,
|
241
|
+
:local_traffic_selector,
|
242
|
+
:location,
|
243
|
+
:logging_service,
|
244
|
+
:machine_type,
|
245
|
+
:managed_zone,
|
246
|
+
:management,
|
247
|
+
:master_auth,
|
248
|
+
:members,
|
249
|
+
:metadata_keys,
|
250
|
+
:metadata_value_by_key,
|
251
|
+
:metadata_values,
|
252
|
+
:metadata,
|
253
|
+
:min_cpu_platform,
|
254
|
+
:monitoring_service,
|
255
|
+
:mutation_record,
|
256
|
+
:name_servers,
|
257
|
+
:family,
|
258
|
+
:filename,
|
259
|
+
:filter,
|
260
|
+
:fingerprint,
|
261
|
+
:friendly_name,
|
262
|
+
:gateway_address,
|
263
|
+
:guest_accelerators,
|
264
|
+
:guest_os_features,
|
265
|
+
:health_check,
|
266
|
+
:healthy_threshold,
|
267
|
+
:host,
|
268
|
+
:ignored_files,
|
269
|
+
:ike_version,
|
270
|
+
:included_files,
|
271
|
+
:included_permissions,
|
272
|
+
:initial_cluster_version,
|
273
|
+
:initial_node_count,
|
274
|
+
:instance_group_urls,
|
275
|
+
:instance_group,
|
276
|
+
:instance_template,
|
277
|
+
:ip_address,
|
278
|
+
:ip_cidr_range,
|
279
|
+
:ip_protocol,
|
280
|
+
:ip_version,
|
281
|
+
:key_ring_name,
|
282
|
+
:key_ring_url,
|
283
|
+
:key_signing_key_algorithm,
|
284
|
+
:kind,
|
285
|
+
:kms_key_name,
|
286
|
+
:label_fingerprint,
|
287
|
+
:label_value_by_key,
|
288
|
+
:labels_keys,
|
289
|
+
:labels_values,
|
290
|
+
:labels,
|
291
|
+
:last_attach_timestamp,
|
292
|
+
:last_detach_timestamp,
|
293
|
+
:last_modified_time,
|
294
|
+
:legacy_abac,
|
295
|
+
:licenses,
|
296
|
+
:lifecycle_state,
|
297
|
+
:load_balancing_scheme,
|
298
|
+
:local_traffic_selector,
|
299
|
+
:location,
|
300
|
+
:logging_service,
|
301
|
+
:machine_type,
|
302
|
+
:managed_zone,
|
303
|
+
:management,
|
304
|
+
:master_auth,
|
305
|
+
:members,
|
306
|
+
:metadata_keys,
|
307
|
+
:metadata_value_by_key,
|
308
|
+
:metadata_values,
|
309
|
+
:metadata,
|
310
|
+
:min_cpu_platform,
|
311
|
+
:monitoring_service,
|
312
|
+
:mutation_record,
|
313
|
+
:name_servers,
|
314
|
+
:name,
|
315
|
+
:named_ports,
|
316
|
+
:network_interfaces,
|
317
|
+
:network,
|
318
|
+
:next_hop_gateway,
|
319
|
+
:next_hop_instance,
|
320
|
+
:next_hop_ip,
|
321
|
+
:next_hop_network,
|
322
|
+
:next_hop_vpn_tunnel,
|
323
|
+
:next_rotation_time_date,
|
324
|
+
:next_rotation_time,
|
325
|
+
:node_config,
|
326
|
+
:node_ipv4_cidr_size,
|
327
|
+
:node_pools,
|
328
|
+
:num_bytes,
|
329
|
+
:num_long_term_bytes,
|
330
|
+
:num_rows,
|
331
|
+
:output_version_format,
|
332
|
+
:parent,
|
333
|
+
:peer_ip,
|
334
|
+
:physical_block_size_bytes,
|
335
|
+
:port_range,
|
336
|
+
:port,
|
337
|
+
:ports,
|
338
|
+
:primary_create_time,
|
339
|
+
:primary_create_time_date,
|
340
|
+
:primary_name,
|
341
|
+
:primary_state,
|
342
|
+
:priority,
|
343
|
+
:private_ip_google_access,
|
344
|
+
:private_key,
|
345
|
+
:profile,
|
346
|
+
:project_id,
|
347
|
+
:project_number,
|
348
|
+
:protocol,
|
349
|
+
:proxy_header,
|
350
|
+
:purpose,
|
351
|
+
:quic_override,
|
352
|
+
:quotas,
|
353
|
+
:raw_disk,
|
354
|
+
:raw_key,
|
355
|
+
:region_name,
|
356
|
+
:region,
|
357
|
+
:remote_traffic_selector,
|
358
|
+
:request_path,
|
359
|
+
:rotation_period,
|
360
|
+
:router,
|
361
|
+
:routing_config,
|
362
|
+
:runtime,
|
363
|
+
:scheduling,
|
364
|
+
:self_link,
|
365
|
+
:service_account_email,
|
366
|
+
:service_accounts,
|
367
|
+
:service,
|
368
|
+
:services_ipv4_cidr,
|
369
|
+
:session_affinity,
|
370
|
+
:sha256,
|
371
|
+
:shared_secret_hash,
|
372
|
+
:shared_secret,
|
373
|
+
:size_gb,
|
374
|
+
:source_archive_url,
|
375
|
+
:source_disk,
|
376
|
+
:source_image_encryption_key,
|
377
|
+
:source_image_id,
|
378
|
+
:source_image,
|
379
|
+
:source_ranges,
|
380
|
+
:source_snapshot_encryption_key,
|
381
|
+
:source_snapshot_id,
|
382
|
+
:source_snapshot,
|
383
|
+
:source_type,
|
384
|
+
:source_upload_url,
|
385
|
+
:ssl_certificates,
|
386
|
+
:ssl_policy,
|
387
|
+
:stage,
|
388
|
+
:start_restricted,
|
389
|
+
:status,
|
390
|
+
:storage_bytes,
|
391
|
+
:subnetwork,
|
392
|
+
:substitutions,
|
393
|
+
:table_id,
|
394
|
+
:table_reference,
|
395
|
+
:tags,
|
396
|
+
:target_pools,
|
397
|
+
:target_size,
|
398
|
+
:target_tags,
|
399
|
+
:target_vpn_gateway,
|
400
|
+
:target,
|
401
|
+
:timeout_sec,
|
402
|
+
:timeout,
|
403
|
+
:title,
|
404
|
+
:ttl,
|
405
|
+
:type,
|
406
|
+
:unhealthy_threshold,
|
407
|
+
:update_time,
|
408
|
+
:url_map,
|
409
|
+
:users,
|
410
|
+
:version_id,
|
411
|
+
:version,
|
412
|
+
:writer_identity,
|
413
|
+
:xpn_project_status,
|
414
|
+
:zone_signing_key_algorithm,
|
415
|
+
:zone
|
416
|
+
].freeze
|
417
|
+
|
418
|
+
# load the resource pack into InSpec::Resource.registry
|
419
|
+
def self.load_resource_pack(resource_path)
|
420
|
+
# find the libraries path in the resource pack
|
421
|
+
if resource_path.end_with?('libraries')
|
422
|
+
libpath = resource_path
|
423
|
+
else
|
424
|
+
libpath = resource_path+'/libraries'
|
425
|
+
end
|
426
|
+
$LOAD_PATH.push(libpath)
|
427
|
+
# find all the classes in the libpath and require them
|
428
|
+
# this adds them to the Inspec::Resource.registry
|
429
|
+
Dir.glob("#{libpath}/*.rb").each do |x|
|
430
|
+
begin
|
431
|
+
require(x)
|
432
|
+
rescue Exception =>e # rubocop:disable Lint/RescueException AWS is blowing up for some reason
|
433
|
+
puts e
|
434
|
+
end
|
435
|
+
end
|
436
|
+
@inspec_resources = Inspec::Resource.registry.keys
|
437
|
+
end
|
438
|
+
|
21
439
|
# there really should be some way to get this directly from InSpec's resources
|
22
|
-
def self.resource_properties(resource)
|
440
|
+
def self.resource_properties(resource, platform)
|
23
441
|
# remove the common methods, in theory only leaving only unique InSpec properties
|
24
|
-
inspec_properties = Inspec::Resource.registry[resource].instance_methods
|
442
|
+
inspec_properties = Inspec::Resource.registry[resource].instance_methods + ADDITIONAL_COMMON_PROPERTIES
|
443
|
+
inspec_properties -= REMOVED_COMMON_PROPERTIES
|
444
|
+
case platform
|
445
|
+
when 'aws'
|
446
|
+
inspec_properties -= InspecPlugins::Iggy::Platforms::AwsHelper::AWS_REMOVED_PROPERTIES[resource] unless InspecPlugins::Iggy::Platforms::AwsHelper::AWS_REMOVED_PROPERTIES[resource].nil?
|
447
|
+
when 'azure'
|
448
|
+
inspec_properties -= InspecPlugins::Iggy::Platforms::AzureHelper::AZURE_REMOVED_PROPERTIES[resource] unless InspecPlugins::Iggy::Platforms::AzureHelper::AZURE_REMOVED_PROPERTIES[resource].nil?
|
449
|
+
when 'gcp'
|
450
|
+
inspec_properties -= InspecPlugins::Iggy::Platforms::GcpHelper::GCP_REMOVED_PROPERTIES[resource] unless InspecPlugins::Iggy::Platforms::GcpHelper::GCP_REMOVED_PROPERTIES[resource].nil?
|
451
|
+
end
|
25
452
|
# get InSpec properties by method names
|
26
453
|
inspec_properties.collect!(&:to_s)
|
27
454
|
Inspec::Log.debug "InspecHelper.resource_properties #{resource} properties = #{inspec_properties}"
|
@@ -29,13 +456,21 @@ module InspecPlugins
|
|
29
456
|
inspec_properties
|
30
457
|
end
|
31
458
|
|
32
|
-
def self.tf_controls(title, generated_controls)
|
33
|
-
content = "#
|
459
|
+
def self.tf_controls(title, generated_controls, platform)
|
460
|
+
content = "title \"#{title}: generated by Iggy v#{Iggy::VERSION}\"\n"
|
34
461
|
|
35
|
-
content +=
|
462
|
+
content += InspecPlugins::Iggy::Platforms::AwsHelper.tf_controls if platform.eql?('aws')
|
36
463
|
|
37
464
|
# write all controls
|
38
|
-
|
465
|
+
generated_controls.flatten.each do |control|
|
466
|
+
if control.class.eql?(Inspec::Control)
|
467
|
+
content += control.to_ruby
|
468
|
+
content += "\n\n"
|
469
|
+
else # this is for embedded iterators in negative tests
|
470
|
+
content += control
|
471
|
+
end
|
472
|
+
end
|
473
|
+
content
|
39
474
|
end
|
40
475
|
|
41
476
|
def self.cfn_controls(title, generated_controls, stack)
|
@@ -58,25 +493,6 @@ module InspecPlugins
|
|
58
493
|
controls.gsub!(/\]\"/, '"]')
|
59
494
|
content + controls
|
60
495
|
end
|
61
|
-
|
62
|
-
# a hack for sure, finds common methods as proxy for InSpec properties
|
63
|
-
COMMON_PROPERTIES = Inspec::Resource.registry['aws_subnet'].instance_methods &
|
64
|
-
Inspec::Resource.registry['directory'].instance_methods
|
65
496
|
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
|
81
497
|
end
|
82
498
|
end
|