From e7b703edc0f1c262cfd7f25f4a186aed5dd04102 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 12 Oct 2018 14:01:37 -0700 Subject: [PATCH 01/11] Add nested objects and parsing logic --- provider/inspec.rb | 40 ++++++++++++++++++++++++-- templates/inspec/nested_object.erb | 40 ++++++++++++++++++++++++++ templates/inspec/singular_resource.erb | 19 +++++++++++- 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 templates/inspec/nested_object.erb diff --git a/provider/inspec.rb b/provider/inspec.rb index 5c309a87d08a..3bd7dba091f8 100644 --- a/provider/inspec.rb +++ b/provider/inspec.rb @@ -65,8 +65,44 @@ def generate_typed_array(data, prop) end def emit_resourceref_object(data) end - def emit_nested_object(data) end - def generate_network_datas(data, object) end + + def emit_nested_object(data) + target = if data[:emit_array] + data[:property].item_type.property_file + else + data[:property].property_file + end + { + source: File.join('templates', 'inspec', 'nested_object.erb'), + target: "libraries/#{target}.rb", + overrides: emit_nested_object_overrides(data) + } + end + + def emit_nested_object_overrides(data) + data.clone.merge( + api_name: data[:api_name].camelize(:upper), + object_type: data[:obj_name].camelize(:upper), + product_ns: data[:product_name].camelize(:upper), + class_name: if data[:emit_array] + data[:property].item_type.property_class.last + else + data[:property].property_class.last + end + ) + 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)) + end + + def resource_ref? (property) + return property.is_a?(::Api::Type::ResourceRef) + end + + def typed_array? (property) + return property.is_a?(::Api::Type::Array) + end end end diff --git a/templates/inspec/nested_object.erb b/templates/inspec/nested_object.erb new file mode 100644 index 000000000000..a41299cd137b --- /dev/null +++ b/templates/inspec/nested_object.erb @@ -0,0 +1,40 @@ +<%# The license inside this block applies to this file. +# 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. +-%> +<%= compile('templates/license.erb') -%> + +<%= lines(autogen_notice :ruby) -%> + +module Google + module <%= product_ns %> + module Property + class <%= class_name -%> + + def initialize(args = nil) + return nil + end + end + +<% if emit_array -%> + class <%= class_name %>Array + def self.parse(value) + return if value.nil? + return <%= class_name %>.new(value) unless value.is_a?(::Array) + value.map { |v| <%= class_name %>.new(v) } + end + end +<% end #if emit_array -%> + end + end +end \ No newline at end of file diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index 8251616a6796..1495fa55c5c6 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -66,7 +66,24 @@ url = "'#{url}'" <% end # object.self_link_query.nil? -%> # TODO - def parse end + def parse + <% + fetch_code = object.properties.reject(&:input).map do |prop| + name = prop.out_name + + if primitive?(prop) || resource_ref?(prop) + init = "@fetched['#{prop.api_name}']" + elsif typed_array?(prop) + init = "#{prop.property_type}.parse(@fetched['#{prop.api_name}'])" + else + init = "#{prop.property_type}.new(@fetched['#{prop.api_name}'])" + end + + assignment = "@#{name} = #{init}" + end +-%> +<%= lines(indent(fetch_code, 4)) -%> + end def exists? !@fetched.nil? From d8d6b8534bd7ef959e9ebd9a459616a3c61e5639 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 12 Oct 2018 14:04:47 -0700 Subject: [PATCH 02/11] Remove todo --- templates/inspec/singular_resource.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index 1495fa55c5c6..f248f8181ec3 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -65,7 +65,6 @@ url = "'#{url}'" end <% end # object.self_link_query.nil? -%> - # TODO def parse <% fetch_code = object.properties.reject(&:input).map do |prop| From b9815968dcd917db3054b3e02cbd091fab464691 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 12 Oct 2018 14:25:05 -0700 Subject: [PATCH 03/11] Add nested constructor --- templates/inspec/nested_object.erb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/templates/inspec/nested_object.erb b/templates/inspec/nested_object.erb index a41299cd137b..9e4bc5b78c8d 100644 --- a/templates/inspec/nested_object.erb +++ b/templates/inspec/nested_object.erb @@ -22,10 +22,23 @@ module Google class <%= class_name -%> def initialize(args = nil) - return nil + return nil if args.nil? +<% nested_properties.each do |prop| -%> +<% + if primitive?(prop) + init = "args['#{prop.api_name}']" + elsif typed_array?(prop) + init = "#{prop.property_type}.parse(args['#{prop.api_name}'])" + else + init = "#{prop.property_type}.new(args['#{prop.api_name}'])" + end + parse_code = "@#{prop.out_name} = #{init}" +-%> +<%= lines(indent(parse_code, 10)) -%> +<% end # nested_properties.each -%> end end - + <% if emit_array -%> class <%= class_name %>Array def self.parse(value) From 1993bf5e771b221cb4f40fbb3c9b6abfbf5723ec Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 12 Oct 2018 14:26:39 -0700 Subject: [PATCH 04/11] Add attr readers for nested object --- templates/inspec/nested_object.erb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/templates/inspec/nested_object.erb b/templates/inspec/nested_object.erb index 9e4bc5b78c8d..ed5e4280b978 100644 --- a/templates/inspec/nested_object.erb +++ b/templates/inspec/nested_object.erb @@ -21,6 +21,13 @@ module Google module Property class <%= class_name -%> +<% if !nested_properties.empty? -%> +<% nested_properties.each do |prop| -%> + attr_reader :<%= prop.out_name %> +<% end # nested_properties.each -%> + +<% end # if !nested_properties.empty? -%> + def initialize(args = nil) return nil if args.nil? <% nested_properties.each do |prop| -%> From ec005438bcd97535aa2da3b046801423218f0d60 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Fri, 12 Oct 2018 14:46:56 -0700 Subject: [PATCH 05/11] Add basic requires --- provider/inspec.rb | 12 ++++++++++++ templates/inspec/singular_resource.erb | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/provider/inspec.rb b/provider/inspec.rb index 3bd7dba091f8..dbf08a36d308 100644 --- a/provider/inspec.rb +++ b/provider/inspec.rb @@ -104,5 +104,17 @@ def resource_ref? (property) def typed_array? (property) return property.is_a?(::Api::Type::Array) end + + def nested_object? (property) + return property.is_a?(::Api::Type::NestedObject) + 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 + end end end diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index f248f8181ec3..4d69292f0932 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -16,6 +16,17 @@ <%= lines(autogen_notice :ruby) -%> +<% + require 'google/string_utils' + + inside_indent = 8 + + requires = generate_requires(object.all_user_properties) + requires << 'inspec/resource' + requires << 'google/hash_utils' +-%> +<%= lines(emit_requires(requires)) -%> + # A provider to manage <%= @api.name -%> resources. <%= lines(indent( emit_rubocop(binding, :class, From 19e7706691f55c3e203c6084a4cb0905878c88cd Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 17 Oct 2018 12:40:39 -0700 Subject: [PATCH 06/11] Making PR simple --- provider/inspec.rb | 12 +++++++++ templates/inspec/singular_resource.erb | 34 +++----------------------- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/provider/inspec.rb b/provider/inspec.rb index 5c309a87d08a..0345db85a5f0 100644 --- a/provider/inspec.rb +++ b/provider/inspec.rb @@ -54,6 +54,18 @@ def generate_resource(data) ) end + # Returns the url that this object can be retrieved from + # based off of the self link + def url(object) + url = object.self_link_url[1] + if url.is_a?(Array) + url = url.join('') + else + url = url.split("\n").join('') + end + url + end + # TODO? def generate_resource_tests(data) end diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index 8251616a6796..00c2784bbc2d 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -17,54 +17,28 @@ <%= lines(autogen_notice :ruby) -%> # A provider to manage <%= @api.name -%> resources. -<%= lines(indent( - emit_rubocop(binding, :class, - ['Google', @api.prefix.upcase, object.name].join('::'), - :disabled), - 4)) -%> class <%= object.name -%> < Inspec.resource(1) name 'google_<%= product_ns.downcase -%>_<%= object.name.downcase -%>' desc '<%= object.name -%>' supports platform: 'gcp-mm' -<% object.properties.reject(&:input).each do |prop| -%> +<% object.properties.each do |prop| -%> <%= "attr_reader :#{prop.out_name}" -%> <% end -%> <% -base = "'#{object.self_link_url[0].join}'" -url = object.self_link_url[1] -if url.is_a?(Array) - url = url.join('') -else - url = url.split("\n").join('') -end -url = "'#{url}'" +base = "''" -%> def base - <%= base %> + '<%= object.self_link_url[0].join %>' end def url - <%= url %> + '<%= url(object) %>' 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) %> - parse unless @fetched.nil? - end -<% end # object.self_link_query.nil? -%> - # TODO def parse end From 15c1ded61e10f18be88446246ace6455114e688d Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 17 Oct 2018 12:41:54 -0700 Subject: [PATCH 07/11] Unused code --- templates/inspec/singular_resource.erb | 3 --- 1 file changed, 3 deletions(-) diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index 34b9cb2d6127..fd8b83606697 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -39,9 +39,6 @@ class <%= object.name -%> < Inspec.resource(1) <% end -%> -<% -base = "''" --%> def base '<%= object.self_link_url[0].join %>' end From 517e065c8068b20ab36b2f007b091bb8c6452e4f Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 17 Oct 2018 12:42:54 -0700 Subject: [PATCH 08/11] Remove unused code --- templates/inspec/singular_resource.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index 00c2784bbc2d..0858313284a5 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -27,10 +27,6 @@ class <%= object.name -%> < Inspec.resource(1) <%= "attr_reader :#{prop.out_name}" -%> <% end -%> - -<% -base = "''" --%> def base '<%= object.self_link_url[0].join %>' end From 5c121cf1d0775c4d1391869249fefbed57f448ab Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 17 Oct 2018 12:53:58 -0700 Subject: [PATCH 09/11] Rubocop fixes --- provider/inspec.rb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/provider/inspec.rb b/provider/inspec.rb index 0345db85a5f0..e2f299adc386 100644 --- a/provider/inspec.rb +++ b/provider/inspec.rb @@ -54,16 +54,12 @@ def generate_resource(data) ) end - # Returns the url that this object can be retrieved from + # Returns the url that this object can be retrieved from # based off of the self link def url(object) url = object.self_link_url[1] - if url.is_a?(Array) - url = url.join('') - else - url = url.split("\n").join('') - end - url + return url.join('') if url.is_a?(Array) + return url.split("\n").join('') end # TODO? From de953789bb5a98d7870b6eca5624a44761837f1e Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 17 Oct 2018 12:58:02 -0700 Subject: [PATCH 10/11] Rubocop fixes --- provider/inspec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/inspec.rb b/provider/inspec.rb index e2f299adc386..69439d7b94de 100644 --- a/provider/inspec.rb +++ b/provider/inspec.rb @@ -59,7 +59,7 @@ def generate_resource(data) def url(object) url = object.self_link_url[1] return url.join('') if url.is_a?(Array) - return url.split("\n").join('') + url.split("\n").join('') end # TODO? From bc71bff551d4f801f21e0bedf91bdf399f475cf8 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 17 Oct 2018 13:26:25 -0700 Subject: [PATCH 11/11] Input is fine --- templates/inspec/singular_resource.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb index 6921740ffcdb..1a8056d7daa3 100644 --- a/templates/inspec/singular_resource.erb +++ b/templates/inspec/singular_resource.erb @@ -62,7 +62,7 @@ class <%= object.name -%> < Inspec.resource(1) def parse <% - fetch_code = object.properties.reject(&:input).map do |prop| + fetch_code = object.properties.map do |prop| name = prop.out_name if primitive?(prop) || resource_ref?(prop)