-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
Add s3_backup_mode option in Firehose Redshift destination #1830
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,59 @@ func cloudWatchLoggingOptionsSchema() *schema.Schema { | |
} | ||
} | ||
|
||
func S3BackupConfigurationSchema() *schema.Schema { | ||
return &schema.Schema{ | ||
Type: schema.TypeSet, | ||
MaxItems: 1, | ||
Optional: true, | ||
Computed: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"bucket_arn": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"buffer_size": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Default: 5, | ||
}, | ||
|
||
"buffer_interval": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Default: 300, | ||
}, | ||
|
||
"compression_format": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "UNCOMPRESSED", | ||
}, | ||
|
||
"kms_key_arn": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ValidateFunc: validateArn, | ||
}, | ||
|
||
"role_arn": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"prefix": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"cloudwatch_logging_options": cloudWatchLoggingOptionsSchema(), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func processingConfigurationSchema() *schema.Schema { | ||
return &schema.Schema{ | ||
Type: schema.TypeList, | ||
|
@@ -281,6 +334,22 @@ func resourceAwsKinesisFirehoseDeliveryStream() *schema.Resource { | |
Required: true, | ||
}, | ||
|
||
"s3_backup_mode": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "Disabled", | ||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { | ||
value := v.(string) | ||
if value != "Disabled" && value != "Enabled" { | ||
errors = append(errors, fmt.Errorf( | ||
"%q must be one of 'Disabled', 'Enabled'", k)) | ||
} | ||
return | ||
}, | ||
}, | ||
|
||
"s3_backup_configuration": S3BackupConfigurationSchema(), | ||
|
||
"retry_duration": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
|
@@ -467,6 +536,34 @@ func createS3Config(d *schema.ResourceData) *firehose.S3DestinationConfiguration | |
return configuration | ||
} | ||
|
||
func createS3BackupConfig(d *schema.ResourceData) *firehose.S3DestinationConfiguration { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mind reducing the scope here? i.e. the function doesn't need access to the whole schema (all fields), all it needs is a single field, so we can pass it as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also it is a convention throughout the codebase to call these functions "expanders" - i.e. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @radeksimko We're not using "expanders" for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't notice that previously - good catch - we should certainly fix that, but I'd prefer to do it in a separate PR which may come afterwards to keep the context & LOC low here. 😉 |
||
redshiftConfig := d.Get("redshift_configuration").([]interface{})[0].(map[string]interface{}) | ||
config := redshiftConfig["s3_backup_configuration"].(*schema.Set).List() | ||
if len(config) == 0 { | ||
return nil | ||
} | ||
|
||
s3 := config[0].(map[string]interface{}) | ||
|
||
configuration := &firehose.S3DestinationConfiguration{ | ||
BucketARN: aws.String(s3["bucket_arn"].(string)), | ||
RoleARN: aws.String(s3["role_arn"].(string)), | ||
BufferingHints: &firehose.BufferingHints{ | ||
IntervalInSeconds: aws.Int64(int64(s3["buffer_interval"].(int))), | ||
SizeInMBs: aws.Int64(int64(s3["buffer_size"].(int))), | ||
}, | ||
Prefix: extractPrefixConfiguration(s3), | ||
CompressionFormat: aws.String(s3["compression_format"].(string)), | ||
EncryptionConfiguration: extractEncryptionConfiguration(s3), | ||
} | ||
|
||
if _, ok := s3["cloudwatch_logging_options"]; ok { | ||
configuration.CloudWatchLoggingOptions = extractCloudWatchLoggingConfiguration(s3) | ||
} | ||
|
||
return configuration | ||
} | ||
|
||
func createExtendedS3Config(d *schema.ResourceData) *firehose.ExtendedS3DestinationConfiguration { | ||
s3 := d.Get("extended_s3_configuration").([]interface{})[0].(map[string]interface{}) | ||
|
||
|
@@ -516,6 +613,35 @@ func updateS3Config(d *schema.ResourceData) *firehose.S3DestinationUpdate { | |
return configuration | ||
} | ||
|
||
func updateS3BackupConfig(d *schema.ResourceData) *firehose.S3DestinationUpdate { | ||
redshiftConfig := d.Get("redshift_configuration").([]interface{})[0].(map[string]interface{}) | ||
config := redshiftConfig["s3_backup_configuration"].(*schema.Set).List() | ||
if len(config) == 0 { | ||
return nil | ||
} | ||
|
||
s3 := config[0].(map[string]interface{}) | ||
|
||
configuration := &firehose.S3DestinationUpdate{ | ||
BucketARN: aws.String(s3["bucket_arn"].(string)), | ||
RoleARN: aws.String(s3["role_arn"].(string)), | ||
BufferingHints: &firehose.BufferingHints{ | ||
IntervalInSeconds: aws.Int64((int64)(s3["buffer_interval"].(int))), | ||
SizeInMBs: aws.Int64((int64)(s3["buffer_size"].(int))), | ||
}, | ||
Prefix: extractPrefixConfiguration(s3), | ||
CompressionFormat: aws.String(s3["compression_format"].(string)), | ||
EncryptionConfiguration: extractEncryptionConfiguration(s3), | ||
CloudWatchLoggingOptions: extractCloudWatchLoggingConfiguration(s3), | ||
} | ||
|
||
if _, ok := s3["cloudwatch_logging_options"]; ok { | ||
configuration.CloudWatchLoggingOptions = extractCloudWatchLoggingConfiguration(s3) | ||
} | ||
|
||
return configuration | ||
} | ||
|
||
func updateExtendedS3Config(d *schema.ResourceData) *firehose.ExtendedS3DestinationUpdate { | ||
s3 := d.Get("extended_s3_configuration").([]interface{})[0].(map[string]interface{}) | ||
|
||
|
@@ -657,6 +783,10 @@ func createRedshiftConfig(d *schema.ResourceData, s3Config *firehose.S3Destinati | |
if _, ok := redshift["cloudwatch_logging_options"]; ok { | ||
configuration.CloudWatchLoggingOptions = extractCloudWatchLoggingConfiguration(redshift) | ||
} | ||
if s3BackupMode, ok := redshift["s3_backup_mode"]; ok { | ||
configuration.S3BackupMode = aws.String(s3BackupMode.(string)) | ||
configuration.S3BackupConfiguration = createS3BackupConfig(d) | ||
} | ||
|
||
return configuration, nil | ||
} | ||
|
@@ -683,6 +813,10 @@ func updateRedshiftConfig(d *schema.ResourceData, s3Update *firehose.S3Destinati | |
if _, ok := redshift["cloudwatch_logging_options"]; ok { | ||
configuration.CloudWatchLoggingOptions = extractCloudWatchLoggingConfiguration(redshift) | ||
} | ||
if s3BackupMode, ok := redshift["s3_backup_mode"]; ok { | ||
configuration.S3BackupMode = aws.String(s3BackupMode.(string)) | ||
configuration.S3BackupUpdate = updateS3BackupConfig(d) | ||
} | ||
|
||
return configuration, nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@radeksimko I have a doubt here. When do we use
TypeSet
vsTypeList
?I see
S3ConfigurationSchema
hasTypeList
withMaxItems: 1
. Is this significant only during type assertion?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set is used when order doesn't matter, list is used in all other cases and typically with
MaxItems: 1
for easier referencing as we can predict the index, i.e.field_name.0.nested_field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other words it would be better to use
TypeList
here.Can't we call this
s3ConfigurationSchema
and use it in"s3_configuration"
too to reduce the repetition a bit?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was going for and noticed that the schemaTypes are different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@radeksimko Just curious. Why do we use
TypeList
here then? The order doesn't matter here, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, it doesn't, but also there's really nothing to order 😃 as we only ever have a single item in the list and
TypeList
makes it more convenient for referencing purposes, i.e.field_name.0.nested_field
instead offield_name.<computed-index>.nested_field
.