Skip to content

Commit

Permalink
Merge pull request #710 from SumoLogic/yuting-SUMO-245309-terraform-s…
Browse files Browse the repository at this point in the history
…upport

SUMO-245309 Add the terraform support for Azure metric sources
  • Loading branch information
ErikAtSumo authored Jan 23, 2025
2 parents dd450a7 + 70873d1 commit 5a1e5b0
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ jobs:
SUMOLOGIC_DATA_FORWARDING_BUCKET: ${{ secrets.SUMOLOGIC_DATA_FORWARDING_BUCKET }}
SUMOLOGIC_DATA_FORWARDING_ROLE_ARN: ${{ secrets.SUMOLOGIC_DATA_FORWARDING_ROLE_ARN }}
SUMOLOGIC_DATA_FORWARDING_AWS_REGION: ${{ secrets.SUMOLOGIC_DATA_FORWARDING_AWS_REGION }}
SUMOLOGIC_TEST_AZURE_TENANT_ID: ${{ secrets.SUMOLOGIC_TEST_AZURE_TENANT_ID }}
SUMOLOGIC_TEST_AZURE_CLIENT_ID: ${{ secrets.SUMOLOGIC_TEST_AZURE_CLIENT_ID }}
SUMOLOGIC_TEST_AZURE_CLIENT_SECRET: ${{ secrets.SUMOLOGIC_TEST_AZURE_CLIENT_SECRET }}

# disable go test timeout. We rely on GitHub action timeout.
run: |
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## X.Y.Z (Unreleased)
* Add new change notes here
FEATURES:
* **New Resource:** sumologic_azure_metrics_source (GH-710)

## 3.0.1 (January 17, 2025)
**ENHANCEMENTS:**
Expand Down
1 change: 1 addition & 0 deletions sumologic/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func Provider() terraform.ResourceProvider {
"sumologic_rum_source": resourceSumologicRumSource(),
"sumologic_role_v2": resourceSumologicRoleV2(),
"sumologic_azure_event_hub_log_source": resourceSumologicGenericPollingSource(),
"sumologic_azure_metrics_source": resourceSumologicGenericPollingSource(),
},
DataSourcesMap: map[string]*schema.Resource{
"sumologic_cse_log_mapping_vendor_product": dataSourceCSELogMappingVendorAndProduct(),
Expand Down
209 changes: 209 additions & 0 deletions sumologic/resource_sumologic_azure_metrics_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package sumologic

import (
"fmt"
"os"
"strconv"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccSumologicAzureMetricsSource_create(t *testing.T) {
var azureMetricsSource PollingSource
var collector Collector
cName, cDescription, cCategory := getRandomizedParams()
sName, sDescription, sCategory := getRandomizedParams()
azureMetricsResourceName := "sumologic_azure_metrics_source.azure"
testTenantId := os.Getenv("SUMOLOGIC_TEST_AZURE_TENANT_ID")
testClientId := os.Getenv("SUMOLOGIC_TEST_AZURE_CLIENT_ID")
testClientSecret := os.Getenv("SUMOLOGIC_TEST_AZURE_CLIENT_SECRET")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAzureMetricsSourceDestroy,
Steps: []resource.TestStep{
{
Config: testAccSumologicAzureMetricsSourceConfig(cName, cDescription, cCategory, sName, sDescription, sCategory, testTenantId, testClientId, testClientSecret),
Check: resource.ComposeTestCheckFunc(
testAccCheckAzureMetricsSourceExists(azureMetricsResourceName, &azureMetricsSource),
testAccCheckAzureMetricsSourceValues(&azureMetricsSource, sName, sDescription, sCategory),
testAccCheckCollectorExists("sumologic_collector.test", &collector),
testAccCheckCollectorValues(&collector, cName, cDescription, cCategory, "Etc/UTC", ""),
resource.TestCheckResourceAttrSet(azureMetricsResourceName, "id"),
resource.TestCheckResourceAttr(azureMetricsResourceName, "name", sName),
resource.TestCheckResourceAttr(azureMetricsResourceName, "description", sDescription),
resource.TestCheckResourceAttr(azureMetricsResourceName, "category", sCategory),
resource.TestCheckResourceAttr(azureMetricsResourceName, "content_type", "AzureMetrics"),
resource.TestCheckResourceAttr(azureMetricsResourceName, "path.0.type", "AzureMetricsPath"),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccSumologicAzureMetricsSource_update(t *testing.T) {
var azureMetricsSource PollingSource
cName, cDescription, cCategory := getRandomizedParams()
sName, sDescription, sCategory := getRandomizedParams()
sNameUpdated, sDescriptionUpdated, sCategoryUpdated := getRandomizedParams()
azureMetricsResourceName := "sumologic_azure_metrics_source.azure"
testTenantId := os.Getenv("SUMOLOGIC_TEST_AZURE_TENANT_ID")
testClientId := os.Getenv("SUMOLOGIC_TEST_AZURE_CLIENT_ID")
testClientSecret := os.Getenv("SUMOLOGIC_TEST_AZURE_CLIENT_SECRET")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAzureMetricsSourceDestroy,
Steps: []resource.TestStep{
{
Config: testAccSumologicAzureMetricsSourceConfig(cName, cDescription, cCategory, sName, sDescription, sCategory, testTenantId, testClientId, testClientSecret),
Check: resource.ComposeTestCheckFunc(
testAccCheckAzureMetricsSourceExists(azureMetricsResourceName, &azureMetricsSource),
testAccCheckAzureMetricsSourceValues(&azureMetricsSource, sName, sDescription, sCategory),
resource.TestCheckResourceAttrSet(azureMetricsResourceName, "id"),
resource.TestCheckResourceAttr(azureMetricsResourceName, "name", sName),
resource.TestCheckResourceAttr(azureMetricsResourceName, "description", sDescription),
resource.TestCheckResourceAttr(azureMetricsResourceName, "category", sCategory),
resource.TestCheckResourceAttr(azureMetricsResourceName, "content_type", "AzureMetrics"),
resource.TestCheckResourceAttr(azureMetricsResourceName, "path.0.type", "AzureMetricsPath"),
),
ExpectNonEmptyPlan: true,
},
{
Config: testAccSumologicAzureMetricsSourceConfig(cName, cDescription, cCategory, sNameUpdated, sDescriptionUpdated, sCategoryUpdated, testTenantId, testClientId, testClientSecret),
Check: resource.ComposeTestCheckFunc(
testAccCheckAzureMetricsSourceExists(azureMetricsResourceName, &azureMetricsSource),
testAccCheckAzureMetricsSourceValues(&azureMetricsSource, sNameUpdated, sDescriptionUpdated, sCategoryUpdated),
resource.TestCheckResourceAttrSet(azureMetricsResourceName, "id"),
resource.TestCheckResourceAttr(azureMetricsResourceName, "name", sNameUpdated),
resource.TestCheckResourceAttr(azureMetricsResourceName, "description", sDescriptionUpdated),
resource.TestCheckResourceAttr(azureMetricsResourceName, "category", sCategoryUpdated),
resource.TestCheckResourceAttr(azureMetricsResourceName, "content_type", "AzureMetrics"),
resource.TestCheckResourceAttr(azureMetricsResourceName, "path.0.type", "AzureMetricsPath"),
),
ExpectNonEmptyPlan: true,
},
},
})

}

func testAccCheckAzureMetricsSourceDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*Client)
for _, rs := range s.RootModule().Resources {
if rs.Type != "sumologic_azure_metrics_source" {
continue
}
if rs.Primary.ID == "" {
return fmt.Errorf("Azure Event Hub Log Source destruction check: Azure Event Hub Log Source ID is not set")
}
id, err := strconv.Atoi(rs.Primary.ID)
if err != nil {
return fmt.Errorf("Encountered an error: " + err.Error())
}
collectorID, err := strconv.Atoi(rs.Primary.Attributes["collector_id"])
if err != nil {
return fmt.Errorf("Encountered an error: " + err.Error())
}
s, err := client.GetPollingSource(collectorID, id)
if err != nil {
return fmt.Errorf("Encountered an error: " + err.Error())
}
if s != nil {
return fmt.Errorf("Polling Source still exists")
}
}
return nil
}

func testAccCheckAzureMetricsSourceExists(n string, pollingSource *PollingSource) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("Polling Source ID is not set")
}
id, err := strconv.Atoi(rs.Primary.ID)
if err != nil {
return fmt.Errorf("Polling Source id should be int; got %s", rs.Primary.ID)
}
collectorID, err := strconv.Atoi(rs.Primary.Attributes["collector_id"])
if err != nil {
return fmt.Errorf("Encountered an error: " + err.Error())
}
c := testAccProvider.Meta().(*Client)
pollingSourceResp, err := c.GetPollingSource(collectorID, id)
if err != nil {
return err
}
*pollingSource = *pollingSourceResp
return nil
}
}

func testAccCheckAzureMetricsSourceValues(pollingSource *PollingSource, name, description, category string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if pollingSource.Name != name {
return fmt.Errorf("bad name, expected \"%s\", got: %#v", name, pollingSource.Name)
}
if pollingSource.Description != description {
return fmt.Errorf("bad description, expected \"%s\", got: %#v", description, pollingSource.Description)
}
if pollingSource.Category != category {
return fmt.Errorf("bad category, expected \"%s\", got: %#v", category, pollingSource.Category)
}
return nil
}
}

func testAccSumologicAzureMetricsSourceConfig(cName, cDescription, cCategory, sName, sDescription, sCategory, testTenantId, testClientId, testClientSecret string) string {
return fmt.Sprintf(`
resource "sumologic_collector" "test" {
name = "%s"
description = "%s"
category = "%s"
}
resource "sumologic_azure_metrics_source" "azure" {
name = "%s"
description = "%s"
category = "%s"
content_type = "AzureMetrics"
collector_id = "${sumologic_collector.test.id}"
authentication {
type = "AzureClientSecretAuthentication"
tenant_id = "%s"
client_id = "%s"
client_secret = "%s"
}
path {
type = "AzureMetricsPath"
environment = "Azure"
limit_to_namespaces = ["Microsoft.ClassicStorage/storageAccounts"]
azure_tag_filters {
type = "AzureTagFilters"
namespace = "Microsoft.ClassicStorage/storageAccounts"
tags {
name = "test-name-1"
values = ["value1"]
}
tags {
name = "test-name-2"
values = ["value2"]
}
}
}
lifecycle {
ignore_changes = [authentication.0.client_secret]
}
}`, cName, cDescription, cCategory, sName, sDescription, sCategory, testTenantId, testClientId, testClientSecret)
}
Loading

0 comments on commit 5a1e5b0

Please sign in to comment.