Skip to content

Commit

Permalink
[Bug Fix - azurerm_api_management_api_operation] - Handling example.v…
Browse files Browse the repository at this point in the history
…alue none-string types (#14848)

* Merge remote-tracking branch 'upstream/main'

* rename func name

* suppress example.value json diffs

* use existing JSON diff suppress

Co-authored-by: Steph <[email protected]>
  • Loading branch information
xuzhang3 and stephybun authored Apr 7, 2022
1 parent 93624f1 commit fe79aab
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,18 @@ func resourceApiManagementApiOperationRead(d *pluginsdk.ResourceData, meta inter
d.Set("method", props.Method)
d.Set("url_template", props.URLTemplate)

flattenedRequest := flattenApiManagementOperationRequestContract(props.Request)
flattenedRequest, err := flattenApiManagementOperationRequestContract(props.Request)
if err != nil {
return err
}
if err := d.Set("request", flattenedRequest); err != nil {
return fmt.Errorf("flattening `request`: %+v", err)
}

flattenedResponse := flattenApiManagementOperationResponseContract(props.Responses)
flattenedResponse, err := flattenApiManagementOperationResponseContract(props.Responses)
if err != nil {
return err
}
if err := d.Set("response", flattenedResponse); err != nil {
return fmt.Errorf("flattening `response`: %+v", err)
}
Expand Down Expand Up @@ -284,9 +290,9 @@ func expandApiManagementOperationRequestContract(d *pluginsdk.ResourceData, sche
}, nil
}

func flattenApiManagementOperationRequestContract(input *apimanagement.RequestContract) []interface{} {
func flattenApiManagementOperationRequestContract(input *apimanagement.RequestContract) ([]interface{}, error) {
if input == nil {
return []interface{}{}
return []interface{}{}, nil
}

output := make(map[string]interface{})
Expand All @@ -297,9 +303,13 @@ func flattenApiManagementOperationRequestContract(input *apimanagement.RequestCo

output["header"] = schemaz.FlattenApiManagementOperationParameterContract(input.Headers)
output["query_parameter"] = schemaz.FlattenApiManagementOperationParameterContract(input.QueryParameters)
output["representation"] = schemaz.FlattenApiManagementOperationRepresentation(input.Representations)
representation, err := schemaz.FlattenApiManagementOperationRepresentation(input.Representations)
if err != nil {
return nil, err
}
output["representation"] = representation

return []interface{}{output}
return []interface{}{output}, nil
}

func expandApiManagementOperationResponseContract(d *pluginsdk.ResourceData, schemaPath string, input []interface{}) (*[]apimanagement.ResponseContract, error) {
Expand Down Expand Up @@ -337,9 +347,9 @@ func expandApiManagementOperationResponseContract(d *pluginsdk.ResourceData, sch
return &outputs, nil
}

func flattenApiManagementOperationResponseContract(input *[]apimanagement.ResponseContract) []interface{} {
func flattenApiManagementOperationResponseContract(input *[]apimanagement.ResponseContract) ([]interface{}, error) {
if input == nil {
return []interface{}{}
return []interface{}{}, nil
}

outputs := make([]interface{}, 0)
Expand All @@ -356,10 +366,15 @@ func flattenApiManagementOperationResponseContract(input *[]apimanagement.Respon
}

output["header"] = schemaz.FlattenApiManagementOperationParameterContract(v.Headers)
output["representation"] = schemaz.FlattenApiManagementOperationRepresentation(v.Representations)

representation, err := schemaz.FlattenApiManagementOperationRepresentation(v.Representations)
if err != nil {
return nil, err
}
output["representation"] = representation

outputs = append(outputs, output)
}

return outputs
return outputs, nil
}
67 changes: 51 additions & 16 deletions internal/services/apimanagement/schemaz/api_management.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package schemaz

import (
"encoding/json"
"fmt"
"strings"

"github.com/hashicorp/terraform-provider-azurerm/internal/features"

"github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2021-08-01/apimanagement"
"github.com/hashicorp/terraform-provider-azurerm/internal/features"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
Expand Down Expand Up @@ -180,9 +180,9 @@ func ExpandApiManagementOperationRepresentation(d *pluginsdk.ResourceData, schem
return &outputs, nil
}

func FlattenApiManagementOperationRepresentation(input *[]apimanagement.RepresentationContract) []interface{} {
func FlattenApiManagementOperationRepresentation(input *[]apimanagement.RepresentationContract) ([]interface{}, error) {
if input == nil {
return []interface{}{}
return []interface{}{}, nil
}

outputs := make([]interface{}, 0)
Expand All @@ -197,10 +197,18 @@ func FlattenApiManagementOperationRepresentation(input *[]apimanagement.Represen
output["form_parameter"] = FlattenApiManagementOperationParameterContract(v.FormParameters)

if v.Examples != nil {
output["example"] = FlattenApiManagementOperationParameterExampleContract(v.Examples)

if features.ThreePointOhBeta() && v.Examples["default"] != nil && v.Examples["default"].Value != nil {
output["sample"] = v.Examples["default"].Value.(string)
example, err := FlattenApiManagementOperationParameterExampleContract(v.Examples)
if err != nil {
return nil, err
}
output["example"] = example

if !features.ThreePointOhBeta() && v.Examples["default"] != nil && v.Examples["default"].Value != nil {
value, err := convert2Json(v.Examples["default"].Value)
if err != nil {
return nil, err
}
output["sample"] = value
}
}

Expand All @@ -215,7 +223,7 @@ func FlattenApiManagementOperationRepresentation(input *[]apimanagement.Represen
outputs = append(outputs, output)
}

return outputs
return outputs, nil
}

func SchemaApiManagementOperationParameterContract() *pluginsdk.Schema {
Expand Down Expand Up @@ -355,8 +363,9 @@ func SchemaApiManagementOperationParameterExampleContract() *pluginsdk.Schema {
},

"value": {
Type: pluginsdk.TypeString,
Optional: true,
Type: pluginsdk.TypeString,
Optional: true,
DiffSuppressFunc: pluginsdk.SuppressJsonDiff,
},

"external_value": {
Expand Down Expand Up @@ -392,7 +401,12 @@ func ExpandApiManagementOperationParameterExampleContract(input []interface{}) m
}

if vs["value"] != nil {
outputs[name].Value = utils.String(vs["value"].(string))
var js interface{}
if json.Unmarshal([]byte(vs["value"].(string)), &js) == nil {
outputs[name].Value = js
} else {
outputs[name].Value = utils.String(vs["value"].(string))
}
}

if vs["external_value"] != nil {
Expand All @@ -403,9 +417,9 @@ func ExpandApiManagementOperationParameterExampleContract(input []interface{}) m
return outputs
}

func FlattenApiManagementOperationParameterExampleContract(input map[string]*apimanagement.ParameterExampleContract) []interface{} {
func FlattenApiManagementOperationParameterExampleContract(input map[string]*apimanagement.ParameterExampleContract) ([]interface{}, error) {
if input == nil {
return []interface{}{}
return []interface{}{}, nil
}

outputs := make([]interface{}, 0)
Expand All @@ -422,8 +436,15 @@ func FlattenApiManagementOperationParameterExampleContract(input map[string]*api
output["description"] = *v.Description
}

// value can be any type, may be a primitive value or an object
// https://github.com/Azure/azure-sdk-for-go/blob/main/services/apimanagement/mgmt/2021-08-01/apimanagement/models.go#L10236
if v.Value != nil {
output["value"] = v.Value.(string)
value, err := convert2Json(v.Value)
if err != nil {
return nil, err
}

output["value"] = value
}

if v.ExternalValue != nil {
Expand All @@ -433,7 +454,7 @@ func FlattenApiManagementOperationParameterExampleContract(input map[string]*api
outputs = append(outputs, output)
}

return outputs
return outputs, nil
}

// CopyCertificateAndPassword copies any certificate and password attributes
Expand All @@ -452,3 +473,17 @@ func CopyCertificateAndPassword(vals []interface{}, hostName string, output map[
}
}
}

func convert2Json(rawVal interface{}) (string, error) {
value := ""
if val, ok := rawVal.(string); ok {
value = val
} else {
val, err := json.Marshal(rawVal)
if err != nil {
return "", fmt.Errorf("failed to marshal `representations.examples.value` to json: %+v", err)
}
value = string(val)
}
return value, nil
}

0 comments on commit fe79aab

Please sign in to comment.