inspec-iggy 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -0,0 +1,42 @@
|
|
1
|
+
# helpers for working with InSpec-AWS profiles
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module InspecPlugins::Iggy::Platforms
|
6
|
+
class AwsHelper
|
7
|
+
# find the additional parameters
|
8
|
+
AWS_RESOURCE_QUALIFIERS = {
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
# the iterators for the various resource types
|
12
|
+
AWS_RESOURCE_ITERATORS = {
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
AWS_REMOVED_PROPERTIES = {
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
# Terraform boilerplate controls/controls.rb content
|
19
|
+
def self.tf_controls
|
20
|
+
"\n\naws_vpc_id = attribute('aws_vpc_id', default: '', description: 'Optional AWS VPC identifier.')\n\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
# readme content
|
24
|
+
def self.readme
|
25
|
+
end
|
26
|
+
|
27
|
+
# inspec.yml boilerplate content from
|
28
|
+
# inspec/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml
|
29
|
+
def self.inspec_yml
|
30
|
+
yml = {}
|
31
|
+
yml['inspec_version'] = '~> 4'
|
32
|
+
yml['depends'] = [{
|
33
|
+
'name' => 'inspec-aws',
|
34
|
+
'url' => 'https://github.com/inspec/inspec-aws/archive/master.tar.gz'
|
35
|
+
}]
|
36
|
+
yml['supports'] = [{
|
37
|
+
'platform' => 'aws'
|
38
|
+
}]
|
39
|
+
yml
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# helpers for working with InSpec-Azure profiles
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module InspecPlugins::Iggy::Platforms
|
6
|
+
class AzureHelper
|
7
|
+
# find the additional parameters
|
8
|
+
AZURE_RESOURCE_QUALIFIERS = {
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
# the iterators for the various resource types
|
12
|
+
AZURE_RESOURCE_ITERATORS = {
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
AZURE_REMOVED_PROPERTIES = {
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
# readme content
|
19
|
+
def self.readme
|
20
|
+
"\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
# inspec.yml boilerplate content from
|
24
|
+
# inspec/lib/plugins/inspec-init/templates/profiles/azure/inspec.yml
|
25
|
+
def self.inspec_yml
|
26
|
+
yml = {}
|
27
|
+
yml['inspec_version'] = '>= 2.2.7'
|
28
|
+
yml['depends'] = [{
|
29
|
+
'name' => 'inspec-azure',
|
30
|
+
'url' => 'https://github.com/inspec/inspec-azure/archive/master.tar.gz'
|
31
|
+
}]
|
32
|
+
yml['supports'] = [{
|
33
|
+
'platform' => 'azure'
|
34
|
+
}]
|
35
|
+
yml
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# helpers for working with InSpec-GCP profiles
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module InspecPlugins::Iggy::Platforms
|
6
|
+
class GcpHelper
|
7
|
+
# find the additional parameters for the 'describe'
|
8
|
+
GCP_RESOURCE_QUALIFIERS = {
|
9
|
+
'google_bigquery_dataset' => [:project, :name],
|
10
|
+
'google_bigquery_table' => [:project, :dataset, :name],
|
11
|
+
'google_cloudfunctions_cloud_function' => [:project, :location, :name],
|
12
|
+
'google_compute_address' => [:project, :location, :name],
|
13
|
+
'google_compute_autoscaler' => [:project, :zone, :name],
|
14
|
+
'google_compute_backend_bucket' => [:project, :name],
|
15
|
+
'google_compute_backend_service' => [:project, :name],
|
16
|
+
'google_compute_disk' => [:project, :name, :zone],
|
17
|
+
'google_compute_firewall' => [:project, :name],
|
18
|
+
'google_compute_forwarding_rule' => [:project, :region, :name],
|
19
|
+
'google_compute_global_address' => [:project, :name],
|
20
|
+
'google_compute_global_forwarding_rule' => [:project, :name],
|
21
|
+
'google_compute_health_check' => [:project, :name],
|
22
|
+
'google_compute_http_health_check' => [:project, :name],
|
23
|
+
'google_compute_https_health_check' => [:project, :name],
|
24
|
+
'google_compute_image' => [:project, :name],
|
25
|
+
'google_compute_instance' => [:project, :zone, :name],
|
26
|
+
'google_compute_instance_group' => [:project, :zone, :name],
|
27
|
+
'google_compute_instance_group_manager' => [:project, :zone, :name],
|
28
|
+
'google_compute_instance_template' => [:project, :name],
|
29
|
+
'google_compute_network' => [:project, :name],
|
30
|
+
'google_compute_project_info' => [:project],
|
31
|
+
'google_compute_region' => [:project, :name],
|
32
|
+
'google_compute_region_backend_service' => [:project, :region, :name],
|
33
|
+
'google_compute_region_instance_group_manager' => [:project, :region, :name],
|
34
|
+
'google_compute_route' => [:project, :name],
|
35
|
+
'google_compute_router' => [:project, :region, :name],
|
36
|
+
'google_compute_snapshot' => [:project, :name],
|
37
|
+
'google_compute_ssl_certificate' => [:project, :name],
|
38
|
+
'google_compute_ssl_policy' => [:project, :name],
|
39
|
+
'google_compute_subnetwork' => [:project, :region, :name],
|
40
|
+
'google_compute_subnetwork_iam_policy' => [:project, :region, :name],
|
41
|
+
'google_compute_target_http_proxy' => [:project, :name],
|
42
|
+
'google_compute_target_https_proxy' => [:project, :name],
|
43
|
+
'google_compute_target_pool' => [:project, :region, :name],
|
44
|
+
'google_compute_target_tcp_proxy' => [:project, :name],
|
45
|
+
'google_compute_url_map' => [:project, :name],
|
46
|
+
'google_compute_vpn_tunnel' => [:project, :region, :name],
|
47
|
+
'google_compute_zone' => [:project, :zone],
|
48
|
+
'google_container_cluster' => [:project, :zone, :name],
|
49
|
+
'google_container_node_pool' => [:project, :zone, :cluster_name, :nodepool_name],
|
50
|
+
'google_container_regional_cluster' => [:project, :location, :name],
|
51
|
+
'google_container_regional_node_pool' => [:project, :location, :cluster, :name],
|
52
|
+
'google_dns_managed_zone' => [:project, :zone],
|
53
|
+
'google_dns_resource_record_set' => [:project, :name, :type, :managed_zone],
|
54
|
+
'google_kms_crypto_key' => [:project, :location, :key_ring_name, :name],
|
55
|
+
'google_kms_crypto_key_iam_binding' => [:crypto_key_url, :role],
|
56
|
+
'google_kms_key_ring' => [:project, :location, :name],
|
57
|
+
'google_kms_key_ring_iam_binding' => [:key_ring_url, :role],
|
58
|
+
'google_logging_project_exclusion' => [:project, :exclusion],
|
59
|
+
'google_logging_project_sink' => [:project, :sink],
|
60
|
+
'google_organization' => [:display_name],
|
61
|
+
'google_organization_policy' => [:name, :constraints],
|
62
|
+
'google_project' => [:project],
|
63
|
+
'google_project_alert_policy' => [:policy],
|
64
|
+
'google_project_alert_policy_condition' => [:name, :filter],
|
65
|
+
'google_project_iam_binding' => [:project, :role],
|
66
|
+
'google_project_iam_custom_role' => [:project, :name],
|
67
|
+
'google_project_logging_audit_config' => [:project],
|
68
|
+
'google_project_metric' => [:project, :metric],
|
69
|
+
'google_pubsub_subscription' => [:project, :name],
|
70
|
+
'google_pubsub_subscription_iam_policy' => [:project, :name],
|
71
|
+
'google_pubsub_topic' => [:project, :name],
|
72
|
+
'google_pubsub_topic_iam_policy' => [:project, :name],
|
73
|
+
'google_resourcemanager_organization_policy' => [:organization_name, :constraint],
|
74
|
+
'google_service_account' => [:name],
|
75
|
+
'google_service_account_key' => [:name],
|
76
|
+
'google_sourcerepo_repository' => [:project, :name],
|
77
|
+
'google_sql_database_instance' => [:project, :database],
|
78
|
+
'google_storage_bucket' => [:name],
|
79
|
+
'google_storage_bucket_acl' => [:bucket, :entity],
|
80
|
+
'google_storage_bucket_iam_binding' => [:bucket, :role],
|
81
|
+
'google_storage_bucket_object' => [:bucket, :object],
|
82
|
+
'google_storage_default_object_acl' => [:bucket, :entity],
|
83
|
+
'google_storage_object_acl' => [:bucket, :object, :entity],
|
84
|
+
'google_user' => [:user_key]
|
85
|
+
}.freeze
|
86
|
+
|
87
|
+
# the iterators for the various resource types
|
88
|
+
GCP_RESOURCE_ITERATORS = {
|
89
|
+
# 'google_compute_disk' => { 'iterator' => 'google_compute_disks', 'index' => 'names', 'qualifiers' => [:project, :zone] }, # false positives because instance attached disks aren't managed by Terraform
|
90
|
+
# 'google_compute_network' => { 'iterator' => 'google_compute_networks', 'index' => 'network_names', 'qualifiers' => [:project] },
|
91
|
+
# 'google_compute_region' => { 'iterator' => 'google_compute_regions', 'index' => 'region_names', 'qualifiers' => [:project] },
|
92
|
+
# 'google_compute_region_instance_group_manager' => { 'iterator' => 'google_compute_region_instance_group_managers', 'index' => 'instance_group_names', 'qualifiers' => [:project, :region] }, verify it has 2 filter criteria
|
93
|
+
# 'google_compute_route' => { 'iterator' => 'google_compute_routes', 'index' => 'names', 'qualifiers' => [:project] },
|
94
|
+
# 'google_compute_subnetwork' => { 'iterator' => 'google_compute_subnetworks', 'index' => 'subnetwork_names', 'qualifiers' => [:project, :region] },
|
95
|
+
# 'google_compute_zone' => { 'iterator' => 'google_compute_zones', 'index' => 'zone_names', 'qualifiers' => [:project] },
|
96
|
+
# 'google_kms_crypto_key_iam_binding' => { 'iterator' => 'google_kms_crypto_key_iam_bindings', 'index' => 'iam_binding_roles', 'qualifiers' => [:crypto_key_url] },
|
97
|
+
# 'google_kms_key_ring' => { 'iterator' => 'google_kms_key_rings', 'index' => 'key_ring_names', 'qualifiers' => [:project, :location] },
|
98
|
+
# 'google_kms_key_ring_iam_binding' => { 'iterator' => 'google_kms_key_ring_iam_bindings', 'index' => 'iam_binding_roles', 'qualifiers' => [:key_ring_url] },
|
99
|
+
# 'google_organization' => { 'iterator' => 'google_organizations', 'index' => 'names', 'qualifiers' => [] }, # organizations are not managed by Terraform
|
100
|
+
# 'google_project' => { 'iterator' => 'google_projects', 'index' => 'project_names', 'qualifiers' => [] }, # projects are not managed by Terraform
|
101
|
+
# 'google_project_iam_binding' => { 'iterator' => 'google_project_iam_bindings', 'index' => 'iam_binding_roles', 'qualifiers' => [:project] },
|
102
|
+
'google_bigquery_dataset' => { 'iterator' => 'google_bigquery_datasets', 'index' => 'names', 'qualifiers' => [:project] },
|
103
|
+
'google_bigquery_table' => { 'iterator' => 'google_bigquery_tables', 'index' => 'table_references', 'qualifiers' => [:project, :dataset] },
|
104
|
+
'google_cloudbuild_trigger' => { 'iterator' => 'google_cloudbuild_triggers', 'index' => 'names', 'qualifiers' => [:project] },
|
105
|
+
'google_cloudfunctions_cloud_function' => { 'iterator' => 'google_cloudfunctions_cloud_functions', 'index' => 'names', 'qualifiers' => [:project, :location] },
|
106
|
+
'google_compute_autoscaler' => { 'iterator' => 'google_compute_autoscalers', 'index' => 'names', 'qualifiers' => [:project, :zone] },
|
107
|
+
'google_compute_backend_bucket' => { 'iterator' => 'google_compute_backend_buckets', 'index' => 'names', 'qualifiers' => [:project] },
|
108
|
+
'google_compute_backend_service' => { 'iterator' => 'google_compute_backend_services', 'index' => 'names', 'qualifiers' => [:project] },
|
109
|
+
'google_compute_firewall' => { 'iterator' => 'google_compute_firewalls', 'index' => 'firewall_names', 'qualifiers' => [:project] },
|
110
|
+
'google_compute_forwarding_rule' => { 'iterator' => 'google_compute_forwarding_rules', 'index' => 'forwarding_rule_names', 'qualifiers' => [:project, :region] },
|
111
|
+
'google_compute_health_check' => { 'iterator' => 'google_compute_health_checks', 'index' => 'names', 'qualifiers' => [:project] },
|
112
|
+
'google_compute_http_health_check' => { 'iterator' => 'google_compute_http_health_checks', 'index' => 'names', 'qualifiers' => [:project] },
|
113
|
+
'google_compute_https_health_check' => { 'iterator' => 'google_compute_https_health_checks', 'index' => 'names', 'qualifiers' => [:project] },
|
114
|
+
'google_compute_instance' => { 'iterator' => 'google_compute_instances', 'index' => 'instance_names', 'qualifiers' => [:project, :zone] },
|
115
|
+
'google_compute_instance_group' => { 'iterator' => 'google_compute_instance_groups', 'index' => 'instance_group_names', 'qualifiers' => [:project, :zone] },
|
116
|
+
'google_compute_instance_group_manager' => { 'iterator' => 'google_compute_instance_group_managers', 'index' => 'base_instance_names', 'qualifiers' => [:project, :zone] },
|
117
|
+
'google_compute_instance_template' => { 'iterator' => 'google_compute_instance_templates', 'index' => 'names', 'qualifiers' => [:project] },
|
118
|
+
'google_compute_router' => { 'iterator' => 'google_compute_routers', 'index' => 'names', 'qualifiers' => [:project, :region] },
|
119
|
+
'google_compute_snapshot' => { 'iterator' => 'google_compute_snapshots', 'index' => 'names', 'qualifiers' => [:project] },
|
120
|
+
'google_compute_ssl_certificate' => { 'iterator' => 'google_compute_ssl_certificates', 'index' => 'names', 'qualifiers' => [:project] },
|
121
|
+
'google_compute_ssl_policy' => { 'iterator' => 'google_compute_ssl_policies', 'index' => 'names', 'qualifiers' => [:project] },
|
122
|
+
'google_compute_target_http_proxy' => { 'iterator' => 'google_compute_target_http_proxies', 'index' => 'names', 'qualifiers' => [:project] },
|
123
|
+
'google_compute_target_https_proxy' => { 'iterator' => 'google_compute_target_https_proxies', 'index' => 'names', 'qualifiers' => [:project] },
|
124
|
+
'google_compute_target_pool' => { 'iterator' => 'google_compute_target_pools', 'index' => 'names', 'qualifiers' => [:project, :region] },
|
125
|
+
'google_compute_target_tcp_proxy' => { 'iterator' => 'google_compute_target_tcp_proxies', 'index' => 'names', 'qualifiers' => [:project] },
|
126
|
+
'google_compute_url_map' => { 'iterator' => 'google_compute_url_maps', 'index' => 'names', 'qualifiers' => [:project] },
|
127
|
+
'google_compute_vpn_tunnel' => { 'iterator' => 'google_compute_vpn_tunnels', 'index' => 'vpn_tunnel_names', 'qualifiers' => [:project, :region] },
|
128
|
+
'google_container_cluster' => { 'iterator' => 'google_container_clusters', 'index' => 'cluster_names', 'qualifiers' => [:project, :zone] },
|
129
|
+
'google_container_node_pool' => { 'iterator' => 'google_container_node_pools', 'index' => 'node_pool_names', 'qualifiers' => [:project, :zone, :cluster_name] },
|
130
|
+
'google_container_regional_cluster' => { 'iterator' => 'google_container_regional_clusters', 'index' => 'names', 'qualifiers' => [:project, :location] },
|
131
|
+
'google_dns_managed_zone' => { 'iterator' => 'google_dns_managed_zones', 'index' => 'zone_names', 'qualifiers' => [:project] },
|
132
|
+
'google_dns_resource_record_set' => { 'iterator' => 'google_dns_resource_record_sets', 'index' => 'names', 'qualifiers' => [:project, :managed_zone] },
|
133
|
+
'google_kms_crypto_key' => { 'iterator' => 'google_kms_crypto_keys', 'index' => 'crypto_key_names', 'qualifiers' => [:project, :location, :key_ring_name] },
|
134
|
+
'google_logging_project_sink' => { 'iterator' => 'google_logging_project_sinks', 'index' => 'sink_names', 'qualifiers' => [:project] },
|
135
|
+
'google_project_alert_policy' => { 'iterator' => 'google_project_alert_policies', 'index' => 'policy_names', 'qualifiers' => [:project] },
|
136
|
+
'google_project_metric' => { 'iterator' => 'google_project_metrics', 'index' => 'metric_names', 'qualifiers' => [:project] },
|
137
|
+
'google_pubsub_subscription' => { 'iterator' => 'google_pubsub_subscriptions', 'index' => 'names', 'qualifiers' => [:project] },
|
138
|
+
}.freeze
|
139
|
+
|
140
|
+
GCP_REMOVED_PROPERTIES = {
|
141
|
+
'google_compute_http_health_check' => [:self_link, :id, :creation_timestamp], # id: terraform has name not id, self_link: undocumented but broken, creation_timestamp api incompatibility
|
142
|
+
'google_compute_instance' => [:label_fingerprint, :machine_type, :min_cpu_platform, :zone], # label_fingerprint, machine_type, zone api incompatibility | min_cpu_platform undefined
|
143
|
+
'google_compute_instance_group' => [:zone], # zone api incompatibility issue
|
144
|
+
'google_compute_forwarding_rule' => [:backend_service, :ip_version, :network, :region, :subnetwork], # :backend_service, :ip_version, :network, :region, :subnetwork api incompatibility
|
145
|
+
'google_compute_target_pool' => [:backup_pool, :failover_ratio, :id, :region, :self_link], # api incompatibility
|
146
|
+
|
147
|
+
}.freeze
|
148
|
+
|
149
|
+
# readme content
|
150
|
+
def self.readme
|
151
|
+
end
|
152
|
+
|
153
|
+
# inspec.yml boilerplate content from
|
154
|
+
# inspec/lib/plugins/inspec-init/templates/profiles/gcp/inspec.yml
|
155
|
+
def self.inspec_yml
|
156
|
+
yml = {}
|
157
|
+
yml['inspec_version'] = '>= 2.3.5'
|
158
|
+
yml['depends'] = [{
|
159
|
+
'name' => 'inspec-gcp',
|
160
|
+
'url' => 'https://github.com/inspec/inspec-gcp/archive/master.tar.gz'
|
161
|
+
}]
|
162
|
+
yml['supports'] = [{
|
163
|
+
'platform' => 'gcp'
|
164
|
+
}]
|
165
|
+
yml
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -1,46 +1,64 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
# renders the profile from the parsed files
|
2
3
|
|
3
4
|
require 'yaml'
|
4
5
|
|
6
|
+
require 'inspec-iggy/platforms/aws_helper'
|
7
|
+
require 'inspec-iggy/platforms/azure_helper'
|
8
|
+
require 'inspec-iggy/platforms/gcp_helper'
|
9
|
+
|
5
10
|
module InspecPlugins
|
6
11
|
module Iggy
|
7
12
|
class ProfileHelper
|
8
13
|
# match the output of 'inspec init profile'
|
9
|
-
|
14
|
+
# inspec/lib/plugins/inspec-init/lib/inspec-init/renderer.rb
|
15
|
+
def self.render_profile(cli, options, source_file, controls, platform = nil)
|
10
16
|
name = options[:name]
|
11
17
|
overwrite_mode = options[:overwrite]
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
|
19
|
+
# --------------------------- InSpec Code Generator ---------------------------
|
20
|
+
cli.headline('InSpec Iggy Code Generator')
|
21
|
+
|
22
|
+
full_destination_path = Pathname.new(Dir.pwd).join(name)
|
23
|
+
|
24
|
+
if File.exist?(full_destination_path) && !overwrite_mode
|
25
|
+
cli.plain_line "#{cli.emphasis(full_destination_path)} exists already, use --overwrite"
|
26
|
+
cli.exit(1)
|
18
27
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
28
|
+
|
29
|
+
# ensure that full_destination_path directory is available
|
30
|
+
FileUtils.mkdir_p(full_destination_path)
|
31
|
+
|
32
|
+
# Creating new profile at /Users/mattray/ws/inspec-iggy/FOO
|
33
|
+
cli.plain_line "Creating new profile at #{cli.emphasis(full_destination_path)}"
|
34
|
+
# * Creating file README.md
|
35
|
+
render_readme_md(cli, name, source_file, platform)
|
36
|
+
# * Creating directory controls
|
37
|
+
cli.list_item "Creating directory #{cli.emphasis('controls')}"
|
23
38
|
FileUtils.mkdir_p("#{name}/controls")
|
24
|
-
|
25
|
-
|
26
|
-
|
39
|
+
# * Creating file controls/generated.rb
|
40
|
+
render_controls_rb(cli, name, controls)
|
41
|
+
# * Creating file inspec.yml
|
42
|
+
render_inspec_yml(cli, name, source_file, options, platform)
|
43
|
+
cli.plain_line
|
27
44
|
end
|
28
45
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
cli_ui.li "Create file #{cli_ui.mark_text(render_file)}"
|
33
|
-
f = File.new(render_file, 'w')
|
46
|
+
def self.render_readme_md(cli, name, source_file, platform)
|
47
|
+
cli.list_item "Creating file #{cli.emphasis('README.md')}"
|
48
|
+
f = File.new("#{name}/README.md", 'w')
|
34
49
|
f.puts("# #{name}")
|
35
50
|
f.puts
|
36
51
|
f.puts("This profile was generated by InSpec-Iggy v#{Iggy::VERSION} from the #{source_file} source file.")
|
52
|
+
|
53
|
+
f.puts(InspecPlugins::Iggy::Platforms::AwsHelper.readme) if platform.eql?('aws')
|
54
|
+
f.puts(InspecPlugins::Iggy::Platforms::AzureHelper.readme) if platform.eql?('azure')
|
55
|
+
f.puts(InspecPlugins::Iggy::Platforms::GcpHelper.readme) if platform.eql?('gcp')
|
56
|
+
|
37
57
|
f.close
|
38
58
|
end
|
39
59
|
|
40
|
-
|
41
|
-
|
42
|
-
render_file = "#{name}/inspec.yml"
|
43
|
-
cli_ui.li "Create file #{cli_ui.mark_text(render_file)}"
|
60
|
+
def self.render_inspec_yml(cli, name, source_file, options, platform)
|
61
|
+
cli.list_item "Creating file #{cli.emphasis('inspec.yml')}"
|
44
62
|
yml = {}
|
45
63
|
yml['name'] = name
|
46
64
|
yml['title'] = options[:title]
|
@@ -51,16 +69,19 @@ module InspecPlugins
|
|
51
69
|
yml['summary'] = options[:summary]
|
52
70
|
yml['version'] = options[:version]
|
53
71
|
yml['description'] = "Generated by InSpec-Iggy v#{Iggy::VERSION} from the #{source_file} source file."
|
54
|
-
|
72
|
+
|
73
|
+
yml.merge!(InspecPlugins::Iggy::Platforms::AwsHelper.inspec_yml) if platform.eql?('aws')
|
74
|
+
yml.merge!(InspecPlugins::Iggy::Platforms::AzureHelper.inspec_yml) if platform.eql?('azure')
|
75
|
+
yml.merge!(InspecPlugins::Iggy::Platforms::GcpHelper.inspec_yml) if platform.eql?('gcp')
|
76
|
+
|
77
|
+
f = File.new("#{name}/inspec.yml", 'w')
|
55
78
|
f.write(yml.to_yaml)
|
56
79
|
f.close
|
57
80
|
end
|
58
81
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
cli_ui.li "Create file #{cli_ui.mark_text(render_file)}"
|
63
|
-
f = File.new(render_file, 'w')
|
82
|
+
def self.render_controls_rb(cli, name, controls)
|
83
|
+
cli.list_item "Creating file #{cli.emphasis('controls/generated.rb')}"
|
84
|
+
f = File.new("#{name}/controls/generated.rb", 'w')
|
64
85
|
f.write(controls)
|
65
86
|
f.close
|
66
87
|
end
|
@@ -4,7 +4,8 @@ require 'inspec/plugin/v2'
|
|
4
4
|
|
5
5
|
require 'inspec-iggy/version'
|
6
6
|
require 'inspec-iggy/profile_helper'
|
7
|
-
require 'inspec-iggy/terraform/
|
7
|
+
require 'inspec-iggy/terraform/generate'
|
8
|
+
require 'inspec-iggy/terraform/negative'
|
8
9
|
|
9
10
|
module InspecPlugins::Iggy
|
10
11
|
module Terraform
|
@@ -20,71 +21,95 @@ module InspecPlugins::Iggy
|
|
20
21
|
say("Iggy v#{InspecPlugins::Iggy::VERSION}")
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
class_option :debug,
|
25
|
+
desc: 'Verbose debugging messages',
|
26
|
+
type: :boolean,
|
27
|
+
default: false
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
class_option :copyright,
|
30
|
+
desc: 'Name of the copyright holder',
|
31
|
+
default: 'The Authors'
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
class_option :email,
|
34
|
+
desc: 'Email address of the author',
|
35
|
+
default: 'you@example.com'
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
class_option :license,
|
38
|
+
desc: 'License for the profile',
|
39
|
+
default: 'Apache-2.0'
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
class_option :maintainer,
|
42
|
+
desc: 'Name of the copyright holder',
|
43
|
+
default: 'The Authors'
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
class_option :summary,
|
46
|
+
desc: 'One line summary for the profile',
|
47
|
+
default: 'An InSpec Compliance Profile'
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
class_option :title,
|
50
|
+
desc: 'Human-readable name for the profile',
|
51
|
+
default: 'InSpec Profile'
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
class_option :version,
|
54
|
+
desc: 'Specify the profile version',
|
55
|
+
default: '0.1.0'
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
class_option :overwrite,
|
58
|
+
desc: 'Overwrites existing profile directory',
|
59
|
+
type: :boolean,
|
60
|
+
default: false
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
class_option :name,
|
63
|
+
aliases: '-n',
|
64
|
+
required: true,
|
65
|
+
desc: 'Name of profile to be generated'
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
class_option :tfstate,
|
68
|
+
aliases: '-t',
|
69
|
+
desc: 'Specify path to the input terraform.tfstate',
|
70
|
+
default: 'terraform.tfstate'
|
71
|
+
|
72
|
+
class_option :platform,
|
73
|
+
desc: 'The InSpec platform providing the necessary resources (aws, azure, or gcp)'
|
74
|
+
|
75
|
+
class_option :resourcepath,
|
76
|
+
desc: 'Specify path to the InSpec Resource Pack providing the necessary resources'
|
70
77
|
|
71
78
|
desc 'generate [options]', 'Generate InSpec compliance controls from terraform.tfstate'
|
72
79
|
def generate
|
73
80
|
Inspec::Log.level = :debug if options[:debug]
|
74
|
-
|
75
|
-
|
76
|
-
|
81
|
+
platform = options[:platform]
|
82
|
+
resource_path = options[:resourcepath]
|
83
|
+
# require validation that if platform or resourcepath are passed, both are available
|
84
|
+
if platform or resource_path
|
85
|
+
unless platform and resource_path
|
86
|
+
error 'You must pass both --platform and --resourcepath if using either'
|
87
|
+
exit(1)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
generated_controls = InspecPlugins::Iggy::Terraform::Generate.parse_generate(options[:tfstate], resource_path, platform)
|
91
|
+
printable_controls = InspecPlugins::Iggy::InspecHelper.tf_controls(options[:title], generated_controls, platform)
|
92
|
+
InspecPlugins::Iggy::ProfileHelper.render_profile(ui, options, options[:tfstate], printable_controls, platform)
|
77
93
|
exit 0
|
78
94
|
end
|
79
95
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
96
|
+
desc 'negative [options]', 'Generate negative InSpec compliance controls from terraform.tfstate'
|
97
|
+
def negative
|
98
|
+
Inspec::Log.level = :debug if options[:debug]
|
99
|
+
platform = options[:platform]
|
100
|
+
resource_path = options[:resourcepath]
|
101
|
+
# require validation that if platform or resourcepath are passed, both are available
|
102
|
+
if platform or resource_path
|
103
|
+
unless platform and resource_path
|
104
|
+
error 'You must pass both --platform and --resourcepath if using either'
|
105
|
+
exit(1)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
negative_controls = InspecPlugins::Iggy::Terraform::Negative.parse_negative(options[:tfstate], resource_path, platform)
|
109
|
+
printable_controls = InspecPlugins::Iggy::InspecHelper.tf_controls(options[:title], negative_controls, platform)
|
110
|
+
InspecPlugins::Iggy::ProfileHelper.render_profile(ui, options, options[:tfstate], printable_controls, platform)
|
111
|
+
exit 0
|
112
|
+
end
|
88
113
|
end
|
89
114
|
end
|
90
115
|
end
|