diff --git a/CHANGELOG.md b/CHANGELOG.md index 53f23d327..f04563626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,36 @@ # Change Log - + +## [v1.10.28](https://github.com/inspec/inspec-gcp/tree/v1.10.28) (2022-06-15) + +#### Merged Pull Requests +- RESOURCE-325-soc2-section-cc6-6-gcp [#411](https://github.com/inspec/inspec-gcp/pull/411) ([sa-progress](https://github.com/sa-progress)) + + +## [v1.10.27](https://github.com/inspec/inspec-gcp/tree/v1.10.27) (2022-05-19) + +#### Merged Pull Requests +- Do not raise an error when calling resource_id if @connection is nil [#416](https://github.com/inspec/inspec-gcp/pull/416) ([rbclark](https://github.com/rbclark)) + +## [v1.10.26](https://github.com/inspec/inspec-gcp/tree/v1.10.26) (2022-05-10) + +#### Merged Pull Requests +- RESOURCE-356 add-superclass-resource-id-method-for-gcp [#414](https://github.com/inspec/inspec-gcp/pull/414) ([sa-progress](https://github.com/sa-progress)) + +## [v1.10.25](https://github.com/inspec/inspec-gcp/tree/v1.10.25) (2022-05-06) + +#### Merged Pull Requests +- RESOURCE-37-sql added for sql operations [#412](https://github.com/inspec/inspec-gcp/pull/412) ([sa-progress](https://github.com/sa-progress)) + +## [v1.10.24](https://github.com/inspec/inspec-gcp/tree/v1.10.24) (2022-04-22) + +#### Merged Pull Requests +- RESOURCE-68 compute-global-public-delegated-prefixes [#413](https://github.com/inspec/inspec-gcp/pull/413) ([sa-progress](https://github.com/sa-progress)) + ## [v1.10.23](https://github.com/inspec/inspec-gcp/tree/v1.10.23) (2022-03-14) #### Merged Pull Requests - RESOURCE-55 region health check services [#401](https://github.com/inspec/inspec-gcp/pull/401) ([sa-progress](https://github.com/sa-progress)) - ## [v1.10.21](https://github.com/inspec/inspec-gcp/tree/v1.10.21) (2022-03-14) diff --git a/VERSION b/VERSION index 0ee4c08bf..24dfaf258 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.10.23 \ No newline at end of file +1.10.28 \ No newline at end of file diff --git a/docs/resources/google_compute_public_delegated_prefix.md b/docs/resources/google_compute_public_delegated_prefix.md new file mode 100644 index 000000000..1b015582b --- /dev/null +++ b/docs/resources/google_compute_public_delegated_prefix.md @@ -0,0 +1,46 @@ +--- +title: About the google_compute_public_delegated_prefix resource +platform: gcp +--- + +## Syntax +A `google_compute_public_delegated_prefix` is used to test a Google PublicDelegatedPrefix resource + +## Examples +``` +describe google_compute_public_delegated_prefix(project: 'chef-gcp-inspec', region: 'us-east1-b', name: 'test') do + it { should exist } +end +``` + +## Properties +Properties that can be accessed from the `google_compute_public_delegated_prefix` resource: + + + * `creation_timestamp`: Creation timestamp in RFC3339 text format.This field is deprecated. + + * `description`: An optional description of this resource. Provide this property when you create the resource. + + * `id`: The unique identifier for the resource. + + * `name`: Name of the resource. Provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression [a-z]([-a-z0-9]*[a-z0-9])? which means the first character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + + * `ip_cidr_range`: The IPv4 address range, in CIDR format, represented by this public delegated prefix. + + * `parent_prefix`: The value of requestId if you provided it in the request. Not present otherwise. + + * `is_live_migration`: If true, the prefix will be live migrated. + + * `fingerprint`: Fingerprint of this resource. A hash of the contents stored in this object. This field is used in optimistic locking. This field will be ignored when inserting a new PublicDelegatedPrefix. An up-to-date fingerprint must be provided in order to update the PublicDelegatedPrefix, otherwise the request will fail with error 412 conditionNotMet. To see the latest fingerprint, make a get() request to retrieve a PublicDelegatedPrefix. A base64-encoded string. + + * `status`: The status of the public delegated prefix, which can be one of following values: * INITIALIZING The public delegated prefix is being initialized and addresses cannot be created yet. * READY_TO_ANNOUNCE The public delegated prefix is a live migration prefix and is active. * ANNOUNCED The public delegated prefix is active. * DELETING The public delegated prefix is being deprovsioned. + Possible values: + * INITIALIZING + * READY_TO_ANNOUNCE + * ANNOUNCED + * DELETING + + +## GCP Permissions + +Ensure the [Compute Engine API](https://console.cloud.google.com/apis/library/compute.googleapis.com/) is enabled for the current project. diff --git a/docs/resources/google_compute_public_delegated_prefixes.md b/docs/resources/google_compute_public_delegated_prefixes.md new file mode 100644 index 000000000..9b3a258d0 --- /dev/null +++ b/docs/resources/google_compute_public_delegated_prefixes.md @@ -0,0 +1,36 @@ +--- +title: About the google_compute_public_delegated_prefixes resource +platform: gcp +--- + +## Syntax +A `google_compute_public_delegated_prefixes` is used to test a Google PublicDelegatedPrefix resource + +## Examples +``` +describe google_compute_public_delegated_prefixes(project: 'chef-gcp-inspec', region: 'us-east1-b') do + it { should exist } +end +``` + +## Properties +Properties that can be accessed from the `google_compute_public_delegated_prefixes` resource: + +See [google_compute_public_delegated_prefix.md](google_compute_public_delegated_prefix.md) for more detailed information + * `creation_timestamps`: an array of `google_compute_public_delegated_prefix` creation_timestamp + * `descriptions`: an array of `google_compute_public_delegated_prefix` description + * `ids`: an array of `google_compute_public_delegated_prefix` id + * `names`: an array of `google_compute_public_delegated_prefix` name + * `ip_cidr_ranges`: an array of `google_compute_public_delegated_prefix` ip_cidr_range + * `parent_prefixes`: an array of `google_compute_public_delegated_prefix` parent_prefix + * `is_live_migrations`: an array of `google_compute_public_delegated_prefix` is_live_migration + * `fingerprints`: an array of `google_compute_public_delegated_prefix` fingerprint + * `statuses`: an array of `google_compute_public_delegated_prefix` status + +## Filter Criteria +This resource supports all of the above properties as filter criteria, which can be used +with `where` as a block or a method. + +## GCP Permissions + +Ensure the [Compute Engine API](https://console.cloud.google.com/apis/library/compute.googleapis.com/) is enabled for the current project. diff --git a/docs/resources/google_sql_operation.md b/docs/resources/google_sql_operation.md new file mode 100644 index 000000000..3332ea838 --- /dev/null +++ b/docs/resources/google_sql_operation.md @@ -0,0 +1,77 @@ +--- +title: About the google_sql_operation resource +platform: gcp +--- + +## Syntax +A `google_sql_operation` is used to test a Google Operation resource + +## Examples +``` +describe google_sql_operation(project: 'chef-gcp-inspec', operation: 'e5c522f1-8391-4830-a8ff-ff1cc4a7b2a5') do + it { should exist } + its('name') { should eq 'e5c522f1-8391-4830-a8ff-ff1cc4a7b2a5' } + its('status') { should eq 'DONE' } + its('operation_type') { should eq 'CREATE' } +end + +describe google_sql_operation(project: 'chef-gcp-inspec', operation: 'nonexistant') do + it { should_not exist } +end +``` + +## Properties +Properties that can be accessed from the `google_sql_operation` resource: + + + * `user`: The email address of the user who initiated this operation. + + * `name`: An identifier that uniquely identifies the operation. You can use this identifier to retrieve the Operations resource that has information about the operation. + + * `status`: An Operation resource. For successful operations that return an Operation resource, only the fields relevant to the operation are populated in the resource. + Possible values: + * PENDING + * RUNNING + * DONE + * SQL_OPERATION_STATUS_UNSPECIFIED + + * `operation_type`: An Operation resource. For successful operations that return an Operation resource, only the fields relevant to the operation are populated in the resource. + Possible values: + * SQL_OPERATION_TYPE_UNSPECIFIED + * IMPORT + * EXPORT + * CREATE + * UPDATE + * DELETE + * RESTART + * BACKUP_VOLUME + * DELETE_VOLUME + * RESTORE_VOLUME + * INJECT_USER + * CLONE + * STOP_REPLICA + * START_REPLICA + * START_REPLICA + * CREATE_REPLICA + * CREATE_USER + * DELETE_USER + * UPDATE_USER + * CREATE_DATABASE + * DELETE_DATABASE + * CREATE_REPLICA + * UPDATE_DATABASE + * FAILOVER + * DELETE_BACKUP + * RECREATE_REPLICA + * TRUNCATE_LOG + * DEMOTE_MASTER + * MAINTENANCE + * RESCHEDULE_MAINTENANCE + * START_EXTERNAL_SYNC + + * `instance`: The name of the Cloud SQL instance. This does not include the project ID. + + +## GCP Permissions + +Ensure the [Cloud SQL Admin API](https://console.cloud.google.com/apis/library/sqladmin.googleapis.com/) is enabled for the current project. diff --git a/docs/resources/google_sql_operations.md b/docs/resources/google_sql_operations.md new file mode 100644 index 000000000..ac5974291 --- /dev/null +++ b/docs/resources/google_sql_operations.md @@ -0,0 +1,36 @@ +--- +title: About the google_sql_operations resource +platform: gcp +--- + +## Syntax +A `google_sql_operations` is used to test a Google Operation resource + +## Examples +``` + +describe google_sql_operations(project: 'chef-gcp-inspec', instance: 'my-database') do + it { should exist } + its('names') { should include 'e5c522f1-8391-4830-a8ff-ff1cc4a7b2a5' } + its('statuses') { should include 'DONE' } + its('operation_types') { should include 'CREATE' } +end +``` + +## Properties +Properties that can be accessed from the `google_sql_operations` resource: + +See [google_sql_operation.md](google_sql_operation.md) for more detailed information + * `users`: an array of `google_sql_operation` user + * `names`: an array of `google_sql_operation` name + * `statuses`: an array of `google_sql_operation` status + * `operation_types`: an array of `google_sql_operation` operation_type + * `instances`: an array of `google_sql_operation` instance + +## Filter Criteria +This resource supports all of the above properties as filter criteria, which can be used +with `where` as a block or a method. + +## GCP Permissions + +Ensure the [Cloud SQL Admin API](https://console.cloud.google.com/apis/library/sqladmin.googleapis.com/) is enabled for the current project. diff --git a/inspec.yml b/inspec.yml index e3a28bc72..a1d7e3a0e 100644 --- a/inspec.yml +++ b/inspec.yml @@ -4,7 +4,7 @@ maintainer: spaterson@chef.io,russell.seymour@turtlesystems.co.uk summary: This resource pack provides compliance resources_old_ignore for Google Cloud Platform copyright: spaterson@chef.io,russell.seymour@turtlesystems.co.uk copyright_email: spaterson@chef.io,russell.seymour@turtlesystems.co.uk -version: 1.10.23 +version: 1.10.28 license: Apache-2.0 inspec_version: '>= 4.7.3' supports: diff --git a/libraries/gcp_backend.rb b/libraries/gcp_backend.rb index b105c6bd3..bb15f9ab5 100644 --- a/libraries/gcp_backend.rb +++ b/libraries/gcp_backend.rb @@ -29,6 +29,10 @@ def failed_resource? @failed_resource end + def resource_id + @connection&.resource_id + end + # Intercept GCP exceptions def catch_gcp_errors yield @@ -248,9 +252,19 @@ def return_if_object(response) result = JSON.parse(response.body) raise_if_errors result, %w{error errors}, 'message' raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK) + fetch_id result result end + def fetch_id(result) + @resource_id = if result.key?('id') + result['id'] + else + result['name'] + end + end + attr_reader :resource_id + def raise_if_errors(response, err_path, msg_field) errors = self.class.navigate(response, err_path) raise_error(errors, msg_field) unless errors.nil? diff --git a/libraries/google_compute_firewall.rb b/libraries/google_compute_firewall.rb index d5925f936..c44f959ce 100644 --- a/libraries/google_compute_firewall.rb +++ b/libraries/google_compute_firewall.rb @@ -123,6 +123,86 @@ def denied_rdp? port_protocol_denied('3389') end + def allowed_dns? + port_protocol_allowed('53') || port_protocol_allowed('53', 'udp') + end + + def allowed_cifs? + port_protocol_allowed('445', 'udp') + end + + def allowed_ftp? + port_protocol_allowed('20') || port_protocol_allowed('21') + end + + def allowed_hdfs_name_node_service? + port_protocol_allowed('8020') + end + + def allowed_name_node_webui_service? + port_protocol_allowed('50070') || port_protocol_allowed('50470') + end + + def allowed_kibana? + port_protocol_allowed('5601') + end + + def allowed_mysql? + port_protocol_allowed('4333') || port_protocol_allowed('3306') + end + + def allowed_net_bios? + port_protocol_allowed('137', 'udp') || port_protocol_allowed('138', 'udp') + end + + def allowed_oracle? + port_protocol_allowed('1521') + end + + def allowed_postgre_sql? + port_protocol_allowed('5432') + end + + def allowed_rpc? + port_protocol_allowed('135') + end + + def allowed_sql_server? + port_protocol_allowed('1434') || port_protocol_allowed('1433') + end + + def allowed_smtp? + port_protocol_allowed('25') + end + + def allowed_windows_smb? + port_protocol_allowed('445') + end + + def allowed_vnc_server? + port_protocol_allowed('5900') + end + + def allowed_vnc_client? + port_protocol_allowed('5500') + end + + def allowed_telnet? + port_protocol_allowed('23') + end + + def allowed_oracle_auto_data_warehouse? + port_protocol_allowed('1522') + end + + def allowed_salt_master? + port_protocol_allowed('4505') || port_protocol_allowed('4506') + end + + def allowed_docker? + port_protocol_allowed('2375') || port_protocol_allowed('2376') + end + def allow_port_protocol?(port, protocol) port_protocol_allowed(port, protocol) end diff --git a/libraries/google_compute_public_delegated_prefix.rb b/libraries/google_compute_public_delegated_prefix.rb new file mode 100644 index 000000000..8d1e8646f --- /dev/null +++ b/libraries/google_compute_public_delegated_prefix.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: false + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- +require 'gcp_backend' + +# A provider to manage Compute Engine resources. +class ComputePublicDelegatedPrefix < GcpResourceBase + name 'google_compute_public_delegated_prefix' + desc 'PublicDelegatedPrefix' + supports platform: 'gcp' + + attr_reader :params + attr_reader :creation_timestamp + attr_reader :description + attr_reader :id + attr_reader :name + attr_reader :ip_cidr_range + attr_reader :parent_prefix + attr_reader :is_live_migration + attr_reader :fingerprint + attr_reader :status + + def initialize(params) + super(params.merge({ use_http_transport: true })) + @params = params + @fetched = @connection.fetch(product_url(params[:beta]), resource_base_url, params, 'Get') + parse unless @fetched.nil? + end + + def parse + @creation_timestamp = parse_time_string(@fetched['creationTimestamp']) + @description = @fetched['description'] + @id = @fetched['id'] + @name = @fetched['name'] + @ip_cidr_range = @fetched['ipCidrRange'] + @parent_prefix = @fetched['parentPrefix'] + @is_live_migration = @fetched['isLiveMigration'] + @fingerprint = @fetched['fingerprint'] + @status = @fetched['status'] + end + + # Handles parsing RFC3339 time string + def parse_time_string(time_string) + time_string ? Time.parse(time_string) : nil + end + + def exists? + !@fetched.nil? + end + + def to_s + "PublicDelegatedPrefix #{@params[:name]}" + end + + private + + def product_url(_ = nil) + 'https://compute.googleapis.com/compute/v1/' + end + + def resource_base_url + 'projects/{{project}}/regions/{{region}}/publicDelegatedPrefixes/{{name}}' + end +end diff --git a/libraries/google_compute_public_delegated_prefixes.rb b/libraries/google_compute_public_delegated_prefixes.rb new file mode 100644 index 000000000..e71a11715 --- /dev/null +++ b/libraries/google_compute_public_delegated_prefixes.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: false + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- +require 'gcp_backend' +class ComputePublicDelegatedPrefixs < GcpResourceBase + name 'google_compute_public_delegated_prefixes' + desc 'PublicDelegatedPrefix plural resource' + supports platform: 'gcp' + + attr_reader :table + + filter_table_config = FilterTable.create + + filter_table_config.add(:creation_timestamps, field: :creation_timestamp) + filter_table_config.add(:descriptions, field: :description) + filter_table_config.add(:ids, field: :id) + filter_table_config.add(:names, field: :name) + filter_table_config.add(:ip_cidr_ranges, field: :ip_cidr_range) + filter_table_config.add(:parent_prefixes, field: :parent_prefix) + filter_table_config.add(:is_live_migrations, field: :is_live_migration) + filter_table_config.add(:fingerprints, field: :fingerprint) + filter_table_config.add(:statuses, field: :status) + + filter_table_config.connect(self, :table) + + def initialize(params = {}) + super(params.merge({ use_http_transport: true })) + @params = params + @table = fetch_wrapped_resource('items') + end + + def fetch_wrapped_resource(wrap_path) + # fetch_resource returns an array of responses (to handle pagination) + result = @connection.fetch_all(product_url, resource_base_url, @params, 'Get') + return if result.nil? + + # Conversion of string -> object hash to symbol -> object hash that InSpec needs + converted = [] + result.each do |response| + next if response.nil? || !response.key?(wrap_path) + response[wrap_path].each do |hash| + hash_with_symbols = {} + hash.each_key do |key| + name, value = transform(key, hash) + hash_with_symbols[name] = value + end + converted.push(hash_with_symbols) + end + end + + converted + end + + def transform(key, value) + return transformers[key].call(value) if transformers.key?(key) + + [key.to_sym, value] + end + + def transformers + { + 'creationTimestamp' => ->(obj) { return :creation_timestamp, parse_time_string(obj['creationTimestamp']) }, + 'description' => ->(obj) { return :description, obj['description'] }, + 'id' => ->(obj) { return :id, obj['id'] }, + 'name' => ->(obj) { return :name, obj['name'] }, + 'ipCidrRange' => ->(obj) { return :ip_cidr_range, obj['ipCidrRange'] }, + 'parentPrefix' => ->(obj) { return :parent_prefix, obj['parentPrefix'] }, + 'isLiveMigration' => ->(obj) { return :is_live_migration, obj['isLiveMigration'] }, + 'fingerprint' => ->(obj) { return :fingerprint, obj['fingerprint'] }, + 'status' => ->(obj) { return :status, obj['status'] }, + } + end + + # Handles parsing RFC3339 time string + def parse_time_string(time_string) + time_string ? Time.parse(time_string) : nil + end + + private + + def product_url(_ = nil) + 'https://compute.googleapis.com/compute/v1/' + end + + def resource_base_url + 'projects/{{project}}/regions/{{region}}/publicDelegatedPrefixes' + end +end diff --git a/libraries/google_project_iam_binding.rb b/libraries/google_project_iam_binding.rb deleted file mode 100644 index a523c97c1..000000000 --- a/libraries/google_project_iam_binding.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: false - -# ---------------------------------------------------------------------------- -# -# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** -# -# ---------------------------------------------------------------------------- -# -# This file is automatically generated by Magic Modules and manual -# changes will be clobbered when the file is regenerated. -# -# Please read more about how to change this file in README.md and -# CONTRIBUTING.md located at the root of this package. -# -# ---------------------------------------------------------------------------- -require 'gcp_backend' -require 'google/iam/property/iam_policy_bindings' - -# A provider to manage Resource Manager IAM Binding resources. -class ProjectIamBinding < GcpResourceBase - name 'google_project_iam_binding' - desc 'Project Iam Binding' - supports platform: 'gcp' - - attr_reader :params - - attr_reader :condition - - def initialize(params) - super(params.merge({ use_http_transport: true })) - raise "Expected 'role' to be defined for iam_binding resource" unless params.key?(:role) - @params = params - @fetched = @connection.fetch(product_url, resource_base_url, params, 'Post', { 'options' => { 'requestedPolicyVersion' => 3 } }.to_json) - parse unless @fetched.nil? - end - - def parse - @bindings = GoogleInSpec::Iam::Property::IamPolicyBindingsArray.parse(@fetched['bindings'], to_s) - @bindings.each do |binding| - next if binding.role != params[:role] - if params[:condition] - # Control defines a condition, match via this condition - condition = params[:condition] - if condition[:title] && condition[:title] != binding&.condition&.title - next - end - if condition[:description] && condition[:description] != binding&.condition&.description - next - end - if condition[:expression] && condition[:expression] != binding&.condition&.expression - next - end - else - # No condition defined in controls, skip any binding with a condition - next unless binding.condition.title.nil? && binding.condition.description.nil? && binding.condition.expression.nil? - end - @members_list = binding.members - @condition = binding.condition - @iam_binding_exists = true - end - end - - def exists? - @iam_binding_exists - end - - def members - @members_list - end - - def to_s - "Project IamBinding #{@params[:project]} Role: #{@params[:role]}" - end - - private - - def product_url - 'https://cloudresourcemanager.googleapis.com/v1/' - end - - def resource_base_url - 'projects/{{project}}:getIamPolicy' - end -end diff --git a/libraries/google_sql_operation.rb b/libraries/google_sql_operation.rb new file mode 100644 index 000000000..c4b18e62b --- /dev/null +++ b/libraries/google_sql_operation.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: false + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- +require 'gcp_backend' + +# A provider to manage Cloud SQL resources. +class SQLOperation < GcpResourceBase + name 'google_sql_operation' + desc 'Operation' + supports platform: 'gcp' + + attr_reader :params + attr_reader :user + attr_reader :name + attr_reader :status + attr_reader :operation_type + attr_reader :instance + + def initialize(params) + super(params.merge({ use_http_transport: true })) + @params = params + @fetched = @connection.fetch(product_url(params[:beta]), resource_base_url, params, 'Get') + parse unless @fetched.nil? + end + + def parse + @user = @fetched['user'] + @name = @fetched['name'] + @status = @fetched['status'] + @operation_type = @fetched['operationType'] + @instance = @fetched['instance'] + end + + def exists? + !@fetched.nil? + end + + def to_s + "Operation #{@params[:operation]}" + end + + private + + def product_url(_ = nil) + 'https://sqladmin.googleapis.com/sql/v1beta4/' + end + + def resource_base_url + 'projects/{{project}}/operations/{{operation}}' + end +end diff --git a/libraries/google_sql_operations.rb b/libraries/google_sql_operations.rb new file mode 100644 index 000000000..fcab5609a --- /dev/null +++ b/libraries/google_sql_operations.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: false + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- +require 'gcp_backend' +class SQLOperations < GcpResourceBase + name 'google_sql_operations' + desc 'Operation plural resource' + supports platform: 'gcp' + + attr_reader :table + + filter_table_config = FilterTable.create + + filter_table_config.add(:users, field: :user) + filter_table_config.add(:names, field: :name) + filter_table_config.add(:statuses, field: :status) + filter_table_config.add(:operation_types, field: :operation_type) + filter_table_config.add(:instances, field: :instance) + + filter_table_config.connect(self, :table) + + def initialize(params = {}) + super(params.merge({ use_http_transport: true })) + @params = params + @table = fetch_wrapped_resource('items') + end + + def fetch_wrapped_resource(wrap_path) + # fetch_resource returns an array of responses (to handle pagination) + result = @connection.fetch_all(product_url, resource_base_url, @params, 'Get') + return if result.nil? + + # Conversion of string -> object hash to symbol -> object hash that InSpec needs + converted = [] + result.each do |response| + next if response.nil? || !response.key?(wrap_path) + response[wrap_path].each do |hash| + hash_with_symbols = {} + hash.each_key do |key| + name, value = transform(key, hash) + hash_with_symbols[name] = value + end + converted.push(hash_with_symbols) + end + end + + converted + end + + def transform(key, value) + return transformers[key].call(value) if transformers.key?(key) + + [key.to_sym, value] + end + + def transformers + { + 'user' => ->(obj) { return :user, obj['user'] }, + 'name' => ->(obj) { return :name, obj['name'] }, + 'status' => ->(obj) { return :status, obj['status'] }, + 'operationType' => ->(obj) { return :operation_type, obj['operationType'] }, + 'instance' => ->(obj) { return :instance, obj['instance'] }, + } + end + + private + + def product_url(_ = nil) + 'https://sqladmin.googleapis.com/sql/v1beta4/' + end + + def resource_base_url + 'projects/{{project}}/operations?instance={{instance}}' + end +end diff --git a/test/integration/configuration/mm-attributes.yml b/test/integration/configuration/mm-attributes.yml index bdc159624..33e456b90 100644 --- a/test/integration/configuration/mm-attributes.yml +++ b/test/integration/configuration/mm-attributes.yml @@ -490,25 +490,6 @@ sql_database_flag: allowed_string_values: ON requires_restart: true -image_family_views: - zone: us-central1-c - name: image-1 - source_type: RAW - status: READY - archive_size_bytes: 539099200 - disk_size_gb: 3 - family: test - -license_code: - name: akl-zone1-1353 - -region_instance_group: - name: instance-group-2 - region: us-central1 - size: 1 - named_port_name: 'port' - named_port_port: 80 - region_operation: name: operation-1641188435323-5d4a6f5b26934-9281422c-dce238f5 region: us-central1 @@ -534,3 +515,8 @@ zone_operation: public_delegated_prefix: name: test + +sql_operation: + name: e5c522f1-8391-4830-a8ff-ff1cc4a7b2a5 + status: DONE + progress: 100 \ No newline at end of file diff --git a/test/integration/verify/controls/google_access_context_manager_access_policy.rb b/test/integration/verify/controls/google_access_context_manager_access_policy.rb index ec1077e18..829155997 100644 --- a/test/integration/verify/controls/google_access_context_manager_access_policy.rb +++ b/test/integration/verify/controls/google_access_context_manager_access_policy.rb @@ -14,9 +14,9 @@ title 'Test GCP google_access_context_manager_access_policy resource.' -gcp_organization_id = input(:gcp_organization_id, input: gcp_organization_id, description: 'The identifier of the organization that is the parent of the perimeter') -gcp_enable_privileged_resources = input(:gcp_enable_privileged_resources, input:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.') -service_perimeter = input('service_perimeter', input: { +gcp_organization_id = input(:gcp_organization_id, value: gcp_organization_id, description: 'The identifier of the organization that is the parent of the perimeter') +gcp_enable_privileged_resources = input(:gcp_enable_privileged_resources, value:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.') +service_perimeter = input('service_perimeter', value: { "name": "restrict_all", "title": "restrict_all", "restricted_service": "storage.googleapis.com", diff --git a/test/integration/verify/controls/google_access_context_manager_service_perimeters.rb b/test/integration/verify/controls/google_access_context_manager_service_perimeters.rb index 73724d6df..8d600aafb 100644 --- a/test/integration/verify/controls/google_access_context_manager_service_perimeters.rb +++ b/test/integration/verify/controls/google_access_context_manager_service_perimeters.rb @@ -14,9 +14,9 @@ title 'Test GCP google_access_context_manager_service_perimeters resource.' -gcp_organization_id = input(:gcp_organization_id, input: gcp_organization_id, description: 'The identifier of the organization that is the parent of the perimeter') -gcp_enable_privileged_resources = input(:gcp_enable_privileged_resources, input:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.') -service_perimeter = input('service_perimeter', input: { +gcp_organization_id = input(:gcp_organization_id, value: 'gcp_organization_id', description: 'The identifier of the organization that is the parent of the perimeter') +gcp_enable_privileged_resources = input(:gcp_enable_privileged_resources, value:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.') +service_perimeter = input('service_perimeter', value: { "name": "restrict_all", "title": "restrict_all", "restricted_service": "storage.googleapis.com", diff --git a/test/integration/verify/controls/google_compute_public_delegated_prefix.rb b/test/integration/verify/controls/google_compute_public_delegated_prefix.rb new file mode 100644 index 000000000..c7e0e0e40 --- /dev/null +++ b/test/integration/verify/controls/google_compute_public_delegated_prefix.rb @@ -0,0 +1,28 @@ +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_compute_public_delegated_prefix resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +public_delegated_prefix = attribute('public_delegated_prefix', default: { + "name": "test" +}, description: 'PublicDelegatedPrefix resource in the given region') +control 'google_compute_public_delegated_prefix-1.0' do + impact 1.0 + title 'google_compute_public_delegated_prefix resource test' + + describe google_compute_public_delegated_prefix(project: gcp_project_id, region: 'us-east1-b', name: public_delegated_prefix['name']) do + it { should exist } + end +end diff --git a/test/integration/verify/controls/google_compute_public_delegated_prefixes.rb b/test/integration/verify/controls/google_compute_public_delegated_prefixes.rb new file mode 100644 index 000000000..119f535a2 --- /dev/null +++ b/test/integration/verify/controls/google_compute_public_delegated_prefixes.rb @@ -0,0 +1,28 @@ +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_compute_public_delegated_prefixes resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +public_delegated_prefix = attribute('public_delegated_prefix', default: { + "name": "test" +}, description: 'PublicDelegatedPrefix resource in the given region') +control 'google_compute_public_delegated_prefixes-1.0' do + impact 1.0 + title 'google_compute_public_delegated_prefixes resource test' + + describe google_compute_public_delegated_prefixes(project: gcp_project_id, region: 'us-east1-b') do + it { should exist } + end +end diff --git a/test/integration/verify/controls/google_sql_operation.rb b/test/integration/verify/controls/google_sql_operation.rb new file mode 100644 index 000000000..7c5da7c86 --- /dev/null +++ b/test/integration/verify/controls/google_sql_operation.rb @@ -0,0 +1,40 @@ +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_sql_operation resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +gcp_location = attribute(:gcp_location, default: 'gcp_location', description: 'The GCP project location.') +gcp_db_instance_name = attribute(:gcp_db_instance_name, default: 'gcp_db_instance_name', description: 'Database instance name.') +sql_operation = attribute('sql_operation', default: { + "name": "e5c522f1-8391-4830-a8ff-ff1cc4a7b2a5", + "status": "DONE", + "operation_type": "CREATE" +}, description: 'An Operation resource. For successful operations that return an Operation resource, only the fields relevant to the operation are populated in the resource.') + +control 'google_sql_operation-1.0' do + impact 1.0 + title 'google_sql_operation resource test' + + describe google_sql_operation(project: gcp_project_id, operation: sql_operation['name']) do + it { should exist } + its('name') { should eq sql_operation['name'] } + its('status') { should eq sql_operation['status'] } + its('operation_type') { should eq sql_operation['operation_type'] } + end + + describe google_sql_operation(project: gcp_project_id, operation: 'nonexistant') do + it { should_not exist } + end +end diff --git a/test/integration/verify/controls/google_sql_operations.rb b/test/integration/verify/controls/google_sql_operations.rb new file mode 100644 index 000000000..a8b84dfe4 --- /dev/null +++ b/test/integration/verify/controls/google_sql_operations.rb @@ -0,0 +1,37 @@ +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in README.md and +# CONTRIBUTING.md located at the root of this package. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_sql_operations resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +gcp_location = attribute(:gcp_location, default: 'gcp_location', description: 'The GCP project location.') +gcp_db_instance_name = attribute(:gcp_db_instance_name, default: 'gcp_db_instance_name', description: 'Database instance name.') +sql_operation = attribute('sql_operation', default: { + "name": "e5c522f1-8391-4830-a8ff-ff1cc4a7b2a5", + "status": "DONE", + "operation_type": "CREATE" +}, description: 'An Operation resource. For successful operations that return an Operation resource, only the fields relevant to the operation are populated in the resource.') + +control 'google_sql_operations-1.0' do + impact 1.0 + title 'google_sql_operations resource test' + + + describe google_sql_operations(project: gcp_project_id, instance: gcp_db_instance_name) do + it { should exist } + its('names') { should include sql_operation['name'] } + its('statuses') { should include sql_operation['status'] } + its('operation_types') { should include sql_operation['operation_type'] } + end +end