Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion build/inspec
2 changes: 1 addition & 1 deletion build/terraform
61 changes: 47 additions & 14 deletions provider/inspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,28 +101,61 @@ def emit_nested_object_overrides(data)
)
end

def primitive? (property)
return property.is_a?(::Api::Type::Primitive) || (property.is_a?(Api::Type::Array) && !property.item_type.is_a?(::Api::Type::NestedObject))
# Figuring out if a property is a primitive ruby type is a hassle. But it is important
# Fingerprints are strings, NameValues are hashes, and arrays of primitives are arrays
# Arrays of NestedObjects need to have their contents parsed and returned in an array
# ResourceRefs are strings
def primitive?(property)
array_primitive = (property.is_a?(Api::Type::Array)\
&& !property.item_type.is_a?(::Api::Type::NestedObject))
property.is_a?(::Api::Type::Primitive)\
|| array_primitive\
|| property.is_a?(::Api::Type::NameValues)\
|| property.is_a?(::Api::Type::Fingerprint)\
|| property.is_a?(::Api::Type::ResourceRef)
end

def resource_ref? (property)
return property.is_a?(::Api::Type::ResourceRef)
# Arrays of nested objects need special requires statements
def typed_array?(property)
property.is_a?(::Api::Type::Array) && nested_object?(property.item_type)
end

def typed_array? (property)
return property.is_a?(::Api::Type::Array)
def nested_object?(property)
property.is_a?(::Api::Type::NestedObject)
end

def nested_object? (property)
return property.is_a?(::Api::Type::NestedObject)
# Only arrays of nested objects and nested object properties need require statements
# for InSpec. Primitives are all handled natively
def generate_requires(properties)
nested_props = properties.select { |type| nested_object?(type) }
nested_object_arrays = properties.select\
{ |type| typed_array?(type) && nested_object?(type.item_type) }
nested_array_requires = nested_object_arrays.collect { |type| array_requires(type) }
# Need to include requires statements for the requirements of a nested object
# TODO is this needed? Not sure how ruby works so well
nested_prop_requires = nested_props.map\
{ |nested_prop| generate_requires(nested_prop.properties) }
nested_object_requires = nested_props.map\
{ |nested_object| nested_object_requires(nested_object) }
nested_object_requires + nested_prop_requires + nested_array_requires
end

def generate_requires(properties, requires = [])
nested_props = properties.select{ |type| nested_object?(type) }
requires.concat(properties.reject{ |type| primitive?(type) || resource_ref?(type) || nested_object?(type) }.collect(&:requires))
requires.concat(nested_props.map{|nested_prop| generate_requires(nested_prop.properties) } )
requires.concat(nested_props.map{|nested_prop| nested_prop.property_file })
requires
def array_requires(type)
File.join(
'google',
type.__resource.__product.prefix[1..-1],
'property',
[type.__resource.name.downcase, type.item_type.name.underscore].join('_')
)
end

def nested_object_requires(nested_object_type)
File.join(
'google',
nested_object_type.__resource.__product.prefix[1..-1],
'property',
[nested_object_type.__resource.name, nested_object_type.name.underscore].join('_')
).downcase
end
end
end
28 changes: 15 additions & 13 deletions templates/inspec/singular_resource.erb
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,27 @@ class <%= object.name -%> < Inspec.resource(1)
end

<% if object.self_link_query.nil? -%>
def initialize(params)
@fetched = <%= method_call('fetch_resource', ['params', ("'#{object.kind}'" if object.kind?)], 2) %>
parse unless @fetched.nil?
end
<% else # object.self_link_query.nil? -%>
def initialize(params)
@fetched = <%= method_call('fetch_wrapped_resource', ['params', ("'#{object.kind}'" if object.kind?),
"'#{object.self_link_query.kind}'",
"'#{object.self_link_query.items}'"], 2) %>
def initialize(params)
@fetched = fetch_resource(params)
parse unless @fetched.nil?
end
<% else # object.self_link_query.nil? -%>
# TODO(slevenick) for other products
def initialize(params)
raise 'Not implemented'
end
<% end # object.self_link_query.nil? -%>

def fetch_resource(params)
get_request = inspec.backend.fetch(base, url, params)
end

def parse
<%
fetch_code = object.properties.map do |prop|
<%
parse_code = object.properties.map do |prop|
name = prop.out_name

if primitive?(prop) || resource_ref?(prop)
if primitive?(prop)
init = "@fetched['#{prop.api_name}']"
elsif typed_array?(prop)
init = "#{prop.property_type}.parse(@fetched['#{prop.api_name}'])"
Expand All @@ -76,7 +78,7 @@ class <%= object.name -%> < Inspec.resource(1)
assignment = "@#{name} = #{init}"
end
-%>
<%= lines(indent(fetch_code, 4)) -%>
<%= lines(indent(parse_code, 4)) -%>
end

def exists?
Expand Down