From 62d61b5c996441244b7333909868143a38136bd0 Mon Sep 17 00:00:00 2001 From: soltysss Date: Mon, 15 May 2023 16:58:02 +0300 Subject: [PATCH 1/9] SCALRCORE-25214 - Provider > Add Slack Integration --- CHANGELOG.md | 1 + docs/resources/scalr_slack_integration.md | 38 +++ go.mod | 2 +- go.sum | 2 + scalr/provider.go | 1 + scalr/provider_test.go | 8 + scalr/resource_scalr_slack_integration.go | 235 ++++++++++++++++++ .../resource_scalr_slack_integration_test.go | 46 ++++ 8 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 docs/resources/scalr_slack_integration.md create mode 100644 scalr/resource_scalr_slack_integration.go create mode 100644 scalr/resource_scalr_slack_integration_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cd87a86..21f05e36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **New data source:** `scalr_environments` ([#225](https://github.com/Scalr/terraform-provider-scalr/pull/225)) - **New data source:** `scalr_workspaces` ([#225](https://github.com/Scalr/terraform-provider-scalr/pull/225)) +- **New resource:** `scalr_slack_integration` ([#250](https://github.com/Scalr/terraform-provider-scalr/pull/250)) ### Changed diff --git a/docs/resources/scalr_slack_integration.md b/docs/resources/scalr_slack_integration.md new file mode 100644 index 00000000..b7af02dc --- /dev/null +++ b/docs/resources/scalr_slack_integration.md @@ -0,0 +1,38 @@ + +# Resource `scalr_slack_integration` + +Manage the state of slack integrations in Scalr. Create, update and destroy. +Slack workspace should be connected to scalr account before using this resource. + +## Example Usage + +Basic usage: + +```hcl +resource "scalr_slack_integration" "test" { + name = data.scalr_slack_channel.test.name + account_id = "acc-xxxx" + events = ["run_approval_required", "run_success", "run_errored"] + channel_id = "xxxx" //Can be found in slack UI (channel settings/info popup) + "environments" = ["env-xxxxx"] + "workspaces" = ["ws-xxxx", "ws-xxxx"] +} +``` + +## Argument Reference + +* `name` - (Required) Name of the slack integration. +* `channel_id` - (Required) Slack channel event should be sent to. +* `events` - (Required) Terraform run events you would like to receive a Slack notifications for. +Supported values are `run_approval_required`, `run_success`, `run_errored` +* `environments` - (Required) List of environments where events should be triggered on. +* `environments` - (Optional) List of workspaces where events should be triggered on. +Workspaces should be in provided environments. +* `account_id` - (Optional) ID of the account. + + +## Attribute Reference + +All arguments plus: + +* `id` - The ID of the Slack integration. diff --git a/go.mod b/go.mod index b9160d57..e40de4b4 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 - github.com/scalr/go-scalr v0.0.0-20230511140835-ed400653430f + github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086 ) require ( diff --git a/go.sum b/go.sum index 14781faf..b92efbb0 100644 --- a/go.sum +++ b/go.sum @@ -248,6 +248,8 @@ github.com/scalr/go-scalr v0.0.0-20230504103205-022c2d21236f h1:NX/BFNSAMB+SD8i1 github.com/scalr/go-scalr v0.0.0-20230504103205-022c2d21236f/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/scalr/go-scalr v0.0.0-20230511140835-ed400653430f h1:TilyG5/f6rLxDIr0NzErEO8+E1fDRMaGAYJbO9wQ6VA= github.com/scalr/go-scalr v0.0.0-20230511140835-ed400653430f/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= +github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086 h1:d21fcWDddlrN/RtDG5zxSCm0OPrLsGa04JixySVJLeI= +github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= diff --git a/scalr/provider.go b/scalr/provider.go index acd6dfbd..dd69c95c 100644 --- a/scalr/provider.go +++ b/scalr/provider.go @@ -101,6 +101,7 @@ func Provider() *schema.Provider { "scalr_run_trigger": resourceScalrRunTrigger(), "scalr_service_account": resourceScalrServiceAccount(), "scalr_service_account_token": resourceScalrServiceAccountToken(), + "scalr_slack_integration": resourceScalrSlackIntegration(), "scalr_tag": resourceScalrTag(), "scalr_variable": resourceScalrVariable(), "scalr_vcs_provider": resourceScalrVcsProvider(), diff --git a/scalr/provider_test.go b/scalr/provider_test.go index 3f24a6ff..6f868b6f 100644 --- a/scalr/provider_test.go +++ b/scalr/provider_test.go @@ -18,6 +18,7 @@ var testAccProvider *schema.Provider var testAccProviderFactories map[string]func() (*schema.Provider, error) var noInstanceIdErr = fmt.Errorf("No instance ID is set") var githubToken = os.Getenv("githubToken") +var slackChannelName = os.Getenv("SLACK_CHANNEL_ID") // ctx is used as default context.Context when making API calls. var ctx = context.Background() @@ -120,3 +121,10 @@ func testVcsAccGithubTokenPreCheck(t *testing.T) { t.Skip("Please set githubToken to run this test") } } + +func testSlackChannelNamePreCheck(t *testing.T) { + testAccPreCheck(t) + if slackChannelName == "" { + t.Skip("Please set `SLACK_CHANNEL_ID` OS variable to run this test. Channel should exist on slack account connected scalr instance tests run on.") + } +} diff --git a/scalr/resource_scalr_slack_integration.go b/scalr/resource_scalr_slack_integration.go new file mode 100644 index 00000000..45248657 --- /dev/null +++ b/scalr/resource_scalr_slack_integration.go @@ -0,0 +1,235 @@ +package scalr + +import ( + "context" + "errors" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/scalr/go-scalr" + "log" +) + +func resourceScalrSlackIntegration() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceScalrSlackIntegrationCreate, + ReadContext: resourceScalrSlackIntegrationRead, + UpdateContext: resourceScalrSlackIntegrationUpdate, + DeleteContext: resourceSlackIntegrationDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "events": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc( + validation.StringInSlice( + []string{scalr.RunApprovalRequiredEvent, scalr.RunSuccessEvent, scalr.RunErroredEvent}, + false, + ), + ), + }, + Required: true, + MinItems: 1, + }, + "channel_id": { + Type: schema.TypeString, + Required: true, + }, + "account_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + DefaultFunc: scalrAccountIDDefaultFunc, + ForceNew: true, + }, + "environments": { + Type: schema.TypeSet, + Required: true, + ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "workspaces": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func parseEvents(d *schema.ResourceData) ([]string, error) { + events := make([]string, 0) + + providedEvents := d.Get("events").([]interface{}) + err := ValidateIDsDefinitions(providedEvents) + if err != nil { + return nil, fmt.Errorf("Got error during parsing events: %s", err.Error()) + } + + for _, event := range providedEvents { + e := event.(string) + events = append(events, e) + } + + return events, nil +} + +func parseEnvironments(d *schema.ResourceData) []*scalr.Environment { + environmentsI := d.Get("environments") + environments := environmentsI.(*schema.Set).List() + environmentValues := make([]*scalr.Environment, 0) + for _, env := range environments { + environmentValues = append(environmentValues, &scalr.Environment{ID: env.(string)}) + } + + return environmentValues +} + +func parseWorkspaces(d *schema.ResourceData) []*scalr.Workspace { + workspacesI, ok := d.GetOk("workspaces") + if !ok { + return nil + } + workspaces := workspacesI.(*schema.Set).List() + workspaceValues := make([]*scalr.Workspace, 0) + for _, ws := range workspaces { + workspaceValues = append(workspaceValues, &scalr.Workspace{ID: ws.(string)}) + } + + return workspaceValues +} + +func resourceScalrSlackIntegrationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + scalrClient := meta.(*scalr.Client) + // Get attributes. + name := d.Get("name").(string) + channelId := d.Get("channel_id").(string) + events, err := parseEvents(d) + if err != nil { + return diag.Errorf("Error creating slack integration %s: %v", name, err) + } + + envs := parseEnvironments(d) + + options := scalr.SlackIntegrationCreateOptions{ + Name: &name, + ChannelId: &channelId, + Events: events, + Account: &scalr.Account{ID: d.Get("account_id").(string)}, + Environment: envs[0], + } + workspaces := parseWorkspaces(d) + if workspaces != nil { + options.Workspaces = workspaces + } + + connection, err := scalrClient.SlackIntegrations.GetConnection(ctx, options.Account.ID) + + if err != nil || connection.ID == "" { + return diag.Errorf("Error creating slack integration, account not connected to slack, create slack connection using UI first.") + } + + options.Connection = connection + + log.Printf("[DEBUG] Create slack integration: %s", name) + integration, err := scalrClient.SlackIntegrations.Create(ctx, options) + if err != nil { + return diag.Errorf("Error creating slack integration %s: %v", name, err) + } + d.SetId(integration.ID) + + return nil +} + +func resourceScalrSlackIntegrationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + scalrClient := meta.(*scalr.Client) + integrationID := d.Id() + + log.Printf("[DEBUG] Read slack integration with ID: %s", integrationID) + slackIntegration, err := scalrClient.SlackIntegrations.Read(ctx, integrationID) + if err != nil { + log.Printf("[DEBUG] slack integration %s no longer exists", integrationID) + d.SetId("") + return nil + } + _ = d.Set("name", slackIntegration.Name) + _ = d.Set("channel_id", slackIntegration.ChannelId) + _ = d.Set("events", slackIntegration.Events) + _ = d.Set("account_id", slackIntegration.Account.ID) + + environmentIDs := make([]string, 0) + //for _, environment := range slackIntegration.Environments { + // environmentIDs = append(environmentIDs, environment.ID) + //} + environmentIDs = append(environmentIDs, slackIntegration.Environment.ID) + _ = d.Set("environments", environmentIDs) + + wsIDs := make([]string, 0) + for _, ws := range slackIntegration.Workspaces { + wsIDs = append(wsIDs, ws.ID) + } + _ = d.Set("workspaces", wsIDs) + + return nil +} + +func resourceScalrSlackIntegrationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + scalrClient := meta.(*scalr.Client) + options := scalr.SlackIntegrationUpdateOptions{} + + if d.HasChange("name") { + options.Name = scalr.String(d.Get("name").(string)) + } + + if d.HasChange("channel_id") { + options.ChannelId = scalr.String(d.Get("channel_id").(string)) + } + + if d.HasChange("events") { + events, err := parseEvents(d) + if err != nil { + return diag.Errorf("Error updating slack integration %s: %v", d.Id(), err) + } + options.Events = events + } + + envs := parseEnvironments(d) + options.Environment = envs[0] + + workspaces := parseWorkspaces(d) + if workspaces != nil { + options.Workspaces = workspaces + } + + log.Printf("[DEBUG] Update slack integration: %s", d.Id()) + _, err := scalrClient.SlackIntegrations.Update(ctx, d.Id(), options) + if err != nil { + return diag.Errorf("Error updating slack integration %s: %v", d.Id(), err) + } + + return nil +} + +func resourceSlackIntegrationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + scalrClient := meta.(*scalr.Client) + + log.Printf("[DEBUG] Delete slack integration: %s", d.Id()) + err := scalrClient.SlackIntegrations.Delete(ctx, d.Id()) + if err != nil { + if errors.Is(err, scalr.ErrResourceNotFound) { + return nil + } + return diag.Errorf("Error deleting slack integration %s: %v", d.Id(), err) + } + + return nil +} diff --git a/scalr/resource_scalr_slack_integration_test.go b/scalr/resource_scalr_slack_integration_test.go new file mode 100644 index 00000000..600a8ec3 --- /dev/null +++ b/scalr/resource_scalr_slack_integration_test.go @@ -0,0 +1,46 @@ +package scalr + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccSlackIntegration_basic(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testSlackChannelNamePreCheck(t) }, + ProviderFactories: testAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccScalrSlackIntegrationConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "id"), + resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "channel_id"), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "name", slackChannelName), + resource.TestCheckResourceAttr("scalr_vcs_provider.test", "account_id", defaultAccount), + ), + }, + }, + }) +} + +func testAccScalrSlackIntegrationConfig() string { + return fmt.Sprintf(` +data "scalr_slack_channel" "test" { + name = "%s" + account_id = "%s" +} +resource scalr_environment test { + name = "test-env-slack" + account_id = data.scalr_slack_channel.test.account_id +} +resource "scalr_slack_integration" "test" { + name = data.scalr_slack_channel.test.name + account_id = data.scalr_slack_channel.test.account_id + events = ["run_approval_required", "run_errored"] + channel_id = data.scalr_slack_channel.test.id + "environments" = [scalr_environment.test.id] +}`, slackChannelName, defaultAccount) +} From e9ec398522b5dbd5bebf5b971f51df67fd7e5ddd Mon Sep 17 00:00:00 2001 From: soltysss Date: Wed, 17 May 2023 13:09:28 +0300 Subject: [PATCH 2/9] SCALRCORE-25214 - Provider > Add Slack Integration --- docs/resources/scalr_slack_integration.md | 2 +- go.mod | 2 +- go.sum | 2 + scalr/provider_test.go | 4 +- .../resource_scalr_slack_integration_test.go | 47 ++++++++++++++----- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/docs/resources/scalr_slack_integration.md b/docs/resources/scalr_slack_integration.md index b7af02dc..bb79e585 100644 --- a/docs/resources/scalr_slack_integration.md +++ b/docs/resources/scalr_slack_integration.md @@ -10,7 +10,7 @@ Basic usage: ```hcl resource "scalr_slack_integration" "test" { - name = data.scalr_slack_channel.test.name + name = "my-channel" account_id = "acc-xxxx" events = ["run_approval_required", "run_success", "run_errored"] channel_id = "xxxx" //Can be found in slack UI (channel settings/info popup) diff --git a/go.mod b/go.mod index e40de4b4..f970a83a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 - github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086 + github.com/scalr/go-scalr v0.0.0-20230515135351-0dde8be2494a ) require ( diff --git a/go.sum b/go.sum index b92efbb0..3f6934bc 100644 --- a/go.sum +++ b/go.sum @@ -250,6 +250,8 @@ github.com/scalr/go-scalr v0.0.0-20230511140835-ed400653430f h1:TilyG5/f6rLxDIr0 github.com/scalr/go-scalr v0.0.0-20230511140835-ed400653430f/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086 h1:d21fcWDddlrN/RtDG5zxSCm0OPrLsGa04JixySVJLeI= github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= +github.com/scalr/go-scalr v0.0.0-20230515135351-0dde8be2494a h1:L6y2Mv0Liv+CWVcjFx6BoX5avJBCejFhyZNlkVhKeB0= +github.com/scalr/go-scalr v0.0.0-20230515135351-0dde8be2494a/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= diff --git a/scalr/provider_test.go b/scalr/provider_test.go index 6f868b6f..20909631 100644 --- a/scalr/provider_test.go +++ b/scalr/provider_test.go @@ -18,7 +18,7 @@ var testAccProvider *schema.Provider var testAccProviderFactories map[string]func() (*schema.Provider, error) var noInstanceIdErr = fmt.Errorf("No instance ID is set") var githubToken = os.Getenv("githubToken") -var slackChannelName = os.Getenv("SLACK_CHANNEL_ID") +var slackChannelId = os.Getenv("SLACK_CHANNEL_ID") // ctx is used as default context.Context when making API calls. var ctx = context.Background() @@ -124,7 +124,7 @@ func testVcsAccGithubTokenPreCheck(t *testing.T) { func testSlackChannelNamePreCheck(t *testing.T) { testAccPreCheck(t) - if slackChannelName == "" { + if slackChannelId == "" { t.Skip("Please set `SLACK_CHANNEL_ID` OS variable to run this test. Channel should exist on slack account connected scalr instance tests run on.") } } diff --git a/scalr/resource_scalr_slack_integration_test.go b/scalr/resource_scalr_slack_integration_test.go index 600a8ec3..4a59d03c 100644 --- a/scalr/resource_scalr_slack_integration_test.go +++ b/scalr/resource_scalr_slack_integration_test.go @@ -17,9 +17,22 @@ func TestAccSlackIntegration_basic(t *testing.T) { Config: testAccScalrSlackIntegrationConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "id"), - resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "channel_id"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "name", slackChannelName), - resource.TestCheckResourceAttr("scalr_vcs_provider.test", "account_id", defaultAccount), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "name", "test-create"), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "channel_id", slackChannelId), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "account_id", defaultAccount), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.0", "run_approval_required"), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.1", "run_errored"), + ), + }, + { + Config: testAccScalrSlackIntegrationUpdateConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "id"), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "name", "test-create2"), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "channel_id", slackChannelId), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "account_id", defaultAccount), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.0", "run_success"), + resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.1", "run_errored"), ), }, }, @@ -28,19 +41,29 @@ func TestAccSlackIntegration_basic(t *testing.T) { func testAccScalrSlackIntegrationConfig() string { return fmt.Sprintf(` -data "scalr_slack_channel" "test" { - name = "%s" +resource scalr_environment test { + name = "test-env-slack" account_id = "%s" } +resource "scalr_slack_integration" "test" { + name = "test-create" + account_id = scalr_environment.test.account_id + events = ["run_approval_required", "run_errored"] + channel_id = "%s" + environments = [scalr_environment.test.id] +}`, defaultAccount, slackChannelId) +} +func testAccScalrSlackIntegrationUpdateConfig() string { + return fmt.Sprintf(` resource scalr_environment test { name = "test-env-slack" - account_id = data.scalr_slack_channel.test.account_id + account_id = "%s" } resource "scalr_slack_integration" "test" { - name = data.scalr_slack_channel.test.name - account_id = data.scalr_slack_channel.test.account_id - events = ["run_approval_required", "run_errored"] - channel_id = data.scalr_slack_channel.test.id - "environments" = [scalr_environment.test.id] -}`, slackChannelName, defaultAccount) + name = "test-create2" + account_id = scalr_environment.test.account_id + events = ["run_success", "run_errored"] + channel_id = "%s" + environments = [scalr_environment.test.id] +}`, defaultAccount, slackChannelId) } From 0d577b2e398eb22e8534607801f5fa0d799a2793 Mon Sep 17 00:00:00 2001 From: soltysss Date: Fri, 26 May 2023 22:55:03 +0300 Subject: [PATCH 3/9] SCALRCORE-25214 - Provider > Add Slack Integration --- docs/resources/scalr_slack_integration.md | 4 ++-- go.mod | 2 +- go.sum | 2 ++ scalr/resource_scalr_slack_integration.go | 21 ++++++++++----------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/resources/scalr_slack_integration.md b/docs/resources/scalr_slack_integration.md index bb79e585..bb4ec587 100644 --- a/docs/resources/scalr_slack_integration.md +++ b/docs/resources/scalr_slack_integration.md @@ -14,8 +14,8 @@ resource "scalr_slack_integration" "test" { account_id = "acc-xxxx" events = ["run_approval_required", "run_success", "run_errored"] channel_id = "xxxx" //Can be found in slack UI (channel settings/info popup) - "environments" = ["env-xxxxx"] - "workspaces" = ["ws-xxxx", "ws-xxxx"] + environments = ["env-xxxxx"] + workspaces = ["ws-xxxx", "ws-xxxx"] } ``` diff --git a/go.mod b/go.mod index f970a83a..1d765dc1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 - github.com/scalr/go-scalr v0.0.0-20230515135351-0dde8be2494a + github.com/scalr/go-scalr v0.0.0-20230526170256-51c054b58bff ) require ( diff --git a/go.sum b/go.sum index 3f6934bc..d9dc2ff0 100644 --- a/go.sum +++ b/go.sum @@ -252,6 +252,8 @@ github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086 h1:d21fcWDddlrN/RtD github.com/scalr/go-scalr v0.0.0-20230513215051-c4d2974b5086/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/scalr/go-scalr v0.0.0-20230515135351-0dde8be2494a h1:L6y2Mv0Liv+CWVcjFx6BoX5avJBCejFhyZNlkVhKeB0= github.com/scalr/go-scalr v0.0.0-20230515135351-0dde8be2494a/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= +github.com/scalr/go-scalr v0.0.0-20230526170256-51c054b58bff h1:buP08606riJhFOWJn2XH14T9GEW3oe2byV9cxZIfRf0= +github.com/scalr/go-scalr v0.0.0-20230526170256-51c054b58bff/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= diff --git a/scalr/resource_scalr_slack_integration.go b/scalr/resource_scalr_slack_integration.go index 45248657..f4832614 100644 --- a/scalr/resource_scalr_slack_integration.go +++ b/scalr/resource_scalr_slack_integration.go @@ -54,7 +54,6 @@ func resourceScalrSlackIntegration() *schema.Resource { "environments": { Type: schema.TypeSet, Required: true, - ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "workspaces": { @@ -121,11 +120,11 @@ func resourceScalrSlackIntegrationCreate(ctx context.Context, d *schema.Resource envs := parseEnvironments(d) options := scalr.SlackIntegrationCreateOptions{ - Name: &name, - ChannelId: &channelId, - Events: events, - Account: &scalr.Account{ID: d.Get("account_id").(string)}, - Environment: envs[0], + Name: &name, + ChannelId: &channelId, + Events: events, + Account: &scalr.Account{ID: d.Get("account_id").(string)}, + Environments: envs, } workspaces := parseWorkspaces(d) if workspaces != nil { @@ -167,10 +166,10 @@ func resourceScalrSlackIntegrationRead(ctx context.Context, d *schema.ResourceDa _ = d.Set("account_id", slackIntegration.Account.ID) environmentIDs := make([]string, 0) - //for _, environment := range slackIntegration.Environments { - // environmentIDs = append(environmentIDs, environment.ID) - //} - environmentIDs = append(environmentIDs, slackIntegration.Environment.ID) + for _, environment := range slackIntegration.Environments { + environmentIDs = append(environmentIDs, environment.ID) + } + _ = d.Set("environments", environmentIDs) wsIDs := make([]string, 0) @@ -203,7 +202,7 @@ func resourceScalrSlackIntegrationUpdate(ctx context.Context, d *schema.Resource } envs := parseEnvironments(d) - options.Environment = envs[0] + options.Environments = envs workspaces := parseWorkspaces(d) if workspaces != nil { From e079eadd8ee9765c0550fcde2484688bb1ea5e9c Mon Sep 17 00:00:00 2001 From: Petro Protsakh Date: Tue, 6 Jun 2023 17:48:13 +0300 Subject: [PATCH 4/9] SCALRCORE-25214 Fix data race in provider configurations --- scalr/resource_scalr_provider_configuration.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scalr/resource_scalr_provider_configuration.go b/scalr/resource_scalr_provider_configuration.go index 2975c888..e4a40107 100644 --- a/scalr/resource_scalr_provider_configuration.go +++ b/scalr/resource_scalr_provider_configuration.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "sync" + "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -783,15 +784,18 @@ func changeParameters( for i := 0; i < numParallel; i++ { go func() { + reqCtx, reqCancel := context.WithTimeout(context.Background(), time.Second*10) + defer reqCancel() + for t := range inputCh { if t.createOption != nil { - parameter, err := client.ProviderConfigurationParameters.Create(ctx, configurationID, *t.createOption) + parameter, err := client.ProviderConfigurationParameters.Create(reqCtx, configurationID, *t.createOption) resultCh <- result{created: parameter, err: err} } else if t.updateOption != nil { - parameter, err := client.ProviderConfigurationParameters.Update(ctx, t.updateOption.ID, *t.updateOption) + parameter, err := client.ProviderConfigurationParameters.Update(reqCtx, t.updateOption.ID, *t.updateOption) resultCh <- result{updated: parameter, err: err} } else { - err := client.ProviderConfigurationParameters.Delete(ctx, *t.deleteId) + err := client.ProviderConfigurationParameters.Delete(reqCtx, *t.deleteId) resultCh <- result{deleted: t.deleteId, err: err} } } From b89c88e4e21520585c19df7b11fb86e199d21bfa Mon Sep 17 00:00:00 2001 From: Petro Protsakh Date: Mon, 12 Jun 2023 20:30:03 +0300 Subject: [PATCH 5/9] SCALRCORE-25214 Update slack_integration resource --- scalr/provider_test.go | 8 -- scalr/resource_scalr_slack_integration.go | 97 ++++++++++--------- .../resource_scalr_slack_integration_test.go | 82 +++++++++++++--- 3 files changed, 119 insertions(+), 68 deletions(-) diff --git a/scalr/provider_test.go b/scalr/provider_test.go index 20909631..3f24a6ff 100644 --- a/scalr/provider_test.go +++ b/scalr/provider_test.go @@ -18,7 +18,6 @@ var testAccProvider *schema.Provider var testAccProviderFactories map[string]func() (*schema.Provider, error) var noInstanceIdErr = fmt.Errorf("No instance ID is set") var githubToken = os.Getenv("githubToken") -var slackChannelId = os.Getenv("SLACK_CHANNEL_ID") // ctx is used as default context.Context when making API calls. var ctx = context.Background() @@ -121,10 +120,3 @@ func testVcsAccGithubTokenPreCheck(t *testing.T) { t.Skip("Please set githubToken to run this test") } } - -func testSlackChannelNamePreCheck(t *testing.T) { - testAccPreCheck(t) - if slackChannelId == "" { - t.Skip("Please set `SLACK_CHANNEL_ID` OS variable to run this test. Channel should exist on slack account connected scalr instance tests run on.") - } -} diff --git a/scalr/resource_scalr_slack_integration.go b/scalr/resource_scalr_slack_integration.go index f4832614..777a3572 100644 --- a/scalr/resource_scalr_slack_integration.go +++ b/scalr/resource_scalr_slack_integration.go @@ -3,7 +3,6 @@ package scalr import ( "context" "errors" - "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -23,16 +22,21 @@ func resourceScalrSlackIntegration() *schema.Resource { SchemaVersion: 0, Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), }, "events": { - Type: schema.TypeList, + Type: schema.TypeSet, Elem: &schema.Schema{ Type: schema.TypeString, ValidateDiagFunc: validation.ToDiagFunc( validation.StringInSlice( - []string{scalr.RunApprovalRequiredEvent, scalr.RunSuccessEvent, scalr.RunErroredEvent}, + []string{ + scalr.SlackIntegrationEventRunApprovalRequired, + scalr.SlackIntegrationEventRunSuccess, + scalr.SlackIntegrationEventRunErrored, + }, false, ), ), @@ -41,8 +45,9 @@ func resourceScalrSlackIntegration() *schema.Resource { MinItems: 1, }, "channel_id": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), }, "account_id": { Type: schema.TypeString, @@ -52,40 +57,41 @@ func resourceScalrSlackIntegration() *schema.Resource { ForceNew: true, }, "environments": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), + }, Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, + MinItems: 1, }, "workspaces": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), + }, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, }, }, } } -func parseEvents(d *schema.ResourceData) ([]string, error) { - events := make([]string, 0) +func parseEvents(d *schema.ResourceData) []string { + events := d.Get("events").(*schema.Set).List() + eventValues := make([]string, 0) - providedEvents := d.Get("events").([]interface{}) - err := ValidateIDsDefinitions(providedEvents) - if err != nil { - return nil, fmt.Errorf("Got error during parsing events: %s", err.Error()) + for _, event := range events { + eventValues = append(eventValues, event.(string)) } - for _, event := range providedEvents { - e := event.(string) - events = append(events, e) - } - - return events, nil + return eventValues } func parseEnvironments(d *schema.ResourceData) []*scalr.Environment { - environmentsI := d.Get("environments") - environments := environmentsI.(*schema.Set).List() + environments := d.Get("environments").(*schema.Set).List() environmentValues := make([]*scalr.Environment, 0) + for _, env := range environments { environmentValues = append(environmentValues, &scalr.Environment{ID: env.(string)}) } @@ -100,6 +106,7 @@ func parseWorkspaces(d *schema.ResourceData) []*scalr.Workspace { } workspaces := workspacesI.(*schema.Set).List() workspaceValues := make([]*scalr.Workspace, 0) + for _, ws := range workspaces { workspaceValues = append(workspaceValues, &scalr.Workspace{ID: ws.(string)}) } @@ -111,20 +118,14 @@ func resourceScalrSlackIntegrationCreate(ctx context.Context, d *schema.Resource scalrClient := meta.(*scalr.Client) // Get attributes. name := d.Get("name").(string) - channelId := d.Get("channel_id").(string) - events, err := parseEvents(d) - if err != nil { - return diag.Errorf("Error creating slack integration %s: %v", name, err) - } - - envs := parseEnvironments(d) + accountID := d.Get("account_id").(string) options := scalr.SlackIntegrationCreateOptions{ Name: &name, - ChannelId: &channelId, - Events: events, - Account: &scalr.Account{ID: d.Get("account_id").(string)}, - Environments: envs, + ChannelId: scalr.String(d.Get("channel_id").(string)), + Events: parseEvents(d), + Account: &scalr.Account{ID: accountID}, + Environments: parseEnvironments(d), } workspaces := parseWorkspaces(d) if workspaces != nil { @@ -132,9 +133,16 @@ func resourceScalrSlackIntegrationCreate(ctx context.Context, d *schema.Resource } connection, err := scalrClient.SlackIntegrations.GetConnection(ctx, options.Account.ID) + if err != nil { + return diag.Errorf("Error creating slack integration %s: %v", name, err) + } - if err != nil || connection.ID == "" { - return diag.Errorf("Error creating slack integration, account not connected to slack, create slack connection using UI first.") + if connection.ID == "" { + return diag.Errorf( + "Error creating Slack integration: account %s does not have Slack connection configured."+ + " Connect your Slack workspace to Scalr using UI first.", + accountID, + ) } options.Connection = connection @@ -146,7 +154,7 @@ func resourceScalrSlackIntegrationCreate(ctx context.Context, d *schema.Resource } d.SetId(integration.ID) - return nil + return resourceScalrSlackIntegrationRead(ctx, d, meta) } func resourceScalrSlackIntegrationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -194,15 +202,14 @@ func resourceScalrSlackIntegrationUpdate(ctx context.Context, d *schema.Resource } if d.HasChange("events") { - events, err := parseEvents(d) - if err != nil { - return diag.Errorf("Error updating slack integration %s: %v", d.Id(), err) - } + events := parseEvents(d) options.Events = events } - envs := parseEnvironments(d) - options.Environments = envs + if d.HasChange("environments") { + envs := parseEnvironments(d) + options.Environments = envs + } workspaces := parseWorkspaces(d) if workspaces != nil { diff --git a/scalr/resource_scalr_slack_integration_test.go b/scalr/resource_scalr_slack_integration_test.go index 4a59d03c..492159a3 100644 --- a/scalr/resource_scalr_slack_integration_test.go +++ b/scalr/resource_scalr_slack_integration_test.go @@ -10,29 +10,81 @@ import ( func TestAccSlackIntegration_basic(t *testing.T) { resource.Test(t, resource.TestCase{ - PreCheck: func() { testSlackChannelNamePreCheck(t) }, + PreCheck: func() { + testAccPreCheck(t) + + scalrClient, _ := createScalrClient() + slackConnection, err := scalrClient.SlackIntegrations.GetConnection(ctx, defaultAccount) + if err != nil { + t.Fatalf("Error fetching Slack connection: %v", err) + return + } + if slackConnection.ID == "" { + t.Skip("Scalr instance doesn't have working slack connection.") + } + }, ProviderFactories: testAccProviderFactories, Steps: []resource.TestStep{ { Config: testAccScalrSlackIntegrationConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "id"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "name", "test-create"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "channel_id", slackChannelId), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "account_id", defaultAccount), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.0", "run_approval_required"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.1", "run_errored"), + resource.TestCheckResourceAttr( + "scalr_slack_integration.test", + "name", + "test-create", + ), + resource.TestCheckResourceAttr( + "scalr_slack_integration.test", + "channel_id", + "C123", + ), + resource.TestCheckResourceAttr( + "scalr_slack_integration.test", + "account_id", + defaultAccount, + ), + resource.TestCheckTypeSetElemAttr( + "scalr_slack_integration.test", + "events.*", + "run_approval_required", + ), + resource.TestCheckTypeSetElemAttr( + "scalr_slack_integration.test", + "events.*", + "run_errored", + ), ), }, { Config: testAccScalrSlackIntegrationUpdateConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("scalr_slack_integration.test", "id"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "name", "test-create2"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "channel_id", slackChannelId), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "account_id", defaultAccount), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.0", "run_success"), - resource.TestCheckResourceAttr("scalr_slack_integration.test", "events.1", "run_errored"), + resource.TestCheckResourceAttr( + "scalr_slack_integration.test", + "name", + "test-create2", + ), + resource.TestCheckResourceAttr( + "scalr_slack_integration.test", + "channel_id", + "C123", + ), + resource.TestCheckResourceAttr( + "scalr_slack_integration.test", + "account_id", + defaultAccount, + ), + resource.TestCheckTypeSetElemAttr( + "scalr_slack_integration.test", + "events.*", + "run_success", + ), + resource.TestCheckTypeSetElemAttr( + "scalr_slack_integration.test", + "events.*", + "run_errored", + ), ), }, }, @@ -49,9 +101,9 @@ resource "scalr_slack_integration" "test" { name = "test-create" account_id = scalr_environment.test.account_id events = ["run_approval_required", "run_errored"] - channel_id = "%s" + channel_id = "C123" environments = [scalr_environment.test.id] -}`, defaultAccount, slackChannelId) +}`, defaultAccount) } func testAccScalrSlackIntegrationUpdateConfig() string { return fmt.Sprintf(` @@ -63,7 +115,7 @@ resource "scalr_slack_integration" "test" { name = "test-create2" account_id = scalr_environment.test.account_id events = ["run_success", "run_errored"] - channel_id = "%s" + channel_id = "C123" environments = [scalr_environment.test.id] -}`, defaultAccount, slackChannelId) +}`, defaultAccount) } From 0ee3e083a04a4ce0260fdd21f4f2166814c83a7a Mon Sep 17 00:00:00 2001 From: Petro Protsakh Date: Mon, 12 Jun 2023 20:30:53 +0300 Subject: [PATCH 6/9] SCALRCORE-25214 Enable race detection by default during acceptance tests --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 2677230b..299c1e20 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -37,7 +37,7 @@ test: $(BUILD_ENV) xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 testacc: - $(BUILD_ENV) TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 15m -covermode atomic -coverprofile=covprofile + TF_ACC=1 go test -race $(TEST) -v $(TESTARGS) -timeout 15m -covermode atomic -coverprofile=covprofile notify-upstream: curl -X POST \ From d8ad9b61b606fcfab31f1f54956ef80fff390e43 Mon Sep 17 00:00:00 2001 From: Petro Protsakh Date: Mon, 12 Jun 2023 20:32:50 +0300 Subject: [PATCH 7/9] SCALRCORE-25214 Bump go-scalr --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fcd24890..2ea01e9e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 - github.com/scalr/go-scalr v0.0.0-20230601124243-269bd29a43a8 + github.com/scalr/go-scalr v0.0.0-20230612172707-84e1dfe6bf84 ) require ( diff --git a/go.sum b/go.sum index c866e3d6..2746a687 100644 --- a/go.sum +++ b/go.sum @@ -242,8 +242,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/scalr/go-scalr v0.0.0-20230601124243-269bd29a43a8 h1:FG+CAdkX9RrKzMzo54JpPWLu/iEe28ufk9Ti12RR/yc= -github.com/scalr/go-scalr v0.0.0-20230601124243-269bd29a43a8/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= +github.com/scalr/go-scalr v0.0.0-20230612172707-84e1dfe6bf84 h1:YWMFr3mzpTvLKjgC3Hdgtzr+yzyVBLjO7ryp+Gma6dM= +github.com/scalr/go-scalr v0.0.0-20230612172707-84e1dfe6bf84/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= From 9dfe9cb38cadd0269db6bfb61b08f369d3adbf76 Mon Sep 17 00:00:00 2001 From: Petro Protsakh Date: Mon, 12 Jun 2023 21:07:00 +0300 Subject: [PATCH 8/9] SCALRCORE-25214 Update docs --- CHANGELOG.md | 7 ++++++- docs/resources/scalr_slack_integration.md | 25 ++++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b84e3e1..8a8c0c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- **New resource:** `scalr_slack_integration` ([#249](https://github.com/Scalr/terraform-provider-scalr/pull/249)) + ### Changed + - `scar_enviroment`: removed attribute `cloud_credentials` ([#247](https://github.com/Scalr/terraform-provider-scalr/pull/247)) - `data.scalr_enviroment`: removed attribute `cloud_credentials` ([#247](https://github.com/Scalr/terraform-provider-scalr/pull/247)) ### Fixed + - `scalr_provider_configuration_default`: fixed a bug where unnecessary policy groups updates were occurring for the environment ([#248](https://github.com/Scalr/terraform-provider-scalr/pull/248)) ## [1.0.6] - 2023-05-12 @@ -21,7 +27,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The provider now supports loading the credentials stored by `terraform login` ([#221](https://github.com/Scalr/terraform-provider-scalr/pull/221)) - **New data source:** `scalr_environments` ([#225](https://github.com/Scalr/terraform-provider-scalr/pull/225)) - **New data source:** `scalr_workspaces` ([#225](https://github.com/Scalr/terraform-provider-scalr/pull/225)) -- **New resource:** `scalr_slack_integration` ([#250](https://github.com/Scalr/terraform-provider-scalr/pull/250)) ### Changed diff --git a/docs/resources/scalr_slack_integration.md b/docs/resources/scalr_slack_integration.md index bb4ec587..9e2584a7 100644 --- a/docs/resources/scalr_slack_integration.md +++ b/docs/resources/scalr_slack_integration.md @@ -1,8 +1,8 @@ # Resource `scalr_slack_integration` -Manage the state of slack integrations in Scalr. Create, update and destroy. -Slack workspace should be connected to scalr account before using this resource. +Manage the state of Slack integrations in Scalr. Create, update and destroy. +Slack workspace should be connected to Scalr account before using this resource. ## Example Usage @@ -10,10 +10,10 @@ Basic usage: ```hcl resource "scalr_slack_integration" "test" { - name = "my-channel" - account_id = "acc-xxxx" - events = ["run_approval_required", "run_success", "run_errored"] - channel_id = "xxxx" //Can be found in slack UI (channel settings/info popup) + name = "my-channel" + account_id = "acc-xxxx" + events = ["run_approval_required", "run_success", "run_errored"] + channel_id = "xxxx" # Can be found in slack UI (channel settings/info popup) environments = ["env-xxxxx"] workspaces = ["ws-xxxx", "ws-xxxx"] } @@ -21,13 +21,14 @@ resource "scalr_slack_integration" "test" { ## Argument Reference -* `name` - (Required) Name of the slack integration. -* `channel_id` - (Required) Slack channel event should be sent to. +* `name` - (Required) Name of the Slack integration. +* `channel_id` - (Required) Slack channel ID the event will be sent to. * `events` - (Required) Terraform run events you would like to receive a Slack notifications for. -Supported values are `run_approval_required`, `run_success`, `run_errored` -* `environments` - (Required) List of environments where events should be triggered on. -* `environments` - (Optional) List of workspaces where events should be triggered on. -Workspaces should be in provided environments. +Supported values are `run_approval_required`, `run_success`, `run_errored`. +* `environments` - (Required) List of environments where events should be triggered. +* `workspaces` - (Optional) List of workspaces where events should be triggered. +Workspaces should be in provided environments. If no workspace is given for a specified environment, +events will trigger in all of its workspaces. * `account_id` - (Optional) ID of the account. From cdc8fbb1e0c0ae4f34934263da23e11432153fe4 Mon Sep 17 00:00:00 2001 From: Admin Admin Date: Fri, 16 Jun 2023 16:08:55 +0300 Subject: [PATCH 9/9] Update changelog --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a8c0c86..d1ecdfe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.0] - 2023-06-16 + ### Added - **New resource:** `scalr_slack_integration` ([#249](https://github.com/Scalr/terraform-provider-scalr/pull/249)) +- The provider now supports loading the credentials stored by `terraform login` ([#221](https://github.com/Scalr/terraform-provider-scalr/pull/221)) ### Changed @@ -20,11 +23,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `scalr_provider_configuration_default`: fixed a bug where unnecessary policy groups updates were occurring for the environment ([#248](https://github.com/Scalr/terraform-provider-scalr/pull/248)) +### Required + +- scalr-server >= `8.71.0` + ## [1.0.6] - 2023-05-12 ### Added -- The provider now supports loading the credentials stored by `terraform login` ([#221](https://github.com/Scalr/terraform-provider-scalr/pull/221)) - **New data source:** `scalr_environments` ([#225](https://github.com/Scalr/terraform-provider-scalr/pull/225)) - **New data source:** `scalr_workspaces` ([#225](https://github.com/Scalr/terraform-provider-scalr/pull/225)) @@ -686,7 +692,8 @@ Requires Scalr 8.0.1-beta.20200625 at least - Initial release. -[Unreleased]: https://github.com/Scalr/terraform-provider-scalr/compare/v1.0.6...HEAD +[Unreleased]: https://github.com/Scalr/terraform-provider-scalr/compare/v1.1.0...HEAD +[1.1.0]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.1.0 [1.0.6]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.6 [1.0.5]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.5 [1.0.4]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.4