Skip to content

Commit

Permalink
fix nested query
Browse files Browse the repository at this point in the history
  • Loading branch information
emilymye committed May 29, 2019
1 parent 78b5376 commit 04c418f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 49 deletions.
110 changes: 64 additions & 46 deletions templates/terraform/nested_query.go.erb
Original file line number Diff line number Diff line change
@@ -1,54 +1,72 @@
var v interface{}
var ok bool
var v interface{}
var ok bool

<% object.nested_query.keys[0...-1].each do |k| -%>
v, ok = res["<%=k-%>"]
if !ok || v == nil {
return nil, nil
}
res = v.(map[string]interface{})
v, ok = res["<%=k-%>"]
if !ok || v == nil {
return nil, nil
}
res = v.(map[string]interface{})

<% end -%>
v, ok = res["<%=object.nested_query.keys[-1]-%>"]
if !ok || v == nil {
return nil, nil
}

// Final nested resource is either a list of resources we need to filter
// or just the resource itself, which we return.
switch v.(type) {
case []interface{}:
break
case map[string]interface{}:
return v.(map[string]interface{}), nil
default:
return nil, fmt.Errorf("invalid value for <%= object.nested_query.keys.join(".") -%>: %v", v)
}

items := v.([]interface{})
for _, vRaw := range items {
v, ok = res["<%=object.nested_query.keys[-1]-%>"]
if !ok || v == nil {
return nil, nil
}

switch v.(type) {
case []interface{}:
break
case map[string]interface{}:
// Construct list out of single nested resource
v = []interface{}{v}
default:
return nil, fmt.Errorf("expected list or map for value <%= object.nested_query.keys.join(".") -%>. Actual value: %v", v)
}

<% object.identity.each do |prop| -%>
<% if settable_properties.include?(prop) -%>
expected<%= titlelize_property(prop) -%>, err := expand<%= resource_name -%><%= titlelize_property(prop) -%>(d.Get("<%= prop.name.underscore -%>"), d, meta.(*Config))
if err != nil {
return nil, err
}
<% else -%>
expected<%= titlelize_property(prop) -%> := d.Get("<%= prop.name.underscore -%>")
<% end # settable_properties.include?(prop)-%>
<% end # object.identity.each -%>

// Search list for this resource.
items := v.([]interface{})
for _, itemRaw := range items {
if itemRaw == nil {
continue
}
<% if object.nested_query.is_list_of_ids -%>
// If only an id is given in parent resource,
// construct a resource map for that id KV pair.
item := map[string]interface{}{"<%=object.identity.first.api_name%>": vRaw}
// List response only contains the ID - construct a response object.
item := map[string]interface{}{
"<%=object.identity.first.api_name%>": itemRaw,
}
<% else -%>
item := vRaw.(map[string]interface{})
item := itemRaw.(map[string]interface{})
<% end -%>

<% if object.custom_code.decoder -%>
// Decode list item before comparing.
item, err := resource<%= resource_name -%>Decoder(d, meta, item)
if err != nil {
return nil, err
}
<% end -%>

<% object.identity.each do |prop| -%>
<% if settable_properties.include?(prop) -%>
itemIdV, err := expand<%= resource_name -%><%= titlelize_property(prop) -%>(d.Get("<%= prop.name.underscore -%>"), d, meta.(*Config))
if err != nil {
return nil, err
}
<% else -%>
itemIdV := d.Get("<%= prop.name.underscore -%>")
<% end # settable_properties.include?(prop)-%>
actualIdV := flatten<%= resource_name -%><%= titlelize_property(prop) -%>(item["<%= prop.api_name %>"], d)
log.Printf("[DEBUG] Checking if item's <%= prop.api_name %> (%#v) is equal to resource's (%#v)", itemIdV, actualIdV)
if !reflect.DeepEqual(itemIdV, actualIdV) {
continue
}
<% end # object.identity.each -%>
return item, nil
}
return nil, nil
item<%= titlelize_property(prop) -%> := flatten<%= resource_name -%><%= titlelize_property(prop) -%>(item["<%= prop.api_name %>"], d)
if !reflect.DeepEqual(item<%= titlelize_property(prop) -%>, expected<%= titlelize_property(prop) -%>) {
log.Printf("[DEBUG] Skipping item with <%= prop.api_name %>= %#v, looking for %#v)", item<%= titlelize_property(prop) -%>, expected<%= titlelize_property(prop) -%>)
continue
}
<% end -%>
log.Printf("[DEBUG] Found item for resource %q: %#v)", d.Id(), item)
return item, nil
}

return nil, nil
6 changes: 3 additions & 3 deletions templates/terraform/resource.erb
Original file line number Diff line number Diff line change
Expand Up @@ -578,15 +578,15 @@ func resource<%= resource_name -%>UpdateEncoder(d *schema.ResourceData, meta int
<% end -%>

<% if object.nested_query -%>
<%# Note that if both nested_uqery and custom_code.decoder are provided,
#the decoder will be included via nested_query.go.erb -%>
func flattenNested<%= resource_name -%>(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
<%= compile_template('templates/terraform/nested_query.go.erb',
object: object,
settable_properties: object.settable_properties,
resource_name: resource_name) -%>
}
<% end -%>

<% if object.custom_code.decoder -%>
<% elsif object.custom_code.decoder -%>
func resource<%= resource_name -%>Decoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
<%= lines(compile(object.custom_code.decoder)) -%>
}
Expand Down

0 comments on commit 04c418f

Please sign in to comment.