From 8a7f366bbcfa5cccdb65f8b90e8bf13528b1233d Mon Sep 17 00:00:00 2001 From: Yuping Wei <56525716+yupwei68@users.noreply.github.com> Date: Mon, 12 Jul 2021 23:56:23 +0800 Subject: [PATCH] Support for `data_masking` in `azurerm_api_management_api_diagnostic` (#12419) Fix #12418 --- .../api_management_api_diagnostic_resource.go | 111 ++++++++++++++ ...management_api_diagnostic_resource_test.go | 135 ++++++++++++++++++ ...pi_management_api_diagnostic.html.markdown | 18 +++ 3 files changed, 264 insertions(+) diff --git a/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource.go b/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource.go index 8a89fc0e39be..7899d689c7bc 100644 --- a/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource.go +++ b/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource.go @@ -135,6 +135,17 @@ func resourceApiManagementApiDiagnosticAdditionalContentSchema() *pluginsdk.Sche }, Set: pluginsdk.HashString, }, + "data_masking": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "query_params": schemaApiManagementDataMaskingEntityList(), + "headers": schemaApiManagementDataMaskingEntityList(), + }, + }, + }, }, }, } @@ -329,6 +340,8 @@ func expandApiManagementApiDiagnosticHTTPMessageDiagnostic(input []interface{}) result.Headers = &headers } + result.DataMasking = expandApiManagementDataMasking(v["data_masking"].([]interface{})) + return result } @@ -348,7 +361,105 @@ func flattenApiManagementApiDiagnosticHTTPMessageDiagnostic(input *apimanagement if input.Headers != nil { diagnostic["headers_to_log"] = set.FromStringSlice(*input.Headers) } + + diagnostic["data_masking"] = flattenApiManagementDataMasking(input.DataMasking) + result = append(result, diagnostic) return result } + +func schemaApiManagementDataMaskingEntityList() *pluginsdk.Schema { + return &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "mode": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.Hide), + string(apimanagement.Mask), + }, false), + }, + + "value": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + }, + } +} + +func expandApiManagementDataMasking(input []interface{}) *apimanagement.DataMasking { + if len(input) == 0 || input[0] == nil { + return nil + } + + inputRaw := input[0].(map[string]interface{}) + return &apimanagement.DataMasking{ + QueryParams: expandApiManagementDataMaskingEntityList(inputRaw["query_params"].([]interface{})), + Headers: expandApiManagementDataMaskingEntityList(inputRaw["headers"].([]interface{})), + } +} + +func expandApiManagementDataMaskingEntityList(input []interface{}) *[]apimanagement.DataMaskingEntity { + if len(input) == 0 || input[0] == nil { + return nil + } + + result := make([]apimanagement.DataMaskingEntity, 0) + for _, v := range input { + entity := v.(map[string]interface{}) + result = append(result, apimanagement.DataMaskingEntity{ + Mode: apimanagement.DataMaskingMode(entity["mode"].(string)), + Value: utils.String(entity["value"].(string)), + }) + } + return &result +} + +func flattenApiManagementDataMasking(dataMasking *apimanagement.DataMasking) []interface{} { + if dataMasking == nil { + return []interface{}{} + } + + var queryParams, headers []interface{} + if dataMasking.QueryParams != nil { + queryParams = flattenApiManagementDataMaskingEntityList(dataMasking.QueryParams) + } + if dataMasking.Headers != nil { + headers = flattenApiManagementDataMaskingEntityList(dataMasking.Headers) + } + + return []interface{}{ + map[string]interface{}{ + "query_params": queryParams, + "headers": headers, + }, + } +} + +func flattenApiManagementDataMaskingEntityList(dataMaskingList *[]apimanagement.DataMaskingEntity) []interface{} { + if dataMaskingList == nil || len(*dataMaskingList) == 0 { + return []interface{}{} + } + + result := []interface{}{} + + for _, entity := range *dataMaskingList { + var value string + if entity.Value != nil { + value = *entity.Value + } + result = append(result, map[string]interface{}{ + "mode": string(entity.Mode), + "value": value, + }) + } + + return result +} diff --git a/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource_test.go b/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource_test.go index 01a6596d04ef..175ca69ab6eb 100644 --- a/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource_test.go +++ b/azurerm/internal/services/apimanagement/api_management_api_diagnostic_resource_test.go @@ -83,6 +83,28 @@ func TestAccApiManagementApiDiagnostic_complete(t *testing.T) { }) } +func TestAccApiManagementApiDiagnostic_dataMasking(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_api_diagnostic", "test") + r := ApiManagementApiDiagnosticResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.dataMaskingUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (ApiManagementApiDiagnosticResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := parse.ApiDiagnosticID(state.ID) if err != nil { @@ -214,6 +236,87 @@ func (r ApiManagementApiDiagnosticResource) complete(data acceptance.TestData) s return fmt.Sprintf(` %s +resource "azurerm_api_management_api_diagnostic" "test" { + identifier = "applicationinsights" + resource_group_name = azurerm_resource_group.test.name + api_management_name = azurerm_api_management.test.name + api_name = azurerm_api_management_api.test.name + api_management_logger_id = azurerm_api_management_logger.test.id + sampling_percentage = 1.0 + always_log_errors = true + log_client_ip = true + http_correlation_protocol = "W3C" + verbosity = "verbose" + + backend_request { + body_bytes = 1 + headers_to_log = ["Host"] + data_masking { + query_params { + mode = "Hide" + value = "backend-Request-Test" + } + headers { + mode = "Mask" + value = "backend-Request-Header" + } + } + } + + backend_response { + body_bytes = 2 + headers_to_log = ["Content-Type"] + data_masking { + query_params { + mode = "Mask" + value = "backend-Resp-Test" + } + } + } + + frontend_request { + body_bytes = 3 + headers_to_log = ["Accept"] + data_masking { + headers { + mode = "Mask" + value = "frontend-Request-Header" + } + } + } + + frontend_response { + body_bytes = 4 + headers_to_log = ["Content-Length"] + data_masking { + query_params { + mode = "Hide" + value = "frontend-Response-Test" + } + + query_params { + mode = "Mask" + value = "frontend-Response-Test-Alt" + } + headers { + mode = "Mask" + value = "frontend-Response-Header" + } + + headers { + mode = "Mask" + value = "frontend-Response-Header-Alt" + } + } + } +} +`, r.template(data)) +} + +func (r ApiManagementApiDiagnosticResource) dataMaskingUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + resource "azurerm_api_management_api_diagnostic" "test" { identifier = "applicationinsights" resource_group_name = azurerm_resource_group.test.name @@ -234,16 +337,48 @@ resource "azurerm_api_management_api_diagnostic" "test" { backend_response { body_bytes = 2 headers_to_log = ["Content-Type"] + data_masking { + query_params { + mode = "Hide" + value = "backend-Resp-Test-Update" + } + } } frontend_request { body_bytes = 3 headers_to_log = ["Accept"] + data_masking { + headers { + mode = "Mask" + value = "frontend-Request-Header-Update" + } + } } frontend_response { body_bytes = 4 headers_to_log = ["Content-Length"] + data_masking { + query_params { + mode = "Hide" + value = "frontend-Response-Test-Update" + } + + query_params { + mode = "Mask" + value = "frontend-Response-Test-Alt-Update" + } + + query_params { + mode = "Mask" + value = "frontend-Response-Test-Alt2-Update" + } + headers { + mode = "Mask" + value = "frontend-Response-Header-Update" + } + } } } `, r.template(data)) diff --git a/website/docs/r/api_management_api_diagnostic.html.markdown b/website/docs/r/api_management_api_diagnostic.html.markdown index 6af509a33e8a..dffe98d360dc 100644 --- a/website/docs/r/api_management_api_diagnostic.html.markdown +++ b/website/docs/r/api_management_api_diagnostic.html.markdown @@ -155,6 +155,24 @@ A `backend_request`, `backend_response`, `frontend_request` or `frontend_respons * `headers_to_log` - (Optional) Specifies a list of headers to log. +* `data_masking` - (Optional) A `data_masking` block as defined below. + +--- + +A `data_masking` block supports the following: + +* `query_params` - (Optional) A `query_params` block as defined below. + +* `headers` - (Optional) A `headers` block as defined below. + +--- + +The `query_params` and `headers` blocks support the following: + +* `mode` - (Required) The data masking mode. Possible values are `Mask` and `Hide` for `query_params`. The only possible value is `Mask` for `headers`. + +* `value` - (Required) The name of the header or the uery parameter to mask. + ## Attributes Reference In addition to the Arguments listed above - the following Attributes are exported: