diff --git a/internal/services/apimanagement/schemaz/api_management.go b/internal/services/apimanagement/schemaz/api_management.go index b19b4f596fae8..90f7ab911b6f0 100644 --- a/internal/services/apimanagement/schemaz/api_management.go +++ b/internal/services/apimanagement/schemaz/api_management.go @@ -7,6 +7,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2021-08-01/apimanagement" "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" "github.com/hashicorp/terraform-provider-azurerm/utils" ) @@ -91,11 +92,16 @@ func SchemaApiManagementOperationRepresentation() *pluginsdk.Schema { "form_parameter": SchemaApiManagementOperationParameterContract(), + // TODO 3.0 - Remove below property "sample": { - Type: pluginsdk.TypeString, - Optional: true, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Deprecated: "Deprecated in favour of `example`", }, + "example": SchemaApiManagementOperationParameterExampleContract(), + "schema_id": { Type: pluginsdk.TypeString, Optional: true, @@ -123,13 +129,26 @@ func ExpandApiManagementOperationRepresentation(d *pluginsdk.ResourceData, schem contentType := vs["content_type"].(string) formParametersRaw := vs["form_parameter"].([]interface{}) formParameters := ExpandApiManagementOperationParameterContract(d, fmt.Sprintf("%s.%d.form_parameter", schemaPath, i), formParametersRaw) - sample := vs["sample"].(string) schemaId := vs["schema_id"].(string) typeName := vs["type_name"].(string) + examples := make(map[string]*apimanagement.ParameterExampleContract) + if vs["examples"] != nil { + if vs["sample"] != nil { + return nil, fmt.Errorf("Only one of `examples` and `sample` can be provided at the same time.") + } + examples = ExpandApiManagementOperationParameterExampleContract(vs["examples"].([]interface{})) + } else if vs["sample"] != nil { + defaultExample := map[string]interface{}{ + "name": "default", + "value": vs["sample"], + } + examples = ExpandApiManagementOperationParameterExampleContract([]interface{}{defaultExample}) + } + output := apimanagement.RepresentationContract{ ContentType: utils.String(contentType), - Sample: utils.String(sample), + Examples: examples, } contentTypeIsFormData := strings.EqualFold(contentType, "multipart/form-data") || strings.EqualFold(contentType, "application/x-www-form-urlencoded") @@ -175,8 +194,13 @@ func FlattenApiManagementOperationRepresentation(input *[]apimanagement.Represen output["form_parameter"] = FlattenApiManagementOperationParameterContract(v.FormParameters) - if v.Sample != nil { - output["sample"] = *v.Sample + if v.Examples != nil { + output["example"] = FlattenApiManagementOperationParameterExampleContract(v.Examples) + + // TODO 3.0 - Remove setting of property + if v.Examples["default"] != nil && v.Examples["default"].Value != nil { + output["sample"] = v.Examples["default"].Value.(string) + } } if v.SchemaID != nil { @@ -307,6 +331,103 @@ func FlattenApiManagementOperationParameterContract(input *[]apimanagement.Param return outputs } +func SchemaApiManagementOperationParameterExampleContract() *pluginsdk.Schema { + return &pluginsdk.Schema{ + Type: pluginsdk.TypeSet, + Optional: true, + Computed: true, // TODO 3.0 - Remove when sample property is removed. + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "summary": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "description": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "value": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "external_value": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.IsURLWithHTTPorHTTPS, + }, + }, + }, + } +} + +func ExpandApiManagementOperationParameterExampleContract(input []interface{}) map[string]*apimanagement.ParameterExampleContract { + if len(input) == 0 { + return map[string]*apimanagement.ParameterExampleContract{} + } + + outputs := make(map[string]*apimanagement.ParameterExampleContract) + + for _, v := range input { + vs := v.(map[string]interface{}) + + name := vs["name"].(string) + summary := vs["summary"].(string) + description := vs["description"].(string) + value := vs["value"].(string) + externalValue := vs["external_value"].(string) + + outputs[name] = &apimanagement.ParameterExampleContract{ + Summary: utils.String(summary), + Description: utils.String(description), + Value: utils.String(value), + ExternalValue: utils.String(externalValue), + } + } + + return outputs +} + +func FlattenApiManagementOperationParameterExampleContract(input map[string]*apimanagement.ParameterExampleContract) []interface{} { + if input == nil { + return []interface{}{} + } + + outputs := make([]interface{}, 0) + for k, v := range input { + output := map[string]interface{}{} + + output["name"] = k + + if v.Summary != nil { + output["summary"] = *v.Summary + } + + if v.Description != nil { + output["description"] = *v.Description + } + + if v.Value != nil { + output["value"] = v.Value.(string) + } + + if v.ExternalValue != nil { + output["external_value"] = *v.ExternalValue + } + + outputs = append(outputs, output) + } + + return outputs +} + // CopyCertificateAndPassword copies any certificate and password attributes // from the old config to the current to avoid state diffs. // Iterate through old state to find sensitive props not returned by API. diff --git a/website/docs/r/api_management_api_operation.html.markdown b/website/docs/r/api_management_api_operation.html.markdown index 9644cfdad3e3e..554a58aff963a 100644 --- a/website/docs/r/api_management_api_operation.html.markdown +++ b/website/docs/r/api_management_api_operation.html.markdown @@ -65,6 +65,20 @@ The following arguments are supported: * `template_parameter` - (Optional) One or more `template_parameter` blocks as defined below. +--- + +An `example` block supports the following: + +* `name` - (Required) The name of this example. + +* `summary` - (Optional) A short description for this example. + +* `description` - (Optional) A long description for this example. + +* `value` - (Optional) The example of the representation. + +* `external_value` - (Optional) A URL that points to the literal example. + --- A `form_parameter` block supports the following: @@ -135,8 +149,12 @@ A `representation` block supports the following: -> **NOTE:** This is Required when `content_type` is set to `application/x-www-form-urlencoded` or `multipart/form-data`. +* `example` - (Optional) One or more `example` blocks as defined above. + * `sample` - (Optional) An example of this representation. +~> **NOTE:** `sample` is deprecated, use `examples` instead. + * `schema_id` - (Optional) The ID of an API Management Schema which represents this Response. -> **NOTE:** This can only be specified when `content_type` is not set to `application/x-www-form-urlencoded` or `multipart/form-data`.