diff --git a/internal/services/loganalytics/log_analytics_saved_search_resource.go b/internal/services/loganalytics/log_analytics_saved_search_resource.go index 3a9f67b31c2d..d75735466f4d 100644 --- a/internal/services/loganalytics/log_analytics_saved_search_resource.go +++ b/internal/services/loganalytics/log_analytics_saved_search_resource.go @@ -91,8 +91,9 @@ func resourceLogAnalyticsSavedSearch() *pluginsdk.Resource { ForceNew: true, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, + // https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/functions/user-defined-functions ValidateFunc: validation.StringMatch( - regexp.MustCompile(`^[a-zA-Z0-9!-_]*:[a-zA-Z0-9!_-]+=[a-zA-Z0-9!_-]+|^[a-zA-Z0-9!-_]*:[a-zA-Z0-9!_-]+`), + regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9-_]*:([a-z]+(=[^,\n]+)?|\(\*\)|(\([a-zA-Z_][a-zA-Z0-9-_]*:[a-z]+(,[a-zA-Z_][a-zA-Z0-9-_]*:([a-z]+))*\)))(,\s*[a-zA-Z_][a-zA-Z0-9-_]*:([a-z]+(=[^,\n]+)?|\(\*\)|(\([a-zA-Z_][a-zA-Z0-9-_]*:[a-z]+(,\s*[a-zA-Z_][a-zA-Z0-9-_]*:([a-z]+))*\))))*$`), "Log Analytics Saved Search Function Parameters must be in the following format: param-name1:type1=default_value1 OR param-name1:type1 OR param-name1:string='string goes here'", ), }, diff --git a/internal/services/loganalytics/log_analytics_saved_search_resource_test.go b/internal/services/loganalytics/log_analytics_saved_search_resource_test.go index 59a767807447..b9c3a8a2ecd5 100644 --- a/internal/services/loganalytics/log_analytics_saved_search_resource_test.go +++ b/internal/services/loganalytics/log_analytics_saved_search_resource_test.go @@ -64,6 +64,35 @@ func TestAccLogAnalyticsSavedSearch_withTag(t *testing.T) { }) } +func TestAccLogAnalyticsSavedSearch_functionParameter(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_log_analytics_saved_search", "test") + r := LogAnalyticsSavedSearchResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.function_parameter(data, "foo:(*)"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.function_parameter(data, "foo:int=1"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.function_parameter(data, "foo:(bar:long)"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccLogAnalyticsSavedSearch_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_log_analytics_saved_search", "test") r := LogAnalyticsSavedSearchResource{} @@ -120,7 +149,7 @@ resource "azurerm_log_analytics_saved_search" "test" { category = "Saved Search Test Category" display_name = "Create or Update Saved Search Test" - query = "Heartbeat | summarize Count() by Computer | take a" + query = "Heartbeat | summarize Count() by Computer | take 1" } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) } @@ -164,7 +193,7 @@ resource "azurerm_log_analytics_saved_search" "test" { category = "Saved Search Test Category" display_name = "Create or Update Saved Search Test" - query = "Heartbeat | summarize Count() by Computer | take a" + query = "Heartbeat | summarize Count() by Computer | take 1" function_alias = "heartbeat_func" function_parameters = ["a:int=1", "b:int=2", "c:int=3"] @@ -172,6 +201,38 @@ resource "azurerm_log_analytics_saved_search" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) } +func (LogAnalyticsSavedSearchResource) function_parameter(data acceptance.TestData, para string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "acctestLAW-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + sku = "PerGB2018" +} + +resource "azurerm_log_analytics_saved_search" "test" { + name = "acctestLASS-%d" + log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id + + category = "Saved Search Test Category" + display_name = "Create or Update Saved Search Test" + query = "Heartbeat | summarize Count() by Computer | take 1" + + function_alias = "heartbeat_func" + function_parameters = ["%s"] +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, para) +} + func (LogAnalyticsSavedSearchResource) withTag(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { @@ -196,7 +257,7 @@ resource "azurerm_log_analytics_saved_search" "test" { category = "Saved Search Test Category" display_name = "Create or Update Saved Search Test" - query = "Heartbeat | summarize Count() by Computer | take a" + query = "Heartbeat | summarize Count() by Computer | take 1" tags = { "Environment" = "Test" diff --git a/website/docs/r/log_analytics_saved_search.html.markdown b/website/docs/r/log_analytics_saved_search.html.markdown index 755c97ddae97..499182072ac8 100644 --- a/website/docs/r/log_analytics_saved_search.html.markdown +++ b/website/docs/r/log_analytics_saved_search.html.markdown @@ -52,7 +52,7 @@ The following arguments are supported: * `function_alias` - (Optional) The function alias if the query serves as a function. Changing this forces a new resource to be created. -* `function_parameters` - (Optional) The function parameters if the query serves as a function. Changing this forces a new resource to be created. +* `function_parameters` - (Optional) The function parameters if the query serves as a function. Changing this forces a new resource to be created. For more examples and proper syntax please refer to [this document](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/functions/user-defined-functions). * `tags` - (Optional) A mapping of tags which should be assigned to the Logs Analytics Saved Search. Changing this forces a new resource to be created.