-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #46 from inspec/add-regions
Add google_compute_region(s) resources, tests etc. and updated README.
- Loading branch information
Showing
10 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
title: About the google_compute_region Resource | ||
platform: gcp | ||
--- | ||
|
||
# google\_compute\_region | ||
|
||
Use the `google_compute_region` InSpec audit resource to test properties of a single GCP compute region. | ||
|
||
<br> | ||
|
||
## Syntax | ||
|
||
A `google_compute_region` resource block declares the tests for a single GCP region by project and name. | ||
|
||
describe google_compute_region(project: 'chef-inspec-gcp', region: 'us-east1-b') do | ||
its('name') { should match 'us-east1-b' } | ||
end | ||
|
||
<br> | ||
|
||
## Examples | ||
|
||
The following examples show how to use this InSpec audit resource. | ||
|
||
### Test that a GCP compute region exists | ||
|
||
describe google_compute_region(project: 'chef-inspec-gcp', region: 'europe-west2') do | ||
it { should exist } | ||
end | ||
|
||
### Test that a GCP compute region is in the expected state | ||
|
||
describe google_compute_region(project: 'chef-inspec-gcp', region: 'europe-west2') do | ||
its('status') { should eq 'UP' } | ||
# or equivalently | ||
it { should be_up } | ||
end | ||
|
||
### Test a GCP compute region identifier | ||
|
||
describe google_compute_region(project: 'chef-inspec-gcp', region: "asia-east1") do | ||
its('id') { should eq 1220 } | ||
end | ||
|
||
### Check that a region is associated with the expected zone fully qualified name | ||
|
||
describe google_compute_region(project: 'chef-inspec-gcp', region: "asia-east1") do | ||
its('zones') { should include "https://www.googleapis.com/compute/v1/projects/spaterson-project/zones/asia-east1-a" } | ||
end | ||
|
||
### Check that a region is associated with the expected zone short name | ||
|
||
describe google_compute_region(project: 'chef-inspec-gcp', region: "asia-east1") do | ||
its('zone_names') { should include "asia-east1-a" } | ||
end | ||
|
||
The `zone_names` property is also useful for subsequently looping over associated `google_compute_zone` resources. For example: | ||
|
||
google_compute_region(project: 'chef-inspec-gcp', region: "asia-east1").zone_names.each do |zone_name| | ||
describe google_compute_zone(project: 'chef-inspec-gcp', name: zone_name) do | ||
it { should be_up } | ||
end | ||
end | ||
|
||
<br> | ||
|
||
## Properties | ||
|
||
* `creation_timestamp`, `description`, `id`, `kind`, `name`, `quotas`, `status`, `zones`, `zone_names` | ||
|
||
<br> | ||
|
||
|
||
## GCP Permissions | ||
|
||
Ensure the [Compute Engine API](https://console.cloud.google.com/apis/library/compute.googleapis.com/) is enabled for the project where the resource is located. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
title: About the google_compute_regions Resource | ||
platform: gcp | ||
--- | ||
|
||
# google\_compute\_regions | ||
|
||
Use the `google_compute_regions` InSpec audit resource to test properties of all, or a filtered group of, GCP compute regions for a project. | ||
|
||
<br> | ||
|
||
## Syntax | ||
|
||
A `google_compute_regions` resource block collects GCP regions by project then tests that group. | ||
|
||
describe google_compute_regions(project: 'chef-inspec-gcp') do | ||
it { should exist } | ||
end | ||
|
||
Use this InSpec resource to enumerate IDs then test in-depth using `google_compute_region`. | ||
|
||
google_compute_regions(project: 'chef-inspec-gcp').region_names.each do |region_name| | ||
describe google_compute_region(project: 'chef-inspec-gcp', region: region_name) do | ||
it { should be_up } | ||
end | ||
end | ||
|
||
<br> | ||
|
||
## Examples | ||
|
||
The following examples show how to use this InSpec audit resource. | ||
|
||
### Test that there are more than a specified number of regions available for the project | ||
|
||
describe google_compute_regions(project: 'chef-inspec-gcp') do | ||
its('count') { should be >= 10} | ||
end | ||
|
||
### Test that an expected region is available for the project | ||
|
||
describe google_compute_regions(project: 'chef-inspec-gcp') do | ||
its('region_names') { should include 'europe-west2' } | ||
end | ||
|
||
### Test whether any regions are in status "DOWN" | ||
|
||
describe google_compute_regions(project: 'chef-inspec-gcp') do | ||
its('region_statuses') { should_not include "DOWN" } | ||
end | ||
|
||
### Test that a subset of all regions matching "europe*" are "UP" | ||
|
||
describe google_compute_regions(project: gcp_project_id).where(region_name: /^europe/).region_names.each do |region_name| | ||
describe google_compute_region(project: 'chef-inspec-gcp', region: region_name) do | ||
it { should be_up } | ||
end | ||
end | ||
|
||
<br> | ||
|
||
## Filter Criteria | ||
|
||
This resource supports the following filter criteria: `region_id`; `region_name` and `region_status`. Any of these may be used with `where`, as a block or as a method. | ||
|
||
## Properties | ||
|
||
* `region_ids` - an array of google_compute_region identifier integers | ||
* `region_names` - an array of google_compute_region name strings | ||
* `region_statuses`- an array of google_compute_region statuses | ||
|
||
<br> | ||
|
||
|
||
## GCP Permissions | ||
|
||
Ensure the [Compute Engine API](https://console.cloud.google.com/apis/library/compute.googleapis.com/) is enabled for the project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'gcp_backend' | ||
|
||
module Inspec::Resources | ||
class GoogleComputeRegion < GcpResourceBase | ||
name 'google_compute_region' | ||
desc 'Verifies settings for a region' | ||
|
||
example " | ||
describe google_compute_region(project: 'chef-inspec-gcp', region: 'europe-west2') do | ||
it { should exist } | ||
end | ||
" | ||
|
||
def initialize(opts = {}) | ||
# Call the parent class constructor | ||
super(opts) | ||
@display_name = opts[:name] | ||
catch_gcp_errors do | ||
@region = @gcp.gcp_compute_client.get_region(opts[:project], opts[:name]) | ||
create_resource_methods(@region) | ||
end | ||
end | ||
|
||
# helper for returning a list of zone short names rather than fully qualified URLs e.g. | ||
# https://www.googleapis.com/compute/v1/projects/spaterson-project/zones/asia-east1-a | ||
def zone_names | ||
return false if !defined?(@region.zones) | ||
@region.zones.map { |zone| zone.split('/').last } | ||
end | ||
|
||
def exists? | ||
!@region.nil? | ||
end | ||
|
||
def up? | ||
return false if !defined?(status) | ||
status == 'UP' | ||
end | ||
|
||
def to_s | ||
"Region #{@display_name}" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'gcp_backend' | ||
|
||
module Inspec::Resources | ||
class GoogleComputeRegions < GcpResourceBase | ||
name 'google_compute_regions' | ||
desc 'Verifies settings for GCP compute regions in bulk' | ||
|
||
example " | ||
describe google_compute_regions(project: 'chef-inspec-gcp') do | ||
it { should exist } | ||
... | ||
end | ||
" | ||
|
||
def initialize(opts = {}) | ||
# Call the parent class constructor | ||
super(opts) | ||
@display_name = opts[:name] | ||
@project = opts[:project] | ||
end | ||
|
||
# FilterTable setup | ||
filter_table_config = FilterTable.create | ||
filter_table_config.add(:region_ids, field: :region_id) | ||
filter_table_config.add(:region_names, field: :region_name) | ||
filter_table_config.add(:region_statuses, field: :region_status) | ||
filter_table_config.connect(self, :fetch_data) | ||
|
||
def fetch_data | ||
region_rows = [] | ||
catch_gcp_errors do | ||
# could paginate here but there are currently 17 regions and the limit on the below call is 500 | ||
@regions = @gcp.gcp_compute_client.list_regions(@project) | ||
end | ||
return [] if !@regions || !@regions.items | ||
@regions.items.map do |region| | ||
region_rows+=[{ region_id: region.id, | ||
region_name: region.name, | ||
region_status: region.status }] | ||
end | ||
@table = region_rows | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
title 'Test single GCP Region' | ||
|
||
gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.') | ||
gcp_region = attribute(:gcp_location, default: '', description: 'The GCP region being used.') | ||
|
||
control 'gcp-single-region-1.0' do | ||
|
||
impact 1.0 | ||
title 'Ensure single region has the correct properties.' | ||
|
||
describe google_compute_region(project: gcp_project_id, name: gcp_region) do | ||
it { should exist } | ||
it { should be_up } | ||
its('zone_names') { should include "#{gcp_region}-a" } | ||
end | ||
end |
16 changes: 16 additions & 0 deletions
16
test/integration/verify/controls/google_compute_region_zones_loop.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
title 'Loop over all zones in a GCP region' | ||
|
||
gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.') | ||
gcp_region = attribute(:gcp_location, default: '', description: 'The GCP region being used.') | ||
|
||
control 'gcp-region-zones-loop-1.0' do | ||
|
||
impact 1.0 | ||
title 'Ensure all zones in a region are available using google_compute_zone for detail.' | ||
|
||
google_compute_region(project: gcp_project_id, name: gcp_region).zone_names.each do |zone_name| | ||
describe google_compute_zone(project: gcp_project_id, name: zone_name) do | ||
it { should be_up } | ||
end | ||
end | ||
end |
20 changes: 20 additions & 0 deletions
20
test/integration/verify/controls/google_compute_regions.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
title 'Regions Properties' | ||
|
||
gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.') | ||
gcp_region = attribute(:gcp_location, default: '', description: 'The GCP region being used.') | ||
gcp_region_id = attribute(:gcp_region_id, default: '', description: 'A sample region identifier to test for.') | ||
|
||
control 'gcp-regions-1.0' do | ||
|
||
impact 1.0 | ||
title 'Ensure regions have the correct properties in bulk' | ||
|
||
describe google_compute_regions(project: gcp_project_id) do | ||
it { should exist } | ||
its('count') { should be <= 100} # 17 at the time of writing | ||
its('region_names') { should include gcp_region } | ||
its('region_statuses') { should_not include "DOWN" } | ||
its('region_ids') { should include gcp_region_id.to_i } | ||
end | ||
|
||
end |
15 changes: 15 additions & 0 deletions
15
test/integration/verify/controls/google_compute_regions_loop.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
title 'Loop over all GCP Regions' | ||
|
||
gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.') | ||
|
||
control 'gcp-regions-loop-1.0' do | ||
|
||
impact 1.0 | ||
title 'Ensure regions have the correct properties in bulk using google_compute_region for detail.' | ||
|
||
google_compute_regions(project: gcp_project_id).region_names.each do |region_name| | ||
describe google_compute_region(project: gcp_project_id, name: region_name) do | ||
it { should be_up } | ||
end | ||
end | ||
end |