Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
df005d9
Adding basic singular resource code
slevenick Oct 12, 2018
1867189
Adding basic singular resource code
slevenick Oct 12, 2018
e7b703e
Add nested objects and parsing logic
slevenick Oct 12, 2018
d8d6b85
Remove todo
slevenick Oct 12, 2018
b981596
Add nested constructor
slevenick Oct 12, 2018
1993bf5
Add attr readers for nested object
slevenick Oct 12, 2018
ec00543
Add basic requires
slevenick Oct 12, 2018
cee98a6
Add resource unwrapping for singular resource
slevenick Oct 15, 2018
6dafb25
Adding list link, plural generation
slevenick Oct 16, 2018
38d3e19
Underscoring names
slevenick Oct 16, 2018
332c368
Templating issues, spacing
slevenick Oct 16, 2018
9ec2097
Fixing resource imports
slevenick Oct 16, 2018
13615e7
Requires changes
slevenick Oct 16, 2018
7d8f69a
Fixing requires
slevenick Oct 17, 2018
63e63e2
Fix inspec branch name
slevenick Oct 17, 2018
89d4760
Merge branch 'master' of https://github.com/GoogleCloudPlatform/magic…
slevenick Oct 17, 2018
df598d5
Merge branch 'master' into ground-up-2
slevenick Oct 17, 2018
1e7f972
Adding excludes for resources
slevenick Oct 17, 2018
a58799f
Merge branch 'master' of https://github.com/GoogleCloudPlatform/magic…
slevenick Oct 17, 2018
c393fa1
Fix inspec branch name
slevenick Oct 17, 2018
665a8b8
Merge branch 'master' into HEAD
slevenick Oct 17, 2018
051cfca
Adding excludes for resources
slevenick Oct 17, 2018
27edcf1
Merge branch 'ground-up-2' into temp
slevenick Oct 17, 2018
6166843
Merge branch 'ground-up-2' into ground-up-3
slevenick Oct 17, 2018
19e7706
Making PR simple
slevenick Oct 17, 2018
16bbe05
Merge branch 'ground-up-2' into ground-up-3
slevenick Oct 17, 2018
15c1ded
Unused code
slevenick Oct 17, 2018
517e065
Remove unused code
slevenick Oct 17, 2018
5c121cf
Rubocop fixes
slevenick Oct 17, 2018
de95378
Rubocop fixes
slevenick Oct 17, 2018
c58634d
Merge branch 'ground-up-2' into ground-up-3
slevenick Oct 17, 2018
777272b
Merge branch 'ground-up-3' into ground-up-4
slevenick Oct 17, 2018
0c13898
Merge branch 'ground-up-4' into ground-up-5
slevenick Oct 17, 2018
bc71bff
Input is fine
slevenick Oct 17, 2018
619941c
Merge branch 'master' into ground-up-3
slevenick Oct 17, 2018
ac73051
Backporting things
slevenick Oct 17, 2018
693edd9
Merge branch 'ground-up-3' into ground-up-4
slevenick Oct 17, 2018
38e652f
Spacing for rubocop
slevenick Oct 17, 2018
06c73d9
Rubocop
slevenick Oct 17, 2018
0583ac6
Fixing up time parsing, input only stuff
slevenick Oct 17, 2018
ac12bb6
prop.input is fine
slevenick Oct 18, 2018
957ad0c
Requires improvements
slevenick Oct 18, 2018
a59fe2f
Improve requires generation
slevenick Oct 18, 2018
f5b82dd
Rubocop
slevenick Oct 18, 2018
6688934
Refactoring, comments
slevenick Oct 19, 2018
4461550
Merge branch 'ground-up-3' into ground-up-4
slevenick Oct 19, 2018
ff347b1
Merge branch 'ground-up-4' into ground-up-5
slevenick Oct 19, 2018
b19e003
Merge branch 'ground-up-5' into ground-up-6
slevenick Oct 19, 2018
15257fe
First pass at generating docs for resources
slevenick Oct 19, 2018
98c0832
Remove extra code for sql
slevenick Oct 19, 2018
ffc450e
Merge branch 'ground-up-4' into ground-up-5
slevenick Oct 19, 2018
62c296a
Merge branch 'ground-up-5' into ground-up-6
slevenick Oct 19, 2018
ba40d67
Add wrapped resource handling
slevenick Oct 19, 2018
d0f6217
Add tests, datetime fixes
slevenick Oct 22, 2018
b2ad7b8
Add real tests
slevenick Oct 22, 2018
70b137b
Spacing
slevenick Oct 22, 2018
0e42763
Adding tests, not sure if CI will work.
slevenick Oct 23, 2018
43b94d5
Adding instance
slevenick Oct 23, 2018
e650fd4
Merge branch 'master' into ground-up-6
slevenick Oct 23, 2018
6a0bd63
Spacing
slevenick Oct 23, 2018
9e2eee6
requires fixes
slevenick Oct 23, 2018
cec8036
Refactor a bit, rubocop
slevenick Oct 24, 2018
fb82839
Merge branch 'ground-up-6' into ground-up-7
slevenick Oct 24, 2018
db28247
Add bundle install
slevenick Oct 24, 2018
de72a6e
Add hash& string utils, ci
slevenick Oct 24, 2018
fadcf6d
Merge branch 'ground-up-6' into ground-up-7
slevenick Oct 24, 2018
dbe395a
Test fixes
slevenick Oct 24, 2018
3903a08
Spacing
slevenick Oct 24, 2018
fc269ca
Add instance test
slevenick Oct 24, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .ci/unit-tests/inspec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@
set -e
set -x

echo 'TODO slevenick write tests'
echo 'TODO slevenick write tests'
pushd "magic-modules/build/inspec/libraries"

bundle install
rspec -I . ../test/unit/*

popd
82 changes: 40 additions & 42 deletions products/compute/inspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,87 +20,85 @@ manifest: !ruby/object:Provider::Inspec::Manifest
description: |
InSpec resources for verifying GCP infrastructure
overrides: !ruby/object:Provider::ResourceOverrides
Address: !ruby/object:Provider::Chef::ResourceOverride
Address: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Autoscaler: !ruby/object:Provider::Chef::ResourceOverride
Autoscaler: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
BackendBucket: !ruby/object:Provider::Chef::ResourceOverride
BackendBucket: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
BackendService: !ruby/object:Provider::Chef::ResourceOverride
BackendService: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Disk: !ruby/object:Provider::Chef::ResourceOverride
Disk: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
DiskType: !ruby/object:Provider::Chef::ResourceOverride
DiskType: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Firewall: !ruby/object:Provider::Chef::ResourceOverride
ForwardingRule: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
ForwardingRule: !ruby/object:Provider::Chef::ResourceOverride
GlobalAddress: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
GlobalAddress: !ruby/object:Provider::Chef::ResourceOverride
GlobalForwardingRule: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
GlobalForwardingRule: !ruby/object:Provider::Chef::ResourceOverride
HealthCheck: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
HealthCheck: !ruby/object:Provider::Chef::ResourceOverride
HttpHealthCheck: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
HttpHealthCheck: !ruby/object:Provider::Chef::ResourceOverride
HttpsHealthCheck: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
HttpsHealthCheck: !ruby/object:Provider::Chef::ResourceOverride
Image: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Image: !ruby/object:Provider::Chef::ResourceOverride
InstanceGroup: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Instance: !ruby/object:Provider::Chef::ResourceOverride
InstanceGroupManager: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
InstanceGroup: !ruby/object:Provider::Chef::ResourceOverride
InstanceTemplate: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
InstanceGroupManager: !ruby/object:Provider::Chef::ResourceOverride
InterconnectAttachment: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
InstanceTemplate: !ruby/object:Provider::Chef::ResourceOverride
License: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
InterconnectAttachment: !ruby/object:Provider::Chef::ResourceOverride
MachineType: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
License: !ruby/object:Provider::Chef::ResourceOverride
Network: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
MachineType: !ruby/object:Provider::Chef::ResourceOverride
Region: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Network: !ruby/object:Provider::Chef::ResourceOverride
RegionAutoscaler: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Region: !ruby/object:Provider::Chef::ResourceOverride
RegionDisk: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
RegionAutoscaler: !ruby/object:Provider::Chef::ResourceOverride
RegionDiskType: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
RegionDisk: !ruby/object:Provider::Chef::ResourceOverride
Route: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
RegionDiskType: !ruby/object:Provider::Chef::ResourceOverride
Router: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Route: !ruby/object:Provider::Chef::ResourceOverride
Snapshot: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Router: !ruby/object:Provider::Chef::ResourceOverride
SslCertificate: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Snapshot: !ruby/object:Provider::Chef::ResourceOverride
SslPolicy: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
SslCertificate: !ruby/object:Provider::Chef::ResourceOverride
Subnetwork: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
SslPolicy: !ruby/object:Provider::Chef::ResourceOverride
TargetHttpProxy: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
Subnetwork: !ruby/object:Provider::Chef::ResourceOverride
TargetHttpsProxy: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
TargetHttpProxy: !ruby/object:Provider::Chef::ResourceOverride
TargetPool: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
TargetHttpsProxy: !ruby/object:Provider::Chef::ResourceOverride
TargetTcpProxy: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
TargetPool: !ruby/object:Provider::Chef::ResourceOverride
TargetVpnGateway: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
TargetTcpProxy: !ruby/object:Provider::Chef::ResourceOverride
TargetSslProxy: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
TargetVpnGateway: !ruby/object:Provider::Chef::ResourceOverride
UrlMap: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
TargetSslProxy: !ruby/object:Provider::Chef::ResourceOverride
exclude: true
UrlMap: !ruby/object:Provider::Chef::ResourceOverride
exclude: true
VpnTunnel: !ruby/object:Provider::Chef::ResourceOverride
VpnTunnel: !ruby/object:Provider::Inspec::ResourceOverride
exclude: true
files: !ruby/object:Provider::Config::Files
copy:
<%= lines(indent(compile('provider/inspec/common~copy.yaml'), 4)) -%>
style:
functions:
changelog:
Expand Down
17 changes: 11 additions & 6 deletions provider/inspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def property_override
# This function uses the resource templates to create singular and plural
# resources that can be used by InSpec
def generate_resource(data)
target_folder = File.join(data[:output_folder], 'inspec')
target_folder = File.join(data[:output_folder], 'libraries')
FileUtils.mkpath target_folder
name = data[:object].name.underscore
generate_resource_file data.clone.merge(
Expand All @@ -58,7 +58,7 @@ def generate_resource(data)
generate_documentation(data)
end

# Generates InSpec markdown documents for the resource
# Generates InSpec markdown documents for the resource
def generate_documentation(data)
name = data[:object].name.underscore
docs_folder = File.join(data[:output_folder], 'docs', 'resources')
Expand All @@ -74,8 +74,12 @@ def format_url(url)
url.split("\n").join('')
end

# TODO?
def generate_resource_tests(data) end
# Copies InSpec unit tests to build folder
def generate_resource_tests(data)
target_folder = File.join(data[:output_folder], 'test/unit')
FileUtils.mkpath target_folder
FileUtils.cp_r 'templates/inspec/tests/.', target_folder
end

def generate_base_property(data) end

Expand Down Expand Up @@ -178,7 +182,7 @@ def resource_name(object, product_ns)
"google_#{product_ns.downcase}_#{object.name.underscore}"
end

def sub_property_descriptions(property)
def sub_property_descriptions(property)
if nested_object?(property)
return property.properties.map \
{ |prop| " * `#{prop.name}`: #{prop.description}" }.join("\n")
Expand All @@ -188,7 +192,8 @@ def sub_property_descriptions(property)
return property.item_type.properties.map \
{ |prop| " * `#{prop.name}`: #{prop.description}" }.join("\n")
end
# rubocop:enable Style/GuardClause
end
# rubocop:enable Style/GuardClause
end
# rubocop:enable Metrics/ClassLength
end
17 changes: 17 additions & 0 deletions provider/inspec/common~copy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# These files are okay to be copied "AS-IS" to the module's final destination:

'libraries/google/hash_utils.rb': 'google/hash_utils.rb'
'libraries/google/string_utils.rb': 'google/string_utils.rb'
2 changes: 1 addition & 1 deletion templates/inspec/nested_object.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module Google
<% nested_properties.each do |prop| -%>
<%
if time?(prop)
init = "Time.new(args['#{prop.api_name}'])"
init = "DateTime.parse(args['#{prop.api_name}'])"
elsif primitive?(prop)
init = "args['#{prop.api_name}']"
elsif typed_array?(prop)
Expand Down
1 change: 1 addition & 0 deletions templates/inspec/plural_resource.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<%= lines(autogen_notice :ruby) -%>

require 'inspec/resource'
class <%= object.name -%>s < Inspec.resource(1)

<%
Expand Down
57 changes: 52 additions & 5 deletions templates/inspec/singular_resource.erb
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,16 @@ class <%= object.name -%> < Inspec.resource(1)
parse unless @fetched.nil?
end
<% else # object.self_link_query.nil? -%>
# TODO(slevenick) for other products
def initialize(params)
raise 'Not implemented'
end
def initialize(params)
@fetched = <%= method_call('fetch_wrapped_resource',
[
'params',
"'#{object.kind}'",
"'#{object.self_link_query.kind}'",
"'#{object.self_link_query.items}'"
], 2) %>
parse unless @fetched.nil?
end
<% end # object.self_link_query.nil? -%>

def fetch_resource(params)
Expand Down Expand Up @@ -84,7 +90,7 @@ class <%= object.name -%> < Inspec.resource(1)
name = prop.out_name

if time?(prop)
init = "Time.new(@fetched['#{prop.api_name}'])"
init = "DateTime.parse(@fetched['#{prop.api_name}'])"
elsif primitive?(prop)
init = "@fetched['#{prop.api_name}']"
elsif typed_array?(prop)
Expand All @@ -102,4 +108,45 @@ class <%= object.name -%> < Inspec.resource(1)
def exists?
!@fetched.nil?
end

<% unless object.self_link_query.nil? -%>
def fetch_wrapped_resource(params, kind, wrap_kind, wrap_path)
result = fetch_resource(params, wrap_kind)
return if result.nil? || !result.key?(wrap_path)
result = unwrap_resource(result[wrap_path], params)
return if result.nil?
raise "Incorrect result: #{result['kind']} (expected #{kind})" \
unless result['kind'] == kind
result
end


def unwrap_resource(result, resource)
query_predicate = unwrap_resource_filter(resource)
matches = result.select do |entry|
query_predicate.all? do |k, v|
entry[k.id2name] == v
end
end
raise "More than 1 result found: #{matches}" if matches.size > 1
return if matches.empty?
matches.first
end

<%
urf_code = [
'{',
indent_list(
Hash[object.identity.map { |i| [i, "resource[:#{property_out_name(i)}]"] }]
.map { |k, v| "#{k.out_name}: #{v}" }, 2
),
'}'
]
-%>
def unwrap_resource_filter(resource)
self.class.unwrap_resource_filter(resource)
end
<%= lines(indent(emit_method('self.unwrap_resource_filter', %w[resource],
urf_code, file_relative), 2), 1) -%>
<% end # object.self_link_query.nil? -%>
end
61 changes: 61 additions & 0 deletions templates/inspec/tests/firewall_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'google_compute_firewall'

class FirewallTest < Firewall
def initialize(data)
@fetched = data
end
end
description = "My description"
firewall_fixture = {"kind"=>"compute#firewall",
"id"=>"960238098441931407",
"creationTimestamp"=>"2018-10-11T22:42:56.000-07:00",
"name"=>"default-uuaca3r2wn7yqlbdyzue5lrn",
"description"=>description,
"network"=>
"https://www.googleapis.com/compute/v1/projects/sam-inspec/global/networks/default",
"priority"=>1000,
"sourceRanges"=>
["103.104.152.0/22",
"104.132.0.0/14",
"113.197.104.0/22",
"185.25.28.0/22",
"193.200.222.0/24",
"89.207.224.0/21"],
"targetTags"=>["https-server"],
"allowed"=>[{"IPProtocol"=>"tcp", "ports"=>["443"]}],
"denied"=>[{"IPProtocol"=>"udp", "ports"=>["555"]}],
"direction"=>"INGRESS",
"disabled"=>false,
"selfLink"=>
"https://www.googleapis.com/compute/v1/projects/sam-inspec/global/firewalls/default-uuaca3r2wn7yqlbdyzue5lrn"}


RSpec.describe Firewall, '#parse' do
before do
@firewall_mock = FirewallTest.new(firewall_fixture)
@firewall_mock.parse
end
context 'firewall attributes' do
it { expect(@firewall_mock.exists?).to be true }
it { expect(@firewall_mock.creation_timestamp).to eq Time.at(1539322976).to_datetime }
it { expect(@firewall_mock.description).to eq description }
it { expect(@firewall_mock.allowed.size).to be 1 }
it { expect(@firewall_mock.allowed[0].ip_protocol).to eq 'tcp' }
it { expect(@firewall_mock.allowed[0].ports).to include "443" }
it { expect(@firewall_mock.denied.size).to be 1 }
it { expect(@firewall_mock.denied[0].ip_protocol).to eq 'udp' }
it { expect(@firewall_mock.denied[0].ports).to include "555" }
it { expect(@firewall_mock.direction).to eq 'INGRESS' }
it { expect(@firewall_mock.network).to match('/default$') }
it { expect(@firewall_mock.source_ranges).to include "113.197.104.0/22" }

end
end


no_firewall = FirewallTest.new(nil)
RSpec.describe Firewall, "#parse" do
it "does not exist" do
expect(no_firewall.exists?).to be false
end
end
Loading