From 505d6074a94dc82bfadcfb4c9e1286b31c016c42 Mon Sep 17 00:00:00 2001 From: Henry Barrow Date: Tue, 8 Feb 2022 10:46:08 +0000 Subject: [PATCH] prepare 2.5.0 release (#87) Co-authored-by: Isabelle Miller --- CHANGELOG.md | 11 +++++ .../audit_log_subscription_configs.go | 28 ++++++++++++ launchdarkly/audit_log_subscription_helper.go | 15 +++---- ...aunchdarkly_audit_log_subscription_test.go | 43 +++++++++++++++++++ ...aunchdarkly_audit_log_subscription_test.go | 37 ++++++++++++++++ .../d/audit_log_subscription.html.markdown | 2 +- .../r/audit_log_subscription.html.markdown | 2 +- 7 files changed, 128 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30db396c..2697c7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [2.5.0] (February 7, 2022) + +FEATURES: + +- Added Slack webhooks to the `launchdarkly_audit_log_subscription` resource and data source. [#16](https://github.com/launchdarkly/terraform-provider-launchdarkly/issues/16) +- Added more Datadog host URLs to the Datadog `launchdarkly_audit_log_subscription` resource. + +BUG FIXES: + +- Fixed an issue where the `config` was not being set on the `launchdarkly_audit_log_subscription` data source. + ## [2.4.1] (January 21, 2022) BUG FIXES: diff --git a/launchdarkly/audit_log_subscription_configs.go b/launchdarkly/audit_log_subscription_configs.go index a20103e2..ef9da821 100644 --- a/launchdarkly/audit_log_subscription_configs.go +++ b/launchdarkly/audit_log_subscription_configs.go @@ -49,6 +49,9 @@ var SUBSCRIPTION_CONFIGURATION_FIELDS = map[string]interface{}{ "allowedValues": []interface{}{ "https://api.datadoghq.com", "https://api.datadoghq.eu", + "https://us3.datadoghq.com", + "https://us5.datadoghq.com", + "https://app.ddog-gov.com", }, "defaultValue": "https://api.datadoghq.com", "isSecret": false, @@ -296,3 +299,28 @@ var SUBSCRIPTION_CONFIGURATION_FIELDS = map[string]interface{}{ }, }, } + +// There is not currently a manifest for slack webhooks so we have to use this for now. +var EXTRA_SUBSCRIPTION_CONFIGURATION_FIELDS = map[string]interface{}{ + "slack": map[string]interface{}{ + "url": map[string]interface{}{ + "type": "uri", + "isOptional": false, + "allowedValues": nil, + "defaultValue": nil, + "isSecret": false, + }, + }, +} + +func getSubscriptionConfigurationFields() map[string]interface{} { + fields := make(map[string]interface{}, len(SUBSCRIPTION_CONFIGURATION_FIELDS)+len(EXTRA_SUBSCRIPTION_CONFIGURATION_FIELDS)) + + for k, v := range SUBSCRIPTION_CONFIGURATION_FIELDS { + fields[k] = v + } + for k, v := range EXTRA_SUBSCRIPTION_CONFIGURATION_FIELDS { + fields[k] = v + } + return fields +} diff --git a/launchdarkly/audit_log_subscription_helper.go b/launchdarkly/audit_log_subscription_helper.go index 02be4802..d907e8d0 100644 --- a/launchdarkly/audit_log_subscription_helper.go +++ b/launchdarkly/audit_log_subscription_helper.go @@ -55,9 +55,9 @@ func auditLogSubscriptionSchema(isDataSource bool) map[string]*schema.Schema { } func parseAuditLogSubscriptionConfigs() map[string]IntegrationConfig { - // SUBSCRIPTION_CONFIGURATION_FIELDS can be found in audit_log_subscription_configs.go - configs := make(map[string]IntegrationConfig, len(SUBSCRIPTION_CONFIGURATION_FIELDS)) - for integrationKey, rawVariables := range SUBSCRIPTION_CONFIGURATION_FIELDS { + rawConfigFields := getSubscriptionConfigurationFields() + configs := make(map[string]IntegrationConfig, len(rawConfigFields)) + for integrationKey, rawVariables := range rawConfigFields { cfg := IntegrationConfig{} variables := rawVariables.(map[string]interface{}) for k, v := range variables { @@ -162,7 +162,7 @@ func configFromResourceData(d *schema.ResourceData) (map[string]interface{}, err return convertedConfig, nil } -func configToResourceData(d *schema.ResourceData, config map[string]interface{}) (map[string]interface{}, error) { +func configToResourceData(d *schema.ResourceData, config map[string]interface{}, isDataSource bool) (map[string]interface{}, error) { integrationKey := d.Get(INTEGRATION_KEY).(string) configMap := parseAuditLogSubscriptionConfigs() configFormat, ok := configMap[integrationKey] @@ -174,9 +174,9 @@ func configToResourceData(d *schema.ResourceData, config map[string]interface{}) for k, v := range config { key := strcase.SnakeCase(k) // some attributes have defaults that the API will return and terraform will complain since config - // is not a computed attribute (cannot be both required & computed) + // is not a computed attribute (cannot be both required & computed). This does not apply for data sources. // TODO: handle this in a SuppressDiff function - if _, setByUser := originalConfig[key]; !setByUser { + if _, setByUser := originalConfig[key]; !setByUser && !isDataSource { continue } convertedConfig[key] = v @@ -221,10 +221,9 @@ func auditLogSubscriptionRead(ctx context.Context, d *schema.ResourceData, metaR d.SetId(*sub.Id) } - _ = d.Set(INTEGRATION_KEY, sub.Kind) _ = d.Set(NAME, sub.Name) _ = d.Set(ON, sub.On) - cfg, err := configToResourceData(d, *sub.Config) + cfg, err := configToResourceData(d, *sub.Config, isDataSource) if err != nil { return diag.Errorf("failed to set config on integration with id %q: %v", *sub.Id, err) } diff --git a/launchdarkly/data_source_launchdarkly_audit_log_subscription_test.go b/launchdarkly/data_source_launchdarkly_audit_log_subscription_test.go index 01dc454a..89664b2b 100644 --- a/launchdarkly/data_source_launchdarkly_audit_log_subscription_test.go +++ b/launchdarkly/data_source_launchdarkly_audit_log_subscription_test.go @@ -116,3 +116,46 @@ func TestAccDataSourceAuditLogSubscription_exists(t *testing.T) { }, }) } + +func TestAccDataSourceAuditLogSubscription_Slack(t *testing.T) { + accTest := os.Getenv("TF_ACC") + if accTest == "" { + t.SkipNow() + } + + integrationKey := "slack" + client, err := newClient(os.Getenv(LAUNCHDARKLY_ACCESS_TOKEN), os.Getenv(LAUNCHDARKLY_API_HOST), false) + require.NoError(t, err) + + subscriptionBody := ldapi.SubscriptionPost{ + Name: "test subscription", + Config: map[string]interface{}{ + "url": "https://hooks.slack.com/services/SOME-RANDOM-HOOK", + }, + } + sub, err := testAccDataSourceAuditLogSubscriptionCreate(client, integrationKey, subscriptionBody) + require.NoError(t, err) + + defer func() { + err := testAccDataSourceAuditLogSubscriptionDelete(client, integrationKey, *sub.Id) + require.NoError(t, err) + }() + + resourceName := "data.launchdarkly_audit_log_subscription.test" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(testAccDataSourceAuditLogSubscriptionExists, *sub.Id, integrationKey), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "id", *sub.Id), + resource.TestCheckResourceAttr(resourceName, "config.url", "https://hooks.slack.com/services/SOME-RANDOM-HOOK"), + ), + }, + }, + }) +} diff --git a/launchdarkly/resource_launchdarkly_audit_log_subscription_test.go b/launchdarkly/resource_launchdarkly_audit_log_subscription_test.go index dbdb4a2b..f9bf9bff 100644 --- a/launchdarkly/resource_launchdarkly_audit_log_subscription_test.go +++ b/launchdarkly/resource_launchdarkly_audit_log_subscription_test.go @@ -177,6 +177,43 @@ func TestAccAuditLogSubscription_CreateMSTeams(t *testing.T) { }) } +func TestAccAuditLogSubscription_CreateSlack(t *testing.T) { + // splunk specifically needs to be converted to kebab case, so we need to handle it specially + integrationKey := "slack" + config := `{ + url = "https://hooks.slack.com/services/SOME-RANDOM-HOOK" + } + ` + + resourceName := fmt.Sprintf("launchdarkly_audit_log_subscription.%s_tf_test", integrationKey) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(testAccAuditLogSubscriptionCreate, integrationKey, integrationKey, config), + Check: resource.ComposeTestCheckFunc( + testAccCheckIntegrationExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, ID), + resource.TestCheckResourceAttr(resourceName, INTEGRATION_KEY, integrationKey), + resource.TestCheckResourceAttr(resourceName, NAME, "terraform test"), + resource.TestCheckResourceAttr(resourceName, ON, "true"), + resource.TestCheckResourceAttr(resourceName, "config.url", "https://hooks.slack.com/services/SOME-RANDOM-HOOK"), + resource.TestCheckResourceAttr(resourceName, "tags.#", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.0", "integrations"), + resource.TestCheckResourceAttr(resourceName, "tags.1", "terraform"), + resource.TestCheckResourceAttr(resourceName, "statements.#", "1"), + resource.TestCheckResourceAttr(resourceName, "statements.0.actions.0", "*"), + resource.TestCheckResourceAttr(resourceName, "statements.0.resources.0", "proj/*:env/*:flag/*"), + resource.TestCheckResourceAttr(resourceName, "statements.0.effect", "deny"), + ), + }, + }, + }) +} + func TestAccAuditLogSubscription_CreateSplunk(t *testing.T) { // splunk specifically needs to be converted to kebab case, so we need to handle it specially integrationKey := "splunk" diff --git a/website/docs/d/audit_log_subscription.html.markdown b/website/docs/d/audit_log_subscription.html.markdown index a7668ab2..02f66b29 100644 --- a/website/docs/d/audit_log_subscription.html.markdown +++ b/website/docs/d/audit_log_subscription.html.markdown @@ -24,7 +24,7 @@ data "launchdarkly_audit_log_subscription" "test" { - `id` (Required) - The unique subscription ID. This can be found in the URL of the pull-out configuration sidebar for the given subscription on your [LaunchDarkly Integrations page](https://app.launchdarkly.com/default/integrations). -- `integration_key` (Required) - The integration key. As of January 2022, supported integrations are `"datadog"`, `"dynatrace"`, `"elastic"`, `"honeycomb"`, `"logdna"`, `"msteams"`, `"new-relic-apm"`, `"signalfx"`, and `"splunk"`. +- `integration_key` (Required) - The integration key. As of February 2022, supported integrations are `"datadog"`, `"dynatrace"`, `"elastic"`, `"honeycomb"`, `"logdna"`, `"msteams"`, `"new-relic-apm"`, `"signalfx"`, `"slack"`, and `"splunk"`. ## Attributes Reference diff --git a/website/docs/r/audit_log_subscription.html.markdown b/website/docs/r/audit_log_subscription.html.markdown index 9a266673..a7ac0ab2 100644 --- a/website/docs/r/audit_log_subscription.html.markdown +++ b/website/docs/r/audit_log_subscription.html.markdown @@ -35,7 +35,7 @@ resource "launchdarkly_audit_log_subscription" "example" { ## Argument Reference -- `integration_key` (Required) The integration key. As of January 2022, supported integrations are `"datadog"`, `"dynatrace"`, `"elastic"`, `"honeycomb"`, `"logdna"`, `"msteams"`, `"new-relic-apm"`, `"signalfx"`, and `"splunk"`. A change in this field will force the destruction of the existing resource and the creation of a new one. +- `integration_key` (Required) The integration key. As of January 2022, supported integrations are `"datadog"`, `"dynatrace"`, `"elastic"`, `"honeycomb"`, `"logdna"`, `"msteams"`, `"new-relic-apm"`, `"signalfx"`, `"slack"`, and `"splunk"`. A change in this field will force the destruction of the existing resource and the creation of a new one. - `name` (Required) - A human-friendly name for your audit log subscription viewable from within the LaunchDarkly Integrations page.