From dd879cc27173315f7029b75e714b0c4d9da46128 Mon Sep 17 00:00:00 2001 From: Experience Coder Date: Tue, 27 Aug 2019 19:14:29 +0000 Subject: [PATCH] GCP Inspec for Standard Application Version Signed-off-by: Modular Magician --- docs/resources/google_appengine_service.md | 30 +++++ docs/resources/google_appengine_services.md | 30 +++++ .../google_appengine_standard_app_version.md | 79 +++++++++++++ .../google_appengine_standard_app_versions.md | 39 +++++++ .../property/standardappversion_deployment.rb | 39 +++++++ .../standardappversion_deployment_files.rb | 37 +++++++ .../standardappversion_deployment_zip.rb | 37 +++++++ .../property/standardappversion_entrypoint.rb | 34 ++++++ .../property/standardappversion_handlers.rb | 62 +++++++++++ .../standardappversion_handlers_script.rb | 34 ++++++ ...tandardappversion_handlers_static_files.rb | 52 +++++++++ .../property/standardappversion_libraries.rb | 45 ++++++++ libraries/google_appengine_service.rb | 62 +++++++++++ libraries/google_appengine_services.rb | 86 +++++++++++++++ .../google_appengine_standard_app_version.rb | 86 +++++++++++++++ .../google_appengine_standard_app_versions.rb | 104 ++++++++++++++++++ test/integration/build/gcp-mm.tf | 24 +++- .../configuration/mm-attributes.yml | 10 +- .../controls/google_appengine_service.rb | 36 ++++++ .../controls/google_appengine_services.rb | 34 ++++++ .../google_appengine_standard_app_version.rb | 43 ++++++++ .../google_appengine_standard_app_versions.rb | 34 ++++++ 22 files changed, 1035 insertions(+), 2 deletions(-) create mode 100644 docs/resources/google_appengine_service.md create mode 100644 docs/resources/google_appengine_services.md create mode 100644 docs/resources/google_appengine_standard_app_version.md create mode 100644 docs/resources/google_appengine_standard_app_versions.md create mode 100644 libraries/google/appengine/property/standardappversion_deployment.rb create mode 100644 libraries/google/appengine/property/standardappversion_deployment_files.rb create mode 100644 libraries/google/appengine/property/standardappversion_deployment_zip.rb create mode 100644 libraries/google/appengine/property/standardappversion_entrypoint.rb create mode 100644 libraries/google/appengine/property/standardappversion_handlers.rb create mode 100644 libraries/google/appengine/property/standardappversion_handlers_script.rb create mode 100644 libraries/google/appengine/property/standardappversion_handlers_static_files.rb create mode 100644 libraries/google/appengine/property/standardappversion_libraries.rb create mode 100644 libraries/google_appengine_service.rb create mode 100644 libraries/google_appengine_services.rb create mode 100644 libraries/google_appengine_standard_app_version.rb create mode 100644 libraries/google_appengine_standard_app_versions.rb create mode 100644 test/integration/verify/controls/google_appengine_service.rb create mode 100644 test/integration/verify/controls/google_appengine_services.rb create mode 100644 test/integration/verify/controls/google_appengine_standard_app_version.rb create mode 100644 test/integration/verify/controls/google_appengine_standard_app_versions.rb diff --git a/docs/resources/google_appengine_service.md b/docs/resources/google_appengine_service.md new file mode 100644 index 000000000..48221cf00 --- /dev/null +++ b/docs/resources/google_appengine_service.md @@ -0,0 +1,30 @@ +--- +title: About the google_appengine_service resource +platform: gcp +--- + +## Syntax +A `google_appengine_service` is used to test a Google Service resource + +## Examples +``` + +describe google_appengine_service(project: 'chef-gcp-inspec', location: '', id: 'default', name: '') do + it { should exist } + its {'name' { should eq '' } } + its {'id' { should eq 'default' } } +end +``` + +## Properties +Properties that can be accessed from the `google_appengine_service` resource: + + * `name`: Full path to the Service resource in the API. Example apps/myapp/services/default. This field is used in responses only. Any value specified here in a request is ignored. + + * `id`: Relative name of the service within the application. Example default. + + + +## GCP Permissions + +Ensure the [App Engine Admin API](https://console.cloud.google.com/apis/library/appengine.googleapis.com/) is enabled for the current project. diff --git a/docs/resources/google_appengine_services.md b/docs/resources/google_appengine_services.md new file mode 100644 index 000000000..7e57ed62c --- /dev/null +++ b/docs/resources/google_appengine_services.md @@ -0,0 +1,30 @@ +--- +title: About the google_appengine_services resource +platform: gcp +--- + +## Syntax +A `google_appengine_services` is used to test a Google Service resource + +## Examples +``` + +describe google_appengine_services(project: 'chef-gcp-inspec', location: '') do + its('count') { should be >= 1 } +end +``` + +## Properties +Properties that can be accessed from the `google_appengine_services` resource: + +See [google_appengine_service.md](google_appengine_service.md) for more detailed information + * `names`: an array of `google_appengine_service` name + * `ids`: an array of `google_appengine_service` id + +## 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 [App Engine Admin API](https://console.cloud.google.com/apis/library/appengine.googleapis.com/) is enabled for the current project. diff --git a/docs/resources/google_appengine_standard_app_version.md b/docs/resources/google_appengine_standard_app_version.md new file mode 100644 index 000000000..14848ff49 --- /dev/null +++ b/docs/resources/google_appengine_standard_app_version.md @@ -0,0 +1,79 @@ +--- +title: About the google_appengine_standard_app_version resource +platform: gcp +--- + +## Syntax +A `google_appengine_standard_app_version` is used to test a Google StandardAppVersion resource + +## Examples +``` + +describe google_appengine_standard_app_version(project: 'chef-gcp-inspec', location: '', version_id: 'v2', service: 'default') do + it { should exist } + its('service') { should eq 'default' } + its('name') { should eq '' } + its('id') { should eq 'v2' } + its('threadsafe') { should be '' } + its('libraries') { should eq '' } + its('env_variables') { should eq 'val1' } + its('runtime_api_version') { should eq '' } + its('runtime') { should eq 'nodejs10' } + its('entrypoint') { should eq 'hello' } +end +``` + +## Properties +Properties that can be accessed from the `google_appengine_standard_app_version` resource: + + * `name`: Full path to the Version resource in the API. Example, "v1". + + * `id`: Relative name of the version within the service. For example, `v1`. Version names can contain only lowercase letters, numbers, or hyphens. Reserved names,"default", "latest", and any name with the prefix "ah-". + + * `runtime`: Desired runtime. Example python27. + + * `threadsafe`: Whether multiple requests can be dispatched to this version at once. + + * `runtime_api_version`: The version of the API in the given runtime environment. Please see the app.yaml reference for valid values at https://cloud.google.com/appengine/docs/standard//config/appref + + * `handlers`: An ordered list of URL-matching patterns that should be applied to incoming requests. The first matching URL handles the request and other request handlers are not attempted. + + * `url_regex`: URL prefix. Uses regular expression syntax, which means regexp special characters must be escaped, but should not contain groupings. All URLs that begin with this prefix are handled by this handler, using the portion of the URL after the prefix as part of the file path. + + * `security_level`: Security (HTTPS) enforcement for this URL. + + * `login`: Methods to restrict access to a URL based on login status. + + * `auth_fail_action`: Actions to take when the user is not logged in. + + * `redirect_http_response_code`: Redirect codes. + + * `script`: Executes a script to handle the requests that match this URL pattern. Only the auto value is supported for Node.js in the App Engine standard environment, for example "script:" "auto". + + * `static_files`: Files served directly to the user for a given URL, such as images, CSS stylesheets, or JavaScript source files. Static file handlers describe which files in the application directory are static files, and which URLs serve them. + + * `libraries`: Configuration for third-party Python runtime libraries that are required by the application. + + * `name`: Name of the library. Example "django". + + * `version`: Version of the library to select, or "latest". + + * `env_variables`: Environment variables available to the application. + + * `deployment`: Code and application artifacts that make up this version. + + * `zip`: Zip File + + * `files`: Manifest of the files stored in Google Cloud Storage that are included as part of this version. All files must be readable using the credentials supplied with this call. + + * `entrypoint`: The entrypoint for the application. + + * `shell`: The format should be a shell command that can be fed to bash -c. + + * `service`: AppEngine service resource + + + +## GCP Permissions + +Ensure the [App Engine Admin API](https://console.cloud.google.com/apis/library/appengine.googleapis.com/) is enabled for the current project. diff --git a/docs/resources/google_appengine_standard_app_versions.md b/docs/resources/google_appengine_standard_app_versions.md new file mode 100644 index 000000000..d5fdaea60 --- /dev/null +++ b/docs/resources/google_appengine_standard_app_versions.md @@ -0,0 +1,39 @@ +--- +title: About the google_appengine_standard_app_versions resource +platform: gcp +--- + +## Syntax +A `google_appengine_standard_app_versions` is used to test a Google StandardAppVersion resource + +## Examples +``` + +describe google_appengine_standard_app_versions(project: 'chef-gcp-inspec', location: '',service: 'default') do + its('count') { should be >= 1 } +end +``` + +## Properties +Properties that can be accessed from the `google_appengine_standard_app_versions` resource: + +See [google_appengine_standard_app_version.md](google_appengine_standard_app_version.md) for more detailed information + * `names`: an array of `google_appengine_standard_app_version` name + * `ids`: an array of `google_appengine_standard_app_version` id + * `runtimes`: an array of `google_appengine_standard_app_version` runtime + * `threadsaves`: an array of `google_appengine_standard_app_version` threadsafe + * `runtime_api_versions`: an array of `google_appengine_standard_app_version` runtime_api_version + * `handlers`: an array of `google_appengine_standard_app_version` handlers + * `libraries`: an array of `google_appengine_standard_app_version` libraries + * `env_variables`: an array of `google_appengine_standard_app_version` env_variables + * `deployments`: an array of `google_appengine_standard_app_version` deployment + * `entrypoints`: an array of `google_appengine_standard_app_version` entrypoint + * `services`: an array of `google_appengine_standard_app_version` service + +## 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 [App Engine Admin API](https://console.cloud.google.com/apis/library/appengine.googleapis.com/) is enabled for the current project. diff --git a/libraries/google/appengine/property/standardappversion_deployment.rb b/libraries/google/appengine/property/standardappversion_deployment.rb new file mode 100644 index 000000000..676bedbdf --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_deployment.rb @@ -0,0 +1,39 @@ +# 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 'google/appengine/property/standardappversion_deployment_files' +require 'google/appengine/property/standardappversion_deployment_zip' +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionDeployment + attr_reader :zip + + attr_reader :files + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @zip = GoogleInSpec::AppEngine::Property::StandardAppVersionDeploymentZip.new(args['zip'], to_s) + @files = args['files'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionDeployment" + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_deployment_files.rb b/libraries/google/appengine/property/standardappversion_deployment_files.rb new file mode 100644 index 000000000..c58343595 --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_deployment_files.rb @@ -0,0 +1,37 @@ +# 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. +# +# ---------------------------------------------------------------------------- +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionDeploymentFiles + attr_reader :sha1_sum + + attr_reader :source_url + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @sha1_sum = args['sha1Sum'] + @source_url = args['sourceUrl'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionDeploymentFiles" + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_deployment_zip.rb b/libraries/google/appengine/property/standardappversion_deployment_zip.rb new file mode 100644 index 000000000..37b8b6212 --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_deployment_zip.rb @@ -0,0 +1,37 @@ +# 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. +# +# ---------------------------------------------------------------------------- +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionDeploymentZip + attr_reader :source_url + + attr_reader :files_count + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @source_url = args['sourceUrl'] + @files_count = args['filesCount'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionDeploymentZip" + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_entrypoint.rb b/libraries/google/appengine/property/standardappversion_entrypoint.rb new file mode 100644 index 000000000..14c2836fc --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_entrypoint.rb @@ -0,0 +1,34 @@ +# 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. +# +# ---------------------------------------------------------------------------- +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionEntrypoint + attr_reader :shell + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @shell = args['shell'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionEntrypoint" + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_handlers.rb b/libraries/google/appengine/property/standardappversion_handlers.rb new file mode 100644 index 000000000..cb9d3726a --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_handlers.rb @@ -0,0 +1,62 @@ +# 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 'google/appengine/property/standardappversion_handlers_script' +require 'google/appengine/property/standardappversion_handlers_static_files' +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionHandlers + attr_reader :url_regex + + attr_reader :security_level + + attr_reader :login + + attr_reader :auth_fail_action + + attr_reader :redirect_http_response_code + + attr_reader :script + + attr_reader :static_files + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @url_regex = args['urlRegex'] + @security_level = args['securityLevel'] + @login = args['login'] + @auth_fail_action = args['authFailAction'] + @redirect_http_response_code = args['redirectHttpResponseCode'] + @script = GoogleInSpec::AppEngine::Property::StandardAppVersionHandlersScript.new(args['script'], to_s) + @static_files = GoogleInSpec::AppEngine::Property::StandardAppVersionHandlersStaticFiles.new(args['staticFiles'], to_s) + end + + def to_s + "#{@parent_identifier} StandardAppVersionHandlers" + end + end + + class StandardAppVersionHandlersArray + def self.parse(value, parent_identifier) + return if value.nil? + return StandardAppVersionHandlers.new(value, parent_identifier) unless value.is_a?(::Array) + value.map { |v| StandardAppVersionHandlers.new(v, parent_identifier) } + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_handlers_script.rb b/libraries/google/appengine/property/standardappversion_handlers_script.rb new file mode 100644 index 000000000..e8e0c76fd --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_handlers_script.rb @@ -0,0 +1,34 @@ +# 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. +# +# ---------------------------------------------------------------------------- +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionHandlersScript + attr_reader :script_path + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @script_path = args['scriptPath'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionHandlersScript" + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_handlers_static_files.rb b/libraries/google/appengine/property/standardappversion_handlers_static_files.rb new file mode 100644 index 000000000..e5ec216a8 --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_handlers_static_files.rb @@ -0,0 +1,52 @@ +# 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. +# +# ---------------------------------------------------------------------------- +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionHandlersStaticFiles + attr_reader :path + + attr_reader :upload_path_regex + + attr_reader :http_headers + + attr_reader :mime_type + + attr_reader :expiration + + attr_reader :require_matching_file + + attr_reader :application_readable + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @path = args['path'] + @upload_path_regex = args['uploadPathRegex'] + @http_headers = args['httpHeaders'] + @mime_type = args['mimeType'] + @expiration = args['expiration'] + @require_matching_file = args['requireMatchingFile'] + @application_readable = args['applicationReadable'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionHandlersStaticFiles" + end + end + end + end +end diff --git a/libraries/google/appengine/property/standardappversion_libraries.rb b/libraries/google/appengine/property/standardappversion_libraries.rb new file mode 100644 index 000000000..92740b7c3 --- /dev/null +++ b/libraries/google/appengine/property/standardappversion_libraries.rb @@ -0,0 +1,45 @@ +# 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. +# +# ---------------------------------------------------------------------------- +module GoogleInSpec + module AppEngine + module Property + class StandardAppVersionLibraries + attr_reader :name + + attr_reader :version + + def initialize(args = nil, parent_identifier = nil) + return if args.nil? + @parent_identifier = parent_identifier + @name = args['name'] + @version = args['version'] + end + + def to_s + "#{@parent_identifier} StandardAppVersionLibraries" + end + end + + class StandardAppVersionLibrariesArray + def self.parse(value, parent_identifier) + return if value.nil? + return StandardAppVersionLibraries.new(value, parent_identifier) unless value.is_a?(::Array) + value.map { |v| StandardAppVersionLibraries.new(v, parent_identifier) } + end + end + end + end +end diff --git a/libraries/google_appengine_service.rb b/libraries/google_appengine_service.rb new file mode 100644 index 000000000..32cd0dac8 --- /dev/null +++ b/libraries/google_appengine_service.rb @@ -0,0 +1,62 @@ +# 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' + +# A provider to manage App Engine resources. +class Service < GcpResourceBase + name 'google_appengine_service' + desc 'Service' + supports platform: 'gcp' + + attr_reader :params + attr_reader :name + attr_reader :id + + def initialize(params) + super(params.merge({ use_http_transport: true })) + @params = params + @fetched = @connection.fetch(product_url, resource_base_url, params) + parse unless @fetched.nil? + end + + def parse + @name = @fetched['name'] + @id = @fetched['id'] + 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 + "Service #{@params[:id]}" + end + + private + + def product_url + 'https://appengine.googleapis.com/v1/' + end + + def resource_base_url + 'apps/{{project}}/services/{{id}}' + end +end diff --git a/libraries/google_appengine_services.rb b/libraries/google_appengine_services.rb new file mode 100644 index 000000000..9695c87a0 --- /dev/null +++ b/libraries/google_appengine_services.rb @@ -0,0 +1,86 @@ +# 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' +class Services < GcpResourceBase + name 'google_appengine_services' + desc 'Service plural resource' + supports platform: 'gcp' + + attr_reader :table + + filter_table_config = FilterTable.create + + filter_table_config.add(:names, field: :name) + filter_table_config.add(:ids, field: :id) + + filter_table_config.connect(self, :table) + + def initialize(params = {}) + super(params.merge({ use_http_transport: true })) + @params = params + @table = fetch_wrapped_resource('services') + 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) + 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 + { + 'name' => ->(obj) { return :name, obj['name'] }, + 'id' => ->(obj) { return :id, obj['id'] }, + } + end + + # Handles parsing RFC3339 time string + def parse_time_string(time_string) + time_string ? Time.parse(time_string) : nil + end + + private + + def product_url + 'https://appengine.googleapis.com/v1/' + end + + def resource_base_url + 'apps/{{project}}/services' + end +end diff --git a/libraries/google_appengine_standard_app_version.rb b/libraries/google_appengine_standard_app_version.rb new file mode 100644 index 000000000..dae790d3b --- /dev/null +++ b/libraries/google_appengine_standard_app_version.rb @@ -0,0 +1,86 @@ +# 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/appengine/property/standardappversion_deployment' +require 'google/appengine/property/standardappversion_deployment_files' +require 'google/appengine/property/standardappversion_deployment_zip' +require 'google/appengine/property/standardappversion_entrypoint' +require 'google/appengine/property/standardappversion_handlers' +require 'google/appengine/property/standardappversion_libraries' + +# A provider to manage App Engine resources. +class StandardAppVersion < GcpResourceBase + name 'google_appengine_standard_app_version' + desc 'StandardAppVersion' + supports platform: 'gcp' + + attr_reader :params + attr_reader :name + attr_reader :id + attr_reader :runtime + attr_reader :threadsafe + attr_reader :runtime_api_version + attr_reader :handlers + attr_reader :libraries + attr_reader :env_variables + attr_reader :deployment + attr_reader :entrypoint + attr_reader :service + + def initialize(params) + super(params.merge({ use_http_transport: true })) + @params = params + @fetched = @connection.fetch(product_url, resource_base_url, params) + parse unless @fetched.nil? + end + + def parse + @name = @fetched['name'] + @id = @fetched['id'] + @runtime = @fetched['runtime'] + @threadsafe = @fetched['threadsafe'] + @runtime_api_version = @fetched['runtimeApiVersion'] + @handlers = GoogleInSpec::AppEngine::Property::StandardAppVersionHandlersArray.parse(@fetched['handlers'], to_s) + @libraries = GoogleInSpec::AppEngine::Property::StandardAppVersionLibrariesArray.parse(@fetched['libraries'], to_s) + @env_variables = @fetched['envVariables'] + @deployment = GoogleInSpec::AppEngine::Property::StandardAppVersionDeployment.new(@fetched['deployment'], to_s) + @entrypoint = GoogleInSpec::AppEngine::Property::StandardAppVersionEntrypoint.new(@fetched['entrypoint'], to_s) + @service = @fetched['service'] + 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 + "StandardAppVersion #{@params[:version_id]}" + end + + private + + def product_url + 'https://appengine.googleapis.com/v1/' + end + + def resource_base_url + 'apps/{{project}}/services/{{service}}/versions/{{version_id}}' + end +end diff --git a/libraries/google_appengine_standard_app_versions.rb b/libraries/google_appengine_standard_app_versions.rb new file mode 100644 index 000000000..23f1aa0d2 --- /dev/null +++ b/libraries/google_appengine_standard_app_versions.rb @@ -0,0 +1,104 @@ +# 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' +class StandardAppVersions < GcpResourceBase + name 'google_appengine_standard_app_versions' + desc 'StandardAppVersion plural resource' + supports platform: 'gcp' + + attr_reader :table + + filter_table_config = FilterTable.create + + filter_table_config.add(:names, field: :name) + filter_table_config.add(:ids, field: :id) + filter_table_config.add(:runtimes, field: :runtime) + filter_table_config.add(:threadsaves, field: :threadsafe) + filter_table_config.add(:runtime_api_versions, field: :runtime_api_version) + filter_table_config.add(:handlers, field: :handlers) + filter_table_config.add(:libraries, field: :libraries) + filter_table_config.add(:env_variables, field: :env_variables) + filter_table_config.add(:deployments, field: :deployment) + filter_table_config.add(:entrypoints, field: :entrypoint) + filter_table_config.add(:services, field: :service) + + filter_table_config.connect(self, :table) + + def initialize(params = {}) + super(params.merge({ use_http_transport: true })) + @params = params + @table = fetch_wrapped_resource('standardAppVersions') + 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) + 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 + { + 'name' => ->(obj) { return :name, obj['name'] }, + 'id' => ->(obj) { return :id, obj['id'] }, + 'runtime' => ->(obj) { return :runtime, obj['runtime'] }, + 'threadsafe' => ->(obj) { return :threadsafe, obj['threadsafe'] }, + 'runtimeApiVersion' => ->(obj) { return :runtime_api_version, obj['runtimeApiVersion'] }, + 'handlers' => ->(obj) { return :handlers, GoogleInSpec::AppEngine::Property::StandardAppVersionHandlersArray.parse(obj['handlers'], to_s) }, + 'libraries' => ->(obj) { return :libraries, GoogleInSpec::AppEngine::Property::StandardAppVersionLibrariesArray.parse(obj['libraries'], to_s) }, + 'envVariables' => ->(obj) { return :env_variables, obj['envVariables'] }, + 'deployment' => ->(obj) { return :deployment, GoogleInSpec::AppEngine::Property::StandardAppVersionDeployment.new(obj['deployment'], to_s) }, + 'entrypoint' => ->(obj) { return :entrypoint, GoogleInSpec::AppEngine::Property::StandardAppVersionEntrypoint.new(obj['entrypoint'], to_s) }, + 'service' => ->(obj) { return :service, obj['service'] }, + } + end + + # Handles parsing RFC3339 time string + def parse_time_string(time_string) + time_string ? Time.parse(time_string) : nil + end + + private + + def product_url + 'https://appengine.googleapis.com/v1/' + end + + def resource_base_url + 'apps/{{project}}/services/{{service}}/versions' + end +end diff --git a/test/integration/build/gcp-mm.tf b/test/integration/build/gcp-mm.tf index 86211476e..d8e59b25a 100644 --- a/test/integration/build/gcp-mm.tf +++ b/test/integration/build/gcp-mm.tf @@ -145,6 +145,10 @@ variable "org_sink" { type = "map" } +variable "standardappversion" { + type = "map" +} + resource "google_compute_ssl_policy" "custom-ssl-policy" { name = "${var.ssl_policy["name"]}" min_tls_version = "${var.ssl_policy["min_tls_version"]}" @@ -568,4 +572,22 @@ resource "google_logging_organization_sink" "my-sink" { # Log all WARN or higher severity messages relating to instances filter = "${var.org_sink.filter}" -} \ No newline at end of file +} + +resource "google_app_engine_standard_app_version" "default" { + version_id = "${var.standardappversion["version_id"]}" + service = "${var.standardappversion["service"]}" + runtime = "${var.standardappversion["runtime"]}" + noop_on_destroy = true + entrypoint = "${var.standardappversion["entrypoint"]}" + + deployment { + zip { + source_url = "https://storage.googleapis.com/${google_storage_bucket.generic-storage-bucket.name}/hello-world.zip" + } + } + + env_variables = { + MY_ENV_VAR = "${var.cloudfunction["env_var_value"]}" + } +} diff --git a/test/integration/configuration/mm-attributes.yml b/test/integration/configuration/mm-attributes.yml index e422a48d5..f21dd5195 100644 --- a/test/integration/configuration/mm-attributes.yml +++ b/test/integration/configuration/mm-attributes.yml @@ -224,4 +224,12 @@ regional_node_pool: org_sink: name: inspec-gcp-org-sink - filter: resource.type = gce_instance \ No newline at end of file + filter: resource.type = gce_instance + +standardappversion: + version_id: v2 + service: default + runtime: nodejs10 + entrypoint: hello + env_var_value: val1 + \ No newline at end of file diff --git a/test/integration/verify/controls/google_appengine_service.rb b/test/integration/verify/controls/google_appengine_service.rb new file mode 100644 index 000000000..4816e2820 --- /dev/null +++ b/test/integration/verify/controls/google_appengine_service.rb @@ -0,0 +1,36 @@ +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_appengine_service resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +gcp_appengine_region = attribute(:gcp_appengine_region, default: 'gcp_appengine_region', description: 'The App Engine region.') +standardappversion = attribute('standardappversion', default: { + "version_id": "v2", + "service": "default", + "runtime": "nodejs10", + "entrypoint": "hello", + "env_var_value": "val1" +}, description: 'Cloud App Engine definition') +control 'google_appengine_service-1.0' do + impact 1.0 + title 'google_appengine_service resource test' + + + describe google_appengine_service(project: gcp_project_id, location: gcp_standardappversion_region, id: standardappversion['service'], name: standardappversion['name']) do + it { should exist } + its {'name' { should eq standardappversion['name'] } } + its {'id' { should eq standardappversion['service'] } } + end +end diff --git a/test/integration/verify/controls/google_appengine_services.rb b/test/integration/verify/controls/google_appengine_services.rb new file mode 100644 index 000000000..99eb079ed --- /dev/null +++ b/test/integration/verify/controls/google_appengine_services.rb @@ -0,0 +1,34 @@ +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_appengine_services resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +gcp_appengine_region = attribute(:gcp_appengine_region, default: 'gcp_appengine_region', description: 'The App Engine region.') +standardappversion = attribute('standardappversion', default: { + "version_id": "v2", + "service": "default", + "runtime": "nodejs10", + "entrypoint": "hello", + "env_var_value": "val1" +}, description: 'Cloud App Engine definition') +control 'google_appengine_services-1.0' do + impact 1.0 + title 'google_appengine_services resource test' + + + describe google_appengine_services(project: gcp_project_id, location: gcp_standardappversion_region) do + its('count') { should be >= 1 } + end +end diff --git a/test/integration/verify/controls/google_appengine_standard_app_version.rb b/test/integration/verify/controls/google_appengine_standard_app_version.rb new file mode 100644 index 000000000..f030b94e5 --- /dev/null +++ b/test/integration/verify/controls/google_appengine_standard_app_version.rb @@ -0,0 +1,43 @@ +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_appengine_standard_app_version resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +gcp_appengine_region = attribute(:gcp_appengine_region, default: 'gcp_appengine_region', description: 'The App Engine region.') +standardappversion = attribute('standardappversion', default: { + "version_id": "v2", + "service": "default", + "runtime": "nodejs10", + "entrypoint": "hello", + "env_var_value": "val1" +}, description: 'Cloud App Engine definition') +control 'google_appengine_standard_app_version-1.0' do + impact 1.0 + title 'google_appengine_standard_app_version resource test' + + + describe google_appengine_standard_app_version(project: gcp_project_id, location: gcp_standardappversion_region, version_id: standardappversion['version_id'], service: standardappversion['service']) do + it { should exist } + its('service') { should eq standardappversion['service'] } + its('name') { should eq standardappversion['name'] } + its('id') { should eq standardappversion['version_id'] } + its('threadsafe') { should be standardappversion['threadsafe'] } + its('libraries') { should eq standardappversion['libraries'] } + its('env_variables') { should eq standardappversion['env_var_value'] } + its('runtime_api_version') { should eq standardappversion['runtime_api_version'] } + its('runtime') { should eq standardappversion['runtime'] } + its('entrypoint') { should eq standardappversion['entrypoint'] } + end +end diff --git a/test/integration/verify/controls/google_appengine_standard_app_versions.rb b/test/integration/verify/controls/google_appengine_standard_app_versions.rb new file mode 100644 index 000000000..053a368b9 --- /dev/null +++ b/test/integration/verify/controls/google_appengine_standard_app_versions.rb @@ -0,0 +1,34 @@ +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- + +title 'Test GCP google_appengine_standard_app_versions resource.' + +gcp_project_id = attribute(:gcp_project_id, default: 'gcp_project_id', description: 'The GCP project identifier.') +gcp_appengine_region = attribute(:gcp_appengine_region, default: 'gcp_appengine_region', description: 'The App Engine region.') +standardappversion = attribute('standardappversion', default: { + "version_id": "v2", + "service": "default", + "runtime": "nodejs10", + "entrypoint": "hello", + "env_var_value": "val1" +}, description: 'Cloud App Engine definition') +control 'google_appengine_standard_app_versions-1.0' do + impact 1.0 + title 'google_appengine_standard_app_versions resource test' + + + describe google_appengine_standard_app_versions(project: gcp_project_id, location: gcp_standardappversion_region,service: standardappversion['service']) do + its('count') { should be >= 1 } + end +end