Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add AWS_SNS notification_provider support for error notifications for Snowpipe. #777

Merged
merged 5 commits into from
Dec 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion docs/resources/notification_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ resource snowflake_notification_integration integration {
notification_provider = "AWS_SQS"
aws_sqs_arn = "..."
aws_sqs_role_arn = "..."

# AWS_SNS
notification_provider = "AWS_SNS"
aws_sns_arn = "..."
aws_sns_role_arn = "..."
}
```

Expand All @@ -42,6 +47,8 @@ resource snowflake_notification_integration integration {

### Optional

- **aws_sns_arn** (String) AWS SNS Topic ARN for notification integration to connect to
- **aws_sns_role_arn** (String) AWS IAM role ARN for notification integration to assume
- **aws_sqs_arn** (String) AWS SQS queue ARN for notification integration to connect to
- **aws_sqs_role_arn** (String) AWS IAM role ARN for notification integration to assume
- **azure_storage_queue_primary_uri** (String) The queue ID for the Azure Queue Storage queue created for Event Grid notifications
Expand All @@ -51,11 +58,13 @@ resource snowflake_notification_integration integration {
- **enabled** (Boolean)
- **gcp_pubsub_subscription_name** (String) The subscription id that Snowflake will listen to when using the GCP_PUBSUB provider.
- **id** (String) The ID of this resource.
- **notification_provider** (String) The third-party cloud message queuing service (e.g. AZURE_STORAGE_QUEUE, AWS_SQS)
- **notification_provider** (String) The third-party cloud message queuing service (e.g. AZURE_STORAGE_QUEUE, AWS_SQS, AWS_SNS)
- **type** (String) A type of integration

### Read-Only

- **aws_sns_external_id** (String) The external ID that Snowflake will use when assuming the AWS role
- **aws_sns_iam_user_arn** (String) The Snowflake user that will attempt to assume the AWS role.
- **aws_sqs_external_id** (String) The external ID that Snowflake will use when assuming the AWS role
- **aws_sqs_iam_user_arn** (String) The Snowflake user that will attempt to assume the AWS role.
- **created_on** (String) Date and time when the notification integration was created.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ resource snowflake_notification_integration integration {
notification_provider = "AWS_SQS"
aws_sqs_arn = "..."
aws_sqs_role_arn = "..."

# AWS_SNS
notification_provider = "AWS_SNS"
aws_sns_arn = "..."
aws_sns_role_arn = "..."
}
56 changes: 54 additions & 2 deletions pkg/resources/notification_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ var notificationIntegrationSchema = map[string]*schema.Schema{
"notification_provider": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"AZURE_STORAGE_QUEUE", "AWS_SQS", "GCP_PUBSUB"}, true),
Description: "The third-party cloud message queuing service (e.g. AZURE_STORAGE_QUEUE, AWS_SQS)",
ValidateFunc: validation.StringInSlice([]string{"AZURE_STORAGE_QUEUE", "AWS_SQS", "AWS_SNS", "GCP_PUBSUB"}, true),
Description: "The third-party cloud message queuing service (e.g. AZURE_STORAGE_QUEUE, AWS_SQS, AWS_SNS)",
},
"azure_storage_queue_primary_uri": &schema.Schema{
Type: schema.TypeString,
Expand Down Expand Up @@ -73,6 +73,26 @@ var notificationIntegrationSchema = map[string]*schema.Schema{
Optional: true,
Description: "AWS IAM role ARN for notification integration to assume",
},
"aws_sns_external_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The external ID that Snowflake will use when assuming the AWS role",
},
"aws_sns_iam_user_arn": {
Type: schema.TypeString,
Computed: true,
Description: "The Snowflake user that will attempt to assume the AWS role.",
},
"aws_sns_arn": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "AWS SNS Topic ARN for notification integration to connect to",
},
"aws_sns_role_arn": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "AWS IAM role ARN for notification integration to assume",
},
"comment": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -142,6 +162,12 @@ func CreateNotificationIntegration(data *schema.ResourceData, meta interface{})
if v, ok := data.GetOk("aws_sqs_role_arn"); ok {
stmt.SetString(`AWS_SQS_ROLE_ARN`, v.(string))
}
if v, ok := data.GetOk("aws_sns_arn"); ok {
stmt.SetString(`AWS_SNS_ARN`, v.(string))
}
if v, ok := data.GetOk("aws_sns_role_arn"); ok {
stmt.SetString(`AWS_SNS_ROLE_ARN`, v.(string))
}
if v, ok := data.GetOk("gcp_pubsub_subscription_name"); ok {
stmt.SetString(`GCP_PUBSUB_SUBSCRIPTION_NAME`, v.(string))
}
Expand Down Expand Up @@ -245,6 +271,22 @@ func ReadNotificationIntegration(data *schema.ResourceData, meta interface{}) er
if err = data.Set("aws_sqs_iam_user_arn", v.(string)); err != nil {
return err
}
case "AWS_SNS_ARN":
if err = data.Set("aws_sns_arn", v.(string)); err != nil {
return err
}
case "AWS_SNS_ROLE_ARN":
if err = data.Set("aws_sns_role_arn", v.(string)); err != nil {
return err
}
case "SF_AWS_EXTERNAL_ID":
if err = data.Set("aws_sns_external_id", v.(string)); err != nil {
return err
}
case "SF_AWS_IAM_USER_ARN":
if err = data.Set("aws_sns_iam_user_arn", v.(string)); err != nil {
return err
}
case "GCP_PUBSUB_SUBSCRIPTION_NAME":
if err = data.Set("gcp_pubsub_subscription_name", v.(string)); err != nil {
return err
Expand Down Expand Up @@ -313,6 +355,16 @@ func UpdateNotificationIntegration(data *schema.ResourceData, meta interface{})
stmt.SetString("AWS_SQS_ROLE_ARN", data.Get("aws_sqs_role_arn").(string))
}

if data.HasChange("aws_sns_arn") {
runSetStatement = true
stmt.SetString("AWS_SNS_ARN", data.Get("aws_sns_arn").(string))
}

if data.HasChange("aws_sns_role_arn") {
runSetStatement = true
stmt.SetString("AWS_SNS_ROLE_ARN", data.Get("aws_sns_role_arn").(string))
}

if data.HasChange("gcp_pubsub_subscription_name") {
runSetStatement = true
stmt.SetString("GCP_PUBSUB_SUBSCRIPTION_NAME", data.Get("gcp_pubsub_subscription_name").(string))
Expand Down
23 changes: 23 additions & 0 deletions pkg/resources/notification_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ func TestNotificationIntegrationCreate(t *testing.T) {
},
expectSQL: `^CREATE NOTIFICATION INTEGRATION "test_notification_integration" AWS_SQS_ARN='some-sqs-arn' AWS_SQS_ROLE_ARN='some-iam-role-arn' COMMENT='great comment' DIRECTION='OUTBOUND' NOTIFICATION_PROVIDER='AWS_SQS' TYPE='QUEUE' ENABLED=true$`,
},
{
notificationProvider: "AWS_SNS",
raw: map[string]interface{}{
"name": "test_notification_integration",
"comment": "great comment",
"direction": "OUTBOUND",
"notification_provider": "AWS_SNS",
"aws_sns_arn": "some-sns-arn",
"aws_sns_role_arn": "some-iam-role-arn",
},
expectSQL: `^CREATE NOTIFICATION INTEGRATION "test_notification_integration" AWS_SNS_ARN='some-sns-arn' AWS_SNS_ROLE_ARN='some-iam-role-arn' COMMENT='great comment' DIRECTION='OUTBOUND' NOTIFICATION_PROVIDER='AWS_SNS' TYPE='QUEUE' ENABLED=true$`,
},
{
notificationProvider: "GCP_PUBSUB",
raw: map[string]interface{}{
Expand Down Expand Up @@ -83,6 +95,9 @@ func TestNotificationIntegrationRead(t *testing.T) {
{
notificationProvider: "AWS_SQS",
},
{
notificationProvider: "AWS_SNS",
},
{
notificationProvider: "GCP_PUBSUB",
},
Expand Down Expand Up @@ -137,6 +152,14 @@ func expectReadNotificationIntegration(mock sqlmock.Sqlmock, notificationProvide
AddRow("AWS_SQS_ROLE_ARN", "String", "some-iam-role-arn", nil).
AddRow("AWS_SQS_EXTERNAL_ID", "String", "AGreatExternalID", nil).
AddRow("AWS_SQS_IAM_USER_ARN", "String", "some-iam-user-arn", nil)
case "AWS_SNS":
descRows = descRows.
AddRow("NOTIFICATION_PROVIDER", "String", notificationProvider, nil).
AddRow("DIRECTION", "String", "OUTBOUND", nil).
AddRow("AWS_SNS_ARN", "String", "some-sns-arn", nil).
AddRow("AWS_SNS_ROLE_ARN", "String", "some-iam-role-arn", nil).
AddRow("SF_AWS_EXTERNAL_ID", "String", "AGreatExternalID", nil).
AddRow("SF_AWS_IAM_USER_ARN", "String", "some-iam-user-arn", nil)
case "GCP_PUBSUB":
descRows = descRows.
AddRow("NOTIFICATION_PROVIDER", "String", notificationProvider, nil).
Expand Down
20 changes: 20 additions & 0 deletions pkg/snowflake/notification_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,23 @@ func TestNotificationIntegration_AWS(t *testing.T) {

r.Equal(`CREATE NOTIFICATION INTEGRATION "aws_sqs" AWS_SQS_ARN='some-sqs-arn' AWS_SQS_ROLE_ARN='some-iam-role-arn' DIRECTION='OUTBOUND' TYPE='QUEUE' ENABLED=true`, q)
}

func TestNotificationIntegration_AWS_SNS(t *testing.T) {
r := require.New(t)
builder := snowflake.NotificationIntegration("aws_sns")
r.NotNil(builder)

q := builder.Show()
r.Equal("SHOW NOTIFICATION INTEGRATIONS LIKE 'aws_sns'", q)

c := builder.Create()

c.SetString(`type`, `QUEUE`)
c.SetString(`direction`, `OUTBOUND`)
c.SetString(`aws_sns_arn`, `some-sns-arn`)
c.SetString(`aws_sns_role_arn`, `some-iam-role-arn`)
c.SetBool(`enabled`, true)
q = c.Statement()

r.Equal(`CREATE NOTIFICATION INTEGRATION "aws_sns" AWS_SNS_ARN='some-sns-arn' AWS_SNS_ROLE_ARN='some-iam-role-arn' DIRECTION='OUTBOUND' TYPE='QUEUE' ENABLED=true`, q)
}