From 9fcf2737c8e4e05c13c27b3ee7ee0570620080d8 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 14 Dec 2018 00:46:17 +0000 Subject: [PATCH 1/2] Add Magic Modules generated resource for SSL Policy Signed-off-by: Sam Levenick --- .gitignore | 5 +- Gemfile | 18 +- Rakefile | 12 +- docs/resources/google_compute_ssl_policies.md | 43 ++++ docs/resources/google_compute_ssl_policy.md | 46 ++++ libraries/gcp_backend.rb | 213 ++++++++++++++++++ .../compute/property/sslpolicy_warnings.rb | 40 ++++ libraries/google_compute_ssl_policies.rb | 71 ++++++ libraries/google_compute_ssl_policy.rb | 65 ++++++ test/integration/build/gcp-mm.tf | 33 +++ .../configuration/gcp_inspec_config.rb | 8 + .../configuration/mm-attributes.yml | 6 + .../controls/google_compute_ssl_policies.rb | 35 +++ .../controls/google_compute_ssl_policy.rb | 30 +++ 14 files changed, 610 insertions(+), 15 deletions(-) create mode 100644 docs/resources/google_compute_ssl_policies.md create mode 100644 docs/resources/google_compute_ssl_policy.md create mode 100644 libraries/google/compute/property/sslpolicy_warnings.rb create mode 100644 libraries/google_compute_ssl_policies.rb create mode 100644 libraries/google_compute_ssl_policy.rb create mode 100644 test/integration/build/gcp-mm.tf create mode 100644 test/integration/configuration/mm-attributes.yml create mode 100644 test/integration/verify/controls/google_compute_ssl_policies.rb create mode 100644 test/integration/verify/controls/google_compute_ssl_policy.rb diff --git a/.gitignore b/.gitignore index 5d90c6dc8..649cc9107 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ local *.idea* *.env *inspec-gcp.tfvars -*gcp-inspec-attributes.yaml \ No newline at end of file +*gcp-inspec-attributes.yaml +inspec-cassettes +*terraform.tfvars +*inspec.json \ No newline at end of file diff --git a/Gemfile b/Gemfile index 2dba7111a..df28b6c9d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,19 +1,17 @@ source 'https://rubygems.org' -gem 'inifile' +gem 'bundle' gem 'google-api-client' -gem 'googleauth' gem 'google-cloud' -gem 'bundle' +gem 'googleauth' +gem 'inifile' +gem 'inspec', '~> 3.0', '>= 3.0.25' +gem 'rubocop' group :development do - gem 'rake' - gem 'rubocop' gem 'github_changelog_generator' - gem 'pry-coolline' gem 'passgen' -end - -group :inspec do - gem 'inspec', '~> 3.0', '>= 3.0.25' + gem 'pry-coolline' + gem 'rake' + gem 'webmock' end diff --git a/Rakefile b/Rakefile index 332eac68f..e6a69e743 100644 --- a/Rakefile +++ b/Rakefile @@ -47,6 +47,13 @@ namespace :test do sh(cmd) end + task :generate_integration_test_variables do + puts "----> Generating terraform and inspec variable files" + #p GCPInspecConfig.config[:gcp_project_id] + GCPInspecConfig.store_json(variable_file_name) + GCPInspecConfig.store_yaml(profile_attributes) + end + task :plan_integration_tests do # Determine the storage account name and the admin password @@ -56,10 +63,7 @@ namespace :test do # Use the first 4 characters of the storage account to create a suffix # suffix = sa_name[0..3] - puts "----> Generating terraform and inspec variable files" - #p GCPInspecConfig.config[:gcp_project_id] - GCPInspecConfig.store_json(variable_file_name) - GCPInspecConfig.store_yaml(profile_attributes) + Rake::Task["test:generate_integration_test_variables"].execute puts "----> Setup" # Create the plan that can be applied to GCP diff --git a/docs/resources/google_compute_ssl_policies.md b/docs/resources/google_compute_ssl_policies.md new file mode 100644 index 000000000..cbe25706e --- /dev/null +++ b/docs/resources/google_compute_ssl_policies.md @@ -0,0 +1,43 @@ +--- +title: About the SslPolicy resource +platform: gcp +--- + + +## Syntax +A `google_compute_ssl_policies` is used to test a Google SslPolicy resource + +## Examples +``` +describe google_compute_ssl_policies({project: ''}) do + it { should exist } + its('names') { should include 'inspec-gcp-ssl-policy' } + its('profiles') { should include 'CUSTOM' } + its('count') { should eq 1 } +end + +google_compute_ssl_policies({project: ''}).names.each do |policy_name| + describe google_compute_ssl_policy({project: '', name: policy_name}) do + its('min_tls_version') { should cmp 'TLS_1_2' } + end +end +``` + +## Properties +Properties that can be accessed from the `google_compute_ssl_policies` resource: + +See [google_compute_ssl_policy.md](google_compute_ssl_policy.md) for more detailed information + * `creation_timestamps`: an array of `google_compute_ssl_policy` creation_timestamp + * `descriptions`: an array of `google_compute_ssl_policy` description + * `ids`: an array of `google_compute_ssl_policy` id + * `names`: an array of `google_compute_ssl_policy` name + * `profiles`: an array of `google_compute_ssl_policy` profile + * `min_tls_versions`: an array of `google_compute_ssl_policy` min_tls_version + * `enabled_features`: an array of `google_compute_ssl_policy` enabled_features + * `custom_features`: an array of `google_compute_ssl_policy` custom_features + * `fingerprints`: an array of `google_compute_ssl_policy` fingerprint + * `warnings`: an array of `google_compute_ssl_policy` warnings + +## 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. diff --git a/docs/resources/google_compute_ssl_policy.md b/docs/resources/google_compute_ssl_policy.md new file mode 100644 index 000000000..56732da1f --- /dev/null +++ b/docs/resources/google_compute_ssl_policy.md @@ -0,0 +1,46 @@ +--- +title: About the SslPolicy resource +platform: gcp +--- + + +## Syntax +A `google_compute_ssl_policy` is used to test a Google SslPolicy resource + +## Examples +``` +describe google_compute_ssl_policy({project: '', name: 'inspec-gcp-ssl-policy'}) do + it { should exist } + its('min_tls_version') { should cmp 'TLS_1_2' } + its('profile') { should cmp 'CUSTOM' } + its('custom_features') { should include 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384' } + its('custom_features') { should include 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384' } +end +``` + +## Properties +Properties that can be accessed from the `google_compute_ssl_policy` resource: + + * `creation_timestamp`: Creation timestamp in RFC3339 text format. + + * `description`: An optional description of this 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. + + * `profile`: Profile specifies the set of SSL features that can be used by the load balancer when negotiating SSL with clients. This can be one of `COMPATIBLE`, `MODERN`, `RESTRICTED`, or `CUSTOM`. If using `CUSTOM`, the set of SSL features to enable must be specified in the `customFeatures` field. + + * `min_tls_version`: The minimum version of SSL protocol that can be used by the clients to establish a connection with the load balancer. This can be one of `TLS_1_0`, `TLS_1_1`, `TLS_1_2`. + + * `enabled_features`: The list of features enabled in the SSL policy. + + * `custom_features`: A list of features enabled when the selected profile is CUSTOM. The method returns the set of features that can be specified in this list. This field must be empty if the profile is not CUSTOM. + + * `fingerprint`: Fingerprint of this resource. A hash of the contents stored in this object. This field is used in optimistic locking. + + * `warnings`: If potential misconfigurations are detected for this SSL policy, this field will be populated with warning messages. + + * `code`: A warning code, if applicable. + + * `message`: A human-readable description of the warning code. diff --git a/libraries/gcp_backend.rb b/libraries/gcp_backend.rb index 41e9c7e99..492d95ad6 100644 --- a/libraries/gcp_backend.rb +++ b/libraries/gcp_backend.rb @@ -6,6 +6,8 @@ # require 'json' +require 'net/http' +require 'googleauth' # Base class for GCP resources - depends on train GCP transport for connection # @@ -17,6 +19,10 @@ def initialize(opts) @opts = opts # ensure we have a GCP connection, resources can choose which of the clients to instantiate @gcp = inspec.backend + + # Magic Modules generated resources use an alternate transport method + # In the future this will be moved into the train-gcp plugin itself + @connection = GcpApiConnection.new if opts[:use_http_transport] end def failed_resource? @@ -178,3 +184,210 @@ def camel_case(data) camel_case_data.gsub(/[gb]/, &:upcase) end end + +class GcpApiConnection + def initialize + @service_account_file = ENV['GOOGLE_APPLICATION_CREDENTIALS'] + end + + def fetch_auth + unless @service_account_file.nil? + return Network::Authorization.new.for!( + ['https://www.googleapis.com/auth/compute.readonly'], + ).from_service_account_json!( + @service_account_file, + ) + end + Network::Authorization.new.from_application_default! + end + + def fetch(base_url, template, var_data) + get_request = Network::Base.new( + build_uri(base_url, template, var_data), + fetch_auth, + ) + return_if_object get_request.send + end + + def fetch_all(base_url, template, var_data) + next_page(build_uri(base_url, template, var_data)) + end + + def next_page(uri, token = nil) + next_hash = {} + next_hash['pageToken'] = token unless token.nil? + current_params = Hash[URI.decode_www_form(uri.query || '')].merge(next_hash) + uri.query = URI.encode_www_form(current_params) + get_request = Network::Base.new( + uri, + fetch_auth, + ) + result = JSON.parse(get_request.send.body) + next_page_token = result['nextPageToken'] + return [result] if next_page_token.nil? + + [result] + next_page(uri, next_page_token) + end + + def return_if_object(response) + raise "Bad response: #{response.body}" \ + if response.is_a?(Net::HTTPBadRequest) + raise "Bad response: #{response}" \ + unless response.is_a?(Net::HTTPResponse) + return if response.is_a?(Net::HTTPNotFound) + return if response.is_a?(Net::HTTPNoContent) + result = JSON.parse(response.body) + raise_if_errors result, %w{error errors}, 'message' + raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK) + result + end + + def raise_if_errors(response, err_path, msg_field) + errors = self.class.navigate(response, err_path) + raise_error(errors, msg_field) unless errors.nil? + end + + def raise_error(errors, msg_field) + raise IOError, ['Operation failed:', + errors.map { |e| e[msg_field] }.join(', ')].join(' ') + end + + def build_uri(base_url, template, var_data) + URI.join( + base_url, + expand_variables(template, var_data), + ) + end + + # Allows fetching objects within a tree path. + def self.navigate(source, path, default = nil) + key = path.take(1)[0] + path = path.drop(1) + return default unless source.key?(key) + result = source.fetch(key) + return navigate(result, path, default) unless path.empty? + return result if path.empty? + end + + def extract_variables(template) + template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') } + .map(&:to_sym) + end + + def expand_variables(template, var_data) + extract_variables(template).each do |v| + unless var_data.key?(v) + raise "Missing variable :#{v} in #{var_data} on #{caller.join("\n")}}" + end + template.gsub!(/{{#{v}}}/, CGI.escape(var_data[v].to_s)) + end + template + end +end + +# A handler for authenticated network request +module Network + class Base + def initialize(link, cred) + @link = link + @cred = cred + end + + def builder + Net::HTTP.const_get('Get') + end + + def send + request = @cred.authorize(builder.new(@link)) + request['User-Agent'] = generate_user_agent + response = transport(request).request(request) + unless ENV['GOOGLE_HTTP_VERBOSE'].nil? + puts ["network(#{request}: [#{response.code}]", + response.body.split("\n").map(&:strip).join(' ')].join(' ') + end + response + end + + def transport(request) + uri = request.uri + puts "network(#{request}: #{uri})" \ + unless ENV['GOOGLE_HTTP_VERBOSE'].nil? + transport = Net::HTTP.new(uri.host, uri.port) + transport.use_ssl = uri.is_a?(URI::HTTPS) + transport.verify_mode = OpenSSL::SSL::VERIFY_PEER + transport.set_debug_output $stderr \ + unless ENV['GOOGLE_HTTP_DEBUG'].nil? + transport + end + + private + + def generate_user_agent + 'inspec-google/1.0.0' + end + end + + # A class to aquire credentials and authorize Google API calls. + class Authorization + def initialize + @authorization = nil + @scopes = [] + end + + def authorize(obj) + raise ArgumentError, 'A from_* method needs to be called before' \ + unless @authorization + + if obj.class <= URI::HTTPS || obj.class <= URI::HTTP + authorize_uri obj + elsif obj.class < Net::HTTPRequest + authorize_http obj + else + obj.authorization = @authorization + obj + end + end + + def for!(*scopes) + @scopes = scopes + self + end + + def from_service_account_json!(service_account_file) + raise 'Missing argument for scopes' if @scopes.empty? + @authorization = ::Google::Auth::ServiceAccountCredentials.make_creds( + json_key_io: File.open(service_account_file), + scope: @scopes, + ) + self + end + + def from_application_default! + @authorization = ::Google::Auth.get_application_default + self + end + + private + + def authorize_uri(obj) + http = Net::HTTP.new(obj.host, obj.port) + http.use_ssl = obj.instance_of?(URI::HTTPS) + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + [http, authorize_http(Net::HTTP::Get.new(obj.request_uri))] + end + + def authorize_http(req) + req.extend TokenProperty + auth = {} + @authorization.apply!(auth) + req['Authorization'] = auth[:authorization] + req.token = auth[:authorization].split(' ')[1] + req + end + end + # Extension methods to enable retrieving the authentication token. + module TokenProperty + attr_reader :token + attr_writer :token + end +end diff --git a/libraries/google/compute/property/sslpolicy_warnings.rb b/libraries/google/compute/property/sslpolicy_warnings.rb new file mode 100644 index 000000000..f098b9e54 --- /dev/null +++ b/libraries/google/compute/property/sslpolicy_warnings.rb @@ -0,0 +1,40 @@ +# 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 Compute + module Property + class SslPolicyWarnings + attr_reader :code + + attr_reader :message + + def initialize(args = nil) + return if args.nil? + @code = args['code'] + @message = args['message'] + end + end + + class SslPolicyWarningsArray + def self.parse(value) + return if value.nil? + return SslPolicyWarnings.new(value) unless value.is_a?(::Array) + value.map { |v| SslPolicyWarnings.new(v) } + end + end + end + end +end diff --git a/libraries/google_compute_ssl_policies.rb b/libraries/google_compute_ssl_policies.rb new file mode 100644 index 000000000..567f84dfe --- /dev/null +++ b/libraries/google_compute_ssl_policies.rb @@ -0,0 +1,71 @@ +# 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 SslPolicys < GcpResourceBase + name 'google_compute_ssl_policies' + desc 'SslPolicy plural resource' + supports platform: 'gcp' + + attr_reader :table + + filter_table_config = FilterTable.create + + filter_table_config.add(:creation_timestamps, field: :creationTimestamp) + 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(:profiles, field: :profile) + filter_table_config.add(:min_tls_versions, field: :minTlsVersion) + filter_table_config.add(:enabled_features, field: :enabledFeatures) + filter_table_config.add(:custom_features, field: :customFeatures) + filter_table_config.add(:fingerprints, field: :fingerprint) + filter_table_config.add(:warnings, field: :warnings) + + filter_table_config.connect(self, :table) + + def base + 'https://www.googleapis.com/compute/v1/' + end + + def url + 'projects/{{project}}/global/sslPolicies' + end + + 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(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_pair { |k, v| hash_with_symbols[k.to_sym] = v } + converted.push(hash_with_symbols) + end + end + + converted + end +end diff --git a/libraries/google_compute_ssl_policy.rb b/libraries/google_compute_ssl_policy.rb new file mode 100644 index 000000000..11dbb550c --- /dev/null +++ b/libraries/google_compute_ssl_policy.rb @@ -0,0 +1,65 @@ +# 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/compute/property/sslpolicy_warnings' + +# A provider to manage Google Compute Engine resources. +class SslPolicy < GcpResourceBase + name 'google_compute_ssl_policy' + desc 'SslPolicy' + supports platform: 'gcp' + + attr_reader :creation_timestamp + attr_reader :description + attr_reader :id + attr_reader :name + attr_reader :profile + attr_reader :min_tls_version + attr_reader :enabled_features + attr_reader :custom_features + attr_reader :fingerprint + attr_reader :warnings + def base + 'https://www.googleapis.com/compute/v1/' + end + + def url + 'projects/{{project}}/global/sslPolicies/{{name}}' + end + + def initialize(params) + super(params.merge({ use_http_transport: true })) + @fetched = @connection.fetch(base, url, params) + parse unless @fetched.nil? + end + + def parse + @creation_timestamp = Time.parse(@fetched['creationTimestamp']) + @description = @fetched['description'] + @id = @fetched['id'] + @name = @fetched['name'] + @profile = @fetched['profile'] + @min_tls_version = @fetched['minTlsVersion'] + @enabled_features = @fetched['enabledFeatures'] + @custom_features = @fetched['customFeatures'] + @fingerprint = @fetched['fingerprint'] + @warnings = GoogleInSpec::Compute::Property::SslPolicyWarningsArray.parse(@fetched['warnings']) + end + + def exists? + !@fetched.nil? + end +end diff --git a/test/integration/build/gcp-mm.tf b/test/integration/build/gcp-mm.tf new file mode 100644 index 000000000..42302bc5b --- /dev/null +++ b/test/integration/build/gcp-mm.tf @@ -0,0 +1,33 @@ +variable "ssl_policy" { + type = "map" +} + +resource "google_compute_ssl_policy" "custom-ssl-policy" { + name = "${var.ssl_policy["name"]}" + min_tls_version = "${var.ssl_policy["min_tls_version"]}" + profile = "${var.ssl_policy["profile"]}" + custom_features = ["${var.ssl_policy["custom_feature"]}", "${var.ssl_policy["custom_feature2"]}"] + project = "${var.gcp_project_id}" +} + +resource "google_service_account" "inspecaccount" { + account_id = "inspec-account" + display_name = "InSpec Service Account" + project = "${var.gcp_project_id}" +} + +resource "google_service_account_key" "inspeckey" { + service_account_id = "${google_service_account.inspecaccount.name}" + public_key_type = "TYPE_X509_PEM_FILE" +} + +resource "google_project_iam_member" "inspec-iam-member" { + role = "roles/viewer" + member = "serviceAccount:${google_service_account.inspecaccount.email}" + project = "${var.gcp_project_id}" +} + +resource "local_file" "file" { + content = "${base64decode(google_service_account_key.inspeckey.private_key)}" + filename = "${path.module}/inspec.json" +} diff --git a/test/integration/configuration/gcp_inspec_config.rb b/test/integration/configuration/gcp_inspec_config.rb index 4e117b54f..2ffc5b255 100644 --- a/test/integration/configuration/gcp_inspec_config.rb +++ b/test/integration/configuration/gcp_inspec_config.rb @@ -6,6 +6,7 @@ require 'json' require 'yaml' require 'passgen' +require 'erb' module GCPInspecConfig @@ -110,8 +111,14 @@ def self.update_from_environment @config.each { |k,v| @config[k] = ENV[k.to_s.upcase] || v } end + def self.load_mm_vars + loaded = YAML.load_file(File.join(File.dirname(__FILE__), 'mm-attributes.yml')) + @config = loaded.merge(@config) + end + # Create JSON for terraform def self.store_json(file_name="gcp-inspec.tfvars") + load_mm_vars update_from_environment File.open(File.join(File.dirname(__FILE__),'..','build',file_name),"w") do |f| f.write(@config.to_json) @@ -120,6 +127,7 @@ def self.store_json(file_name="gcp-inspec.tfvars") # Create YAML for inspec def self.store_yaml(file_name="gcp-inspec-attributes.yaml") + load_mm_vars update_from_environment File.open(File.join(File.dirname(__FILE__),'..','build',file_name),"w") do |f| f.write(@config.to_yaml) diff --git a/test/integration/configuration/mm-attributes.yml b/test/integration/configuration/mm-attributes.yml new file mode 100644 index 000000000..adbf7782d --- /dev/null +++ b/test/integration/configuration/mm-attributes.yml @@ -0,0 +1,6 @@ +ssl_policy: + name: 'inspec-gcp-ssl-policy' + min_tls_version: 'TLS_1_2' + profile: 'CUSTOM' + custom_feature: 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384' + custom_feature2: 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384' diff --git a/test/integration/verify/controls/google_compute_ssl_policies.rb b/test/integration/verify/controls/google_compute_ssl_policies.rb new file mode 100644 index 000000000..f1c5683b3 --- /dev/null +++ b/test/integration/verify/controls/google_compute_ssl_policies.rb @@ -0,0 +1,35 @@ +# ---------------------------------------------------------------------------- +# +# *** 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_compute_ssl_policies resource.' + +project_name = attribute(:gcp_project_name, default: '') +ssl_policy = attribute('ssl_policy', default: {"name"=>"inspec-gcp-ssl-policy", "min_tls_version"=>"TLS_1_2", "profile"=>"CUSTOM", "custom_feature"=>"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "custom_feature2"=>"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}) +control 'google_compute_ssl_policies-1.0' do + impact 1.0 + title 'google_compute_ssl_policies resource test' + + describe google_compute_ssl_policies({project: project_name}) do + it { should exist } + its('names') { should include ssl_policy['name'] } + its('profiles') { should include ssl_policy['profile'] } + its('count') { should eq 1 } + end + + google_compute_ssl_policies({project: project_name}).names.each do |policy_name| + describe google_compute_ssl_policy({project: project_name, name: policy_name}) do + its('min_tls_version') { should cmp ssl_policy['min_tls_version'] } + end + end +end diff --git a/test/integration/verify/controls/google_compute_ssl_policy.rb b/test/integration/verify/controls/google_compute_ssl_policy.rb new file mode 100644 index 000000000..d261bfae7 --- /dev/null +++ b/test/integration/verify/controls/google_compute_ssl_policy.rb @@ -0,0 +1,30 @@ +# ---------------------------------------------------------------------------- +# +# *** 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_compute_ssl_policy resource.' + +project_name = attribute(:gcp_project_name, default: '') +ssl_policy = attribute('ssl_policy', default: {"name"=>"inspec-gcp-ssl-policy", "min_tls_version"=>"TLS_1_2", "profile"=>"CUSTOM", "custom_feature"=>"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "custom_feature2"=>"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}) +control 'google_compute_ssl_policy-1.0' do + impact 1.0 + title 'google_compute_ssl_policy resource test' + + describe google_compute_ssl_policy({project: project_name, name: ssl_policy['name']}) do + it { should exist } + its('min_tls_version') { should cmp ssl_policy['min_tls_version'] } + its('profile') { should cmp ssl_policy['profile'] } + its('custom_features') { should include ssl_policy['custom_feature'] } + its('custom_features') { should include ssl_policy['custom_feature2'] } + end +end From 2d0cb523409b90b0ef7afcb1acefc0bb5308827e Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 26 Dec 2018 17:39:45 +0000 Subject: [PATCH 2/2] Remove old service account from inspec integration test tf file Signed-off-by: Sam Levenick --- test/integration/build/gcp-mm.tf | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/test/integration/build/gcp-mm.tf b/test/integration/build/gcp-mm.tf index 42302bc5b..a80322bd4 100644 --- a/test/integration/build/gcp-mm.tf +++ b/test/integration/build/gcp-mm.tf @@ -8,26 +8,4 @@ resource "google_compute_ssl_policy" "custom-ssl-policy" { profile = "${var.ssl_policy["profile"]}" custom_features = ["${var.ssl_policy["custom_feature"]}", "${var.ssl_policy["custom_feature2"]}"] project = "${var.gcp_project_id}" -} - -resource "google_service_account" "inspecaccount" { - account_id = "inspec-account" - display_name = "InSpec Service Account" - project = "${var.gcp_project_id}" -} - -resource "google_service_account_key" "inspeckey" { - service_account_id = "${google_service_account.inspecaccount.name}" - public_key_type = "TYPE_X509_PEM_FILE" -} - -resource "google_project_iam_member" "inspec-iam-member" { - role = "roles/viewer" - member = "serviceAccount:${google_service_account.inspecaccount.email}" - project = "${var.gcp_project_id}" -} - -resource "local_file" "file" { - content = "${base64decode(google_service_account_key.inspeckey.private_key)}" - filename = "${path.module}/inspec.json" -} +} \ No newline at end of file