From 88d43aa7ce8571f5b905f7716e31b7ae9b770d89 Mon Sep 17 00:00:00 2001 From: Stuart Paterson Date: Thu, 6 Sep 2018 16:04:37 +0100 Subject: [PATCH] Added google_sql_database_instance(s) resources, docs, tests, tf. Updated docs in zones. Signed-off-by: Stuart Paterson --- docs/resources/google_compute_zones.md | 2 +- .../resources/google_sql_database_instance.md | 69 +++++++++++++++ .../google_sql_database_instances.md | 88 +++++++++++++++++++ libraries/google_sql_database_instance.rb | 35 ++++++++ libraries/google_sql_database_instances.rb | 45 ++++++++++ test/integration/build/gcp.tf | 1 + .../controls/google_sql_database_instance.rb | 17 ++++ .../controls/google_sql_database_instances.rb | 17 ++++ 8 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 docs/resources/google_sql_database_instance.md create mode 100644 docs/resources/google_sql_database_instances.md create mode 100644 libraries/google_sql_database_instance.rb create mode 100644 libraries/google_sql_database_instances.rb create mode 100644 test/integration/verify/controls/google_sql_database_instance.rb create mode 100644 test/integration/verify/controls/google_sql_database_instances.rb diff --git a/docs/resources/google_compute_zones.md b/docs/resources/google_compute_zones.md index 688135e03..63253c532 100644 --- a/docs/resources/google_compute_zones.md +++ b/docs/resources/google_compute_zones.md @@ -59,7 +59,7 @@ The following examples show how to use this InSpec audit resource. ### Test that a subset of all zones matching "us*" are "UP" - describe google_compute_zones(project: gcp_project_id).where(zone_name: /^us/).zone_names.each do |zone_name| + google_compute_zones(project: 'chef-inspec-gcp').where(zone_name: /^us/).zone_names.each do |zone_name| describe google_compute_zone(project: 'chef-inspec-gcp', zone: zone_name) do it { should exist } its('kind') { should eq "compute#zone" } diff --git a/docs/resources/google_sql_database_instance.md b/docs/resources/google_sql_database_instance.md new file mode 100644 index 000000000..1463bca24 --- /dev/null +++ b/docs/resources/google_sql_database_instance.md @@ -0,0 +1,69 @@ +--- +title: About the google_sql_database_instance Resource +platform: gcp +--- + +# google\_sql\_database\_instance + +Use the `google_sql_database_instance` InSpec audit resource to test properties of a single GCP Cloud SQL Database instance. + +
+ +## Syntax + +A `google_sql_database_instance` resource block declares the tests for a single CP Cloud SQL Database instance by project and name. + + describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do + it { should exist } + end + +
+ +## Examples + +The following examples show how to use this InSpec audit resource. + + +### Test that a GCP Cloud SQL Database instance is in the expected state + + describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do + its('state') { should eq 'RUNNABLE' } + end + +### Test that a GCP Cloud SQL Database instance generation type + + describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do + its('backend_type') { should eq "SECOND_GEN" } + end + +### Test that a GCP Cloud SQL Database instance connection name is as expected + + describe google_sql_database_instance(project: 'spaterson-project', database: 'gcp-inspec-db-instance') do + its('connection_name') { should eq "spaterson-project:europe-west2:gcp-inspec-db-instance" } + end + +### Confirm that a GCP Cloud SQL Database instance has the correct version + + describe google_sql_database_instance(project: 'spaterson-project', database: 'gcp-inspec-db-instance') do + its('database_version') { should eq "MYSQL_5_7" } + end + +### Confirm that a GCP Cloud SQL Database instance is running in the desired region and zone + + describe google_sql_database_instance(project: 'spaterson-project', database: 'gcp-inspec-db-instance') do + its('gce_zone') { should eq "europe-west2-a" } + its('region') { should eq "europe-west2" } + end + +
+ +## Properties + +* `backend_type`, `connection_name`, `database_version`, `etag`, `gce_zone`, `instance_type`, `ip_addresses`, `kind`, `name`, `project`, `region`, `server_ca_cert`, `service_account_email_address`, `settings`, `state` + +
+ + +## GCP Permissions + +Ensure the [Cloud SQL API](https://console.cloud.google.com/projectselector/apis/api/sqladmin.googleapis.com/overview) is enabled for the project. \ No newline at end of file diff --git a/docs/resources/google_sql_database_instances.md b/docs/resources/google_sql_database_instances.md new file mode 100644 index 000000000..cbde25c83 --- /dev/null +++ b/docs/resources/google_sql_database_instances.md @@ -0,0 +1,88 @@ +--- +title: About the google_sql_database_instances Resource +platform: gcp +--- + +# google\_sql\_database\_instances + +Use the `google_sql_database_instances` InSpec audit resource to test properties of GCP Cloud SQL Database instances. + +
+ +## Syntax + +A `google_sql_database_instances` resource block collects GCP zones by project then tests that group. + + describe google_sql_database_instances(project: 'chef-inspec-gcp') do + it { should exist } + end + +Use this InSpec resource to enumerate IDs then test in-depth using `google_sql_database_instance`. + + google_sql_database_instances(project: 'chef-inspec-gcp').instance_names.each do |instance_name| + describe google_sql_database_instance(project: 'chef-inspec-gcp', database: instance_name) do + it { should exist } + its('backend_type') { should eq "SECOND_GEN" } + 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_sql_database_instances(project: 'chef-inspec-gcp') do + its('count') { should be <= 100} + end + + +### Test that a database instance exists in the expected zone + + describe google_sql_database_instances(project: 'chef-inspec-gcp') do + its('instance_zones') { should include "us-east1-b" } + end + +### Test that a database instance exists in the expected region + + describe google_sql_database_instances(project: 'chef-inspec-gcp') do + its('instance_regions') { should include "us-east1" } + end + + +### Confirm that at least one database instance is in "RUNNABLE" state + + describe google_sql_database_instances(project: 'chef-inspec-gcp') do + its('instance_states') { should include "RUNNABLE" } + end + +### Test that a subset of all database instances matching "*mysqldb*" are all version "MYSQL_5_7" + + google_sql_database_instances(project: 'chef-inspec-gcp').where(instance_name: /mysqldb/).instance_names.each do |instance_name| + describe google_sql_database_instance(project: 'chef-inspec-gcp', database: instance_name) do + it { should exist } + its('database_version') { should eq "MYSQL_5_7" } + end + end + +
+ +## Filter Criteria + +This resource supports the following filter criteria: `instance_name`; `instance_region`; `instance_zone` and `instance_state`. Any of these may be used with `where`, as a block or as a method. + +## Properties + +* `instance_names` - an array of google_sql_database_instance name strings +* `instance_regions`- an array of google_compute_region name strings +* `instance_zones`- an array of google_sql_database_instance name strings +* `instance_states`- an array of google_sql_database_instance state strings + +
+ + +## 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. \ No newline at end of file diff --git a/libraries/google_sql_database_instance.rb b/libraries/google_sql_database_instance.rb new file mode 100644 index 000000000..d64b4a114 --- /dev/null +++ b/libraries/google_sql_database_instance.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'gcp_backend' +require 'google/apis/sqladmin_v1beta4' + +module Inspec::Resources + class GoogleCloudSqlDatabaseInstance < GcpResourceBase + name 'google_sql_database_instance' + desc 'Verifies settings for a GCP Cloud SQL Database instance' + + example " + describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do + it { should exist } + end + " + + def initialize(opts = {}) + # Call the parent class constructor + super(opts) + @display_name = opts[:database] + catch_gcp_errors do + @database = @gcp.gcp_client(Google::Apis::SqladminV1beta4::SQLAdminService).get_instance(opts[:project], opts[:database]) + create_resource_methods(@database) + end + end + + def exists? + !@database.nil? + end + + def to_s + "Database #{@display_name}" + end + end +end diff --git a/libraries/google_sql_database_instances.rb b/libraries/google_sql_database_instances.rb new file mode 100644 index 000000000..e1e3ee8eb --- /dev/null +++ b/libraries/google_sql_database_instances.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'gcp_backend' + +module Inspec::Resources + class GoogleCloudSqlDatabaseInstances < GcpResourceBase + name 'google_sql_database_instances' + desc 'Verifies settings for GCP Cloud SQL Database instances in bulk' + + example " + describe google_sql_database_instances(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(:instance_names, field: :instance_name) + filter_table_config.add(:instance_regions, field: :instance_region) + filter_table_config.add(:instance_zones, field: :instance_zone) + filter_table_config.add(:instance_states, field: :instance_state) + filter_table_config.connect(self, :fetch_data) + + def fetch_data + instance_rows = [] + catch_gcp_errors do + @databases = @gcp.gcp_client(Google::Apis::SqladminV1beta4::SQLAdminService).list_instances(opts[:project]) + end + return [] if !@databases || !@databases.items + @databases.items.map do |instance| + instance_rows+=[{ instance_name: instance.name, + instance_region: instance.region, + instance_zone: instance.gce_zone, + instance_state: instance.state }] + end + @databases = instance_rows + end + end +end diff --git a/test/integration/build/gcp.tf b/test/integration/build/gcp.tf index f413e834e..5f92442a9 100644 --- a/test/integration/build/gcp.tf +++ b/test/integration/build/gcp.tf @@ -784,6 +784,7 @@ resource "google_sql_database" "cloud-sql-db-name" { } resource "google_sql_user" "cloud-sql-db-user" { + project = "${var.gcp_project_id}" name = "${var.gcp_db_user_name}" instance = "${google_sql_database_instance.cloud-sql-db-instance.name}" password = "${var.gcp_db_user_password}" diff --git a/test/integration/verify/controls/google_sql_database_instance.rb b/test/integration/verify/controls/google_sql_database_instance.rb new file mode 100644 index 000000000..a75a86d5d --- /dev/null +++ b/test/integration/verify/controls/google_sql_database_instance.rb @@ -0,0 +1,17 @@ +title 'Test single GCP Cloud SQL Database instance' + +gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.') +gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '', description: 'The GCP DB instance name.') + +control 'gcp-db-instance-1.0' do + + impact 1.0 + title 'Ensure GCP Cloud SQL Database instance has the correct properties.' + + describe google_sql_database_instance(project: gcp_project_id, database: gcp_db_instance_name) do + it { should exist } + its('state') { should eq 'RUNNABLE' } + its('backend_type') { should eq 'SECOND_GEN' } + its('database_version') { should eq 'MYSQL_5_7' } + end +end \ No newline at end of file diff --git a/test/integration/verify/controls/google_sql_database_instances.rb b/test/integration/verify/controls/google_sql_database_instances.rb new file mode 100644 index 000000000..a886b8e40 --- /dev/null +++ b/test/integration/verify/controls/google_sql_database_instances.rb @@ -0,0 +1,17 @@ +title 'GCP Cloud SQL Database Instances Properties' + +gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.') +gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '', description: 'The GCP DB instance name.') + +control 'gcp-db-instances-1.0' do + + impact 1.0 + title 'Ensure GCP Cloud SQL Database instances have the correct properties in bulk' + + describe google_sql_database_instances(project: gcp_project_id) do + its('count') { should be <= 100} + its('instance_states') { should include 'RUNNABLE' } + its('instance_names') { should include gcp_db_instance_name } + end + +end \ No newline at end of file