diff --git a/docs/resources/google_compute_subnetworks.md b/docs/resources/google_compute_subnetworks.md
index 02a799664..553a0759b 100644
--- a/docs/resources/google_compute_subnetworks.md
+++ b/docs/resources/google_compute_subnetworks.md
@@ -64,13 +64,14 @@ The following examples show how to use this InSpec audit resource.
## Filter Criteria
-This resource supports the following filter criteria: `subnetwork_id`; `subnetwork_name` and `subnetwork_network`. Any of these may be used with `where`, as a block or as a method.
+This resource supports the following filter criteria: `subnetwork_id`; `subnetwork_name`; `enable_flow_logs` and `subnetwork_network`. Any of these may be used with `where`, as a block or as a method.
## Properties
* `subnetwork_ids` - an array of google_compute_subnetwork identifier integers
* `subnetwork_names` - an array of google_compute_subnetwork name strings
* `subnetwork_networks` - an array of google_compute_network name strings
+* `enable_flow_logs` - an array of enable_flow_log booleans
diff --git a/docs/resources/google_dns_managed_zone.md b/docs/resources/google_dns_managed_zone.md
new file mode 100644
index 000000000..2e523c163
--- /dev/null
+++ b/docs/resources/google_dns_managed_zone.md
@@ -0,0 +1,56 @@
+---
+title: About the google_dns_managed_zones Resource
+platform: gcp
+---
+
+# google\_dns\_managed\_zone
+
+Use the `google_dns_managed_zones` InSpec audit resource to test properties of a single GCP DNS managed zone.
+
+
+
+## Syntax
+
+A `google_dns_managed_zone` resource block declares the tests for a single GCP zone by project and name.
+
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: 'zone-name') do
+ it { should exist }
+ end
+
+
+
+## Examples
+
+The following examples show how to use this InSpec audit resource.
+
+### Test that a GCP compute zone exists
+
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: 'zone-name') do
+ it { should exist }
+ end
+
+### Test that a GCP DNS managed zone has the expected DNS name
+
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: 'zone-name') do
+ its('dns_name') { should match 'mydomain.com' }
+ end
+
+### Test that a GCP DNS managed zone has expected name server
+
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: 'zone-name') do
+ its('name_servers') { should include 'ns-cloud-d1.googledomains.com.' }
+ end
+
+
+
+
+## Properties
+
+* `creation_time`, `creation_time_date`, `description`, `dns_name`, `dnssec_config`, `id`, `kind`, `name`, `name_servers`, `key_signing_key_algorithm`, `zone_signing_key_algorithm`
+
+
+
+
+## GCP Permissions
+
+Ensure the [Cloud DNS API](https://console.cloud.google.com/apis/api/dns.googleapis.com/) is enabled for the project.
\ No newline at end of file
diff --git a/docs/resources/google_dns_managed_zones.md b/docs/resources/google_dns_managed_zones.md
new file mode 100644
index 000000000..cfcb3c7c1
--- /dev/null
+++ b/docs/resources/google_dns_managed_zones.md
@@ -0,0 +1,72 @@
+---
+title: About the google_dns_managed_zones Resource
+platform: gcp
+---
+
+# google\_dns\_managed\_zones
+
+Use the `google_dns_managed_zones` InSpec audit resource to test properties of all, or a filtered group of, GCP DNS managed zones for a project.
+
+
+
+## Syntax
+
+A `google_dns_managed_zones` resource block collects GCP zones by project then tests that group.
+
+ describe google_dns_managed_zones(project: 'chef-inspec-gcp') do
+ it { should exist }
+ end
+
+Use this InSpec resource to enumerate IDs then test in-depth using `google_dns_managed_zone`.
+
+ google_dns_managed_zones(project: 'chef-inspec-gcp').zone_names.each do |zone_name|
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: zone_name) do
+ it { should exist }
+ end
+ end
+
+
+
+## Examples
+
+The following examples show how to use this InSpec audit resource.
+
+### Test that there are no more than a specified number of zones available for the project
+
+ describe google_dns_managed_zones(project: 'chef-inspec-gcp') do
+ its('count') { should be <= 100}
+ end
+
+### Test that an expected, named managed zone is available for the project
+
+ describe google_dns_managed_zones(project: 'chef-inspec-gcp') do
+ its('zone_names') { should include "zone-name" }
+ end
+
+### Test that a subset of all zones matching "myzone*" exist
+
+ google_dns_managed_zones(project: 'chef-inspec-gcp').where(zone_name: /^myzone/).zone_names.each do |zone_name|
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: zone_name) do
+ it { should exist }
+ end
+ end
+
+
+
+## Filter Criteria
+
+This resource supports the following filter criteria: `zone_id`; `zone_name`; `zone_dns_name` and `dnssec_enabled`. Any of these may be used with `where`, as a block or as a method.
+
+## Properties
+
+* `zone_ids` - an array of google_dns_managed_zone identifier integers
+* `zone_names` - an array of google_dns_managed_zone name strings
+* `zone_dns_names` - an array of google_dns_managed_zone dns name strings
+* `dnssec_config_state`- an array of google_dns_managed_zone dnssec_config boolean values
+
+
+
+
+## GCP Permissions
+
+Ensure the [Cloud DNS API](https://console.cloud.google.com/apis/api/dns.googleapis.com/) is enabled for the project.
\ No newline at end of file
diff --git a/libraries/google_compute_firewall.rb b/libraries/google_compute_firewall.rb
index 3d6abddd3..20461ac96 100644
--- a/libraries/google_compute_firewall.rb
+++ b/libraries/google_compute_firewall.rb
@@ -39,6 +39,10 @@ def allowed_https?
port_protocol_allowed('443')
end
+ def allowed_rdp?
+ port_protocol_allowed('3389')
+ end
+
def allow_port_protocol?(port, protocol)
port_protocol_allowed(port, protocol)
end
diff --git a/libraries/google_compute_network.rb b/libraries/google_compute_network.rb
index 7c67051cc..c0d544ecc 100644
--- a/libraries/google_compute_network.rb
+++ b/libraries/google_compute_network.rb
@@ -27,6 +27,13 @@ def exists?
!@network.nil?
end
+ def legacy?
+ return false if @network.auto_create_subnetworks
+ return false if !defined?(@network.gateway_i_pv4)
+ return false if !defined?(@network.i_pv4_range)
+ true
+ end
+
def creation_timestamp_date
return false if !defined?(creation_timestamp)
Time.parse(creation_timestamp.to_s)
diff --git a/libraries/google_compute_subnetworks.rb b/libraries/google_compute_subnetworks.rb
index f587af8e9..c5e2af8a7 100644
--- a/libraries/google_compute_subnetworks.rb
+++ b/libraries/google_compute_subnetworks.rb
@@ -25,6 +25,7 @@ def initialize(opts = {})
filter_table_config.add(:subnetwork_ids, field: :subnetwork_id)
filter_table_config.add(:subnetwork_names, field: :subnetwork_name)
filter_table_config.add(:subnetwork_networks, field: :subnetwork_network)
+ filter_table_config.add(:enable_flow_logs, field: :enable_flow_log)
filter_table_config.connect(self, :fetch_data)
def fetch_data
@@ -36,9 +37,13 @@ def fetch_data
end
return [] if !@subnetworks || !@subnetworks.items
@subnetworks.items.map do |subnetwork|
+ catch_gcp_errors do
+ @flow_logs_enabled = !@gcp.gcp_compute_client.list_subnetworks(@project, @region, filter: "enableFlowLogs=true name=\"#{subnetwork.name}\"").items.nil?
+ end
subnetwork_rows+=[{ subnetwork_id: subnetwork.id,
subnetwork_name: subnetwork.name,
- subnetwork_network: subnetwork.network.split('/').last }]
+ subnetwork_network: subnetwork.network.split('/').last,
+ enable_flow_log: @flow_logs_enabled }]
end
next_page = @subnetworks.next_page_token
break unless next_page
diff --git a/libraries/google_dns_managed_zone.rb b/libraries/google_dns_managed_zone.rb
new file mode 100644
index 000000000..9b0edb05f
--- /dev/null
+++ b/libraries/google_dns_managed_zone.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'gcp_backend'
+
+module Inspec::Resources
+ class GoogleDnsManagedZone < GcpResourceBase
+ name 'google_dns_managed_zone'
+ desc 'Verifies settings for a GCP DNS managed zone'
+
+ example "
+ describe google_dns_managed_zone(project: 'chef-inspec-gcp', zone: 'zone-name') do
+ it { should exist }
+ end
+ "
+
+ def initialize(opts = {})
+ # Call the parent class constructor
+ super(opts)
+ @display_name = opts[:name]
+ catch_gcp_errors do
+ @managed_zone = @gcp.gcp_client(Google::Apis::DnsV2beta1::DnsService).get_managed_zone(opts[:project], opts[:zone])
+ create_resource_methods(@managed_zone)
+ @key_specs={}
+ if defined?(@managed_zone.dnssec_config.default_key_specs)
+ @managed_zone.dnssec_config.default_key_specs.each do |spec|
+ @key_specs[spec.key_type]=spec.algorithm
+ end
+ end
+ end
+ end
+
+ def exists?
+ !@managed_zone.nil?
+ end
+
+ def creation_time_date
+ return false if !defined?(@managed_zone.creation_time)
+ Time.parse(@managed_zone.creation_time)
+ end
+
+ def key_signing_key_algorithm
+ raise Inspec::Exceptions::ResourceFailed, "google_dns_managed_zone is missing expected property 'dnssec_config.default_key_specs'" if !@key_specs.key?('keySigning')
+ @key_specs['keySigning']
+ end
+
+ def zone_signing_key_algorithm
+ raise Inspec::Exceptions::ResourceFailed, "google_dns_managed_zone is missing expected property 'dnssec_config.default_key_specs'" if !@key_specs.key?('zoneSigning')
+ @key_specs['zoneSigning']
+ end
+
+ def to_s
+ "DNS Managed Zone #{@display_name}"
+ end
+ end
+end
diff --git a/libraries/google_dns_managed_zones.rb b/libraries/google_dns_managed_zones.rb
new file mode 100644
index 000000000..a66fe195f
--- /dev/null
+++ b/libraries/google_dns_managed_zones.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'gcp_backend'
+require 'google/apis/dns_v2beta1'
+
+module Inspec::Resources
+ class GoogleDnsManagedZones < GcpResourceBase
+ name 'google_dns_managed_zones'
+ desc 'Verifies settings for GCP DNS managed zones in bulk'
+
+ example "
+ describe google_dns_managed_zones(project: 'chef-inspec-gcp') do
+ it { should exist }
+ end
+ "
+
+ def initialize(opts = {})
+ # Call the parent class constructor
+ super(opts)
+ @project = opts[:project]
+ end
+
+ # FilterTable setup
+ filter_table_config = FilterTable.create
+ filter_table_config.add(:zone_ids, field: :zone_id)
+ filter_table_config.add(:zone_names, field: :zone_name)
+ filter_table_config.add(:zone_dns_names, field: :zone_dns_name)
+ filter_table_config.add(:dnssec_config_states, field: :dnssec_config_state)
+ filter_table_config.connect(self, :fetch_data)
+
+ def fetch_data
+ managed_zones = []
+ next_page = nil
+ loop do
+ catch_gcp_errors do
+ @managed_zones = @gcp.gcp_client(Google::Apis::DnsV2beta1::DnsService).list_managed_zones(@project, page_token: next_page)
+ end
+ return [] if !@managed_zones || !@managed_zones.managed_zones
+ @managed_zones.managed_zones.map do |zone|
+ dns_enabled=false
+ if defined?(zone.dnssec_config.state)
+ dns_enabled=true if zone.dnssec_config.state == 'on'
+ end
+ managed_zones+=[{ zone_id: zone.id,
+ zone_name: zone.name,
+ zone_dns_name: zone.dns_name,
+ dnssec_config_state: dns_enabled }]
+ end
+ next_page = @managed_zones.next_page_token
+ break unless next_page
+ end
+ @table = managed_zones
+ end
+ end
+end