diff --git a/awsmt/data_source_playback_configuration.go b/awsmt/data_source_playback_configuration.go index 1e4389c..20c4879 100644 --- a/awsmt/data_source_playback_configuration.go +++ b/awsmt/data_source_playback_configuration.go @@ -2,7 +2,7 @@ package awsmt import ( "context" - "github.com/aws/aws-sdk-go/service/mediatailor" + "github.com/aws/aws-sdk-go-v2/service/mediatailor" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" @@ -18,7 +18,7 @@ func DataSourcePlaybackConfiguration() datasource.DataSource { } type dataSourcePlaybackConfiguration struct { - client *mediatailor.MediaTailor + client *mediatailor.Client } func (d *dataSourcePlaybackConfiguration) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { @@ -30,7 +30,7 @@ func (d *dataSourcePlaybackConfiguration) Schema(_ context.Context, _ datasource Attributes: map[string]schema.Attribute{ "id": computedString, "ad_decision_server_url": computedString, - "avail_supression": schema.SingleNestedAttribute{ + "avail_suppression": schema.SingleNestedAttribute{ Computed: true, Attributes: map[string]schema.Attribute{ "fill_policy": computedString, @@ -107,20 +107,20 @@ func (d *dataSourcePlaybackConfiguration) Configure(_ context.Context, req datas return } - d.client = req.ProviderData.(clients).v1 + d.client = req.ProviderData.(clients).v2 } func (d *dataSourcePlaybackConfiguration) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { var data playbackConfigurationModel - diags := req.Config.Get(ctx, &data) - resp.Diagnostics.Append(diags...) + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { return } name := data.Name - playbackConfiguration, err := d.client.GetPlaybackConfiguration(&mediatailor.GetPlaybackConfigurationInput{Name: name}) + playbackConfiguration, err := d.client.GetPlaybackConfiguration(context.TODO(), &mediatailor.GetPlaybackConfigurationInput{Name: name}) if err != nil { resp.Diagnostics.AddError( "Error while retrieving the playback configuration "+err.Error(), @@ -129,7 +129,7 @@ func (d *dataSourcePlaybackConfiguration) Read(ctx context.Context, req datasour return } - data = readPlaybackConfigToPlan(data, mediatailor.PutPlaybackConfigurationOutput(*playbackConfiguration)) + m := putPlaybackConfigurationModelbuilder{model: &data, output: mediatailor.PutPlaybackConfigurationOutput(*playbackConfiguration), isResource: false} - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + resp.Diagnostics.Append(resp.State.Set(ctx, m.getModel())...) } diff --git a/awsmt/data_source_playback_configuration_test.go b/awsmt/data_source_playback_configuration_test.go index d6175f3..7c91dc5 100644 --- a/awsmt/data_source_playback_configuration_test.go +++ b/awsmt/data_source_playback_configuration_test.go @@ -16,9 +16,9 @@ func TestAccPlaybackConfigurationDataSourceBasic(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "id", "example-playback-configuration-awsmt"), resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "ad_decision_server_url", "https://exampleurl.com/"), - resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "avail_supression.fill_policy", "FULL_AVAIL_ONLY"), - resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "avail_supression.mode", "BEHIND_LIVE_EDGE"), - resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "avail_supression.value", "00:00:00"), + resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "avail_suppression.fill_policy", "FULL_AVAIL_ONLY"), + resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "avail_suppression.mode", "BEHIND_LIVE_EDGE"), + resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "avail_suppression.value", "00:00:00"), resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "bumper.end_url", "https://wxample.com/endbumper"), resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "bumper.start_url", "https://wxample.com/startbumper"), resource.TestCheckResourceAttr("data.awsmt_playback_configuration.test", "cdn_configuration.ad_segment_url_prefix", "https://exampleurl.com/"), @@ -55,7 +55,7 @@ func TestAccPlaybackConfigurationDataSourceErrors(t *testing.T) { func playbackConfigDS() string { return `resource "awsmt_playback_configuration" "r1" { ad_decision_server_url = "https://exampleurl.com/" - avail_supression = { + avail_suppression = { fill_policy = "FULL_AVAIL_ONLY" mode = "BEHIND_LIVE_EDGE" value = "00:00:00" @@ -101,7 +101,7 @@ func playbackConfigDS() string { func plabackConfigDSError() string { return `resource "awsmt_playback_configuration" "r1" { ad_decision_server_url = "https://exampleurl.com/" - avail_supression = { + avail_suppression = { fill_policy = "FULL_AVAIL_ONLY" mode = "BEHIND_LIVE_EDGE" value = "00:00:00" diff --git a/awsmt/helpers_playback_configuration.go b/awsmt/helpers_playback_configuration.go index 671dda3..0a6416d 100644 --- a/awsmt/helpers_playback_configuration.go +++ b/awsmt/helpers_playback_configuration.go @@ -1,292 +1,320 @@ package awsmt import ( - "github.com/aws/aws-sdk-go/service/mediatailor" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/mediatailor" + awsTypes "github.com/aws/aws-sdk-go-v2/service/mediatailor/types" "github.com/hashicorp/terraform-plugin-framework/types" ) -func playbackConfigurationInput(plan playbackConfigurationModel) mediatailor.PutPlaybackConfigurationInput { +type putPlaybackConfigurationInputBuilder struct { + model playbackConfigurationModel + input *mediatailor.PutPlaybackConfigurationInput +} - input := &mediatailor.PutPlaybackConfigurationInput{} +type putPlaybackConfigurationModelbuilder struct { + model *playbackConfigurationModel + output mediatailor.PutPlaybackConfigurationOutput + isResource bool +} - input.AdDecisionServerUrl = plan.AdDecisionServerUrl +func (i *putPlaybackConfigurationInputBuilder) getInput() *mediatailor.PutPlaybackConfigurationInput { - if plan.AvailSupression != nil { - input.AvailSuppression = getAvailSuppressionInput(plan.AvailSupression) - } + i.addAvailSuppressionToInput() + i.addBumperToInput() + i.addCdnConfigurationToInput() + i.addDashConfigurationToInput() + i.addLivePreRollConfigurationToInput() + i.addManifestProcessingRulesToInput() + i.addOptionalFieldsToInput() + i.addRequiredFieldsToInput() - if plan.Bumper != nil { - input.Bumper = getBumperInput(plan.Bumper) + return i.input +} + +func (i *putPlaybackConfigurationInputBuilder) addAvailSuppressionToInput() { + if i.model.AvailSuppression == nil { + return + } + temp := &awsTypes.AvailSuppression{} + if i.model.AvailSuppression.Mode != nil { + var mode awsTypes.Mode + switch *i.model.AvailSuppression.Mode { + case "BEHIND_LIVE_EDGE": + mode = awsTypes.ModeBehindLiveEdge + case "AFTER_LIVE_EDGE": + mode = awsTypes.ModeAfterLiveEdge + default: + mode = awsTypes.ModeOff + } + temp.Mode = mode } + if i.model.AvailSuppression.Value != nil { + temp.Value = i.model.AvailSuppression.Value + } + if i.model.AvailSuppression.FillPolicy != nil { + var policy awsTypes.FillPolicy + if *i.model.AvailSuppression.FillPolicy == "FULL_AVAIL_ONLY" { + policy = awsTypes.FillPolicyFullAvailOnly + } else { + policy = awsTypes.FillPolicyPartialAvail + } + temp.FillPolicy = policy + } + i.input.AvailSuppression = temp +} - if plan.CdnConfiguration != nil { - input.CdnConfiguration = getCdnConfigurationInput(plan.CdnConfiguration) +func (i *putPlaybackConfigurationInputBuilder) addBumperToInput() { + if i.model.Bumper == nil { + return + } + temp := &awsTypes.Bumper{} + if i.model.Bumper.EndUrl != nil { + temp.EndUrl = i.model.Bumper.EndUrl } + if i.model.Bumper.StartUrl != nil { + temp.StartUrl = i.model.Bumper.StartUrl + } + i.input.Bumper = temp + +} - if plan.ConfigurationAliases != nil { - input.ConfigurationAliases = plan.ConfigurationAliases +func (i *putPlaybackConfigurationInputBuilder) addCdnConfigurationToInput() { + if i.model.CdnConfiguration == nil { + return + } + temp := &awsTypes.CdnConfiguration{} + if i.model.CdnConfiguration != nil { + if i.model.CdnConfiguration.AdSegmentUrlPrefix != nil { + temp.AdSegmentUrlPrefix = i.model.CdnConfiguration.AdSegmentUrlPrefix + } + if i.model.CdnConfiguration.ContentSegmentUrlPrefix != nil { + temp.ContentSegmentUrlPrefix = i.model.CdnConfiguration.ContentSegmentUrlPrefix + } } + i.input.CdnConfiguration = temp +} - if plan.DashConfiguration != nil { - input.DashConfiguration = getDashConfigurationInput(plan.DashConfiguration) +func (i *putPlaybackConfigurationInputBuilder) addDashConfigurationToInput() { + if i.model.DashConfiguration == nil { + return + } + temp := &awsTypes.DashConfigurationForPut{} + if i.model.DashConfiguration.MpdLocation != nil { + temp.MpdLocation = i.model.DashConfiguration.MpdLocation + } + if i.model.DashConfiguration.OriginManifestType != nil { + var manifestType awsTypes.OriginManifestType + if *i.model.DashConfiguration.OriginManifestType == "SINGLE_PERIOD" { + manifestType = awsTypes.OriginManifestTypeSinglePeriod + } else { + manifestType = awsTypes.OriginManifestTypeMultiPeriod + } + temp.OriginManifestType = manifestType } + i.input.DashConfiguration = temp +} - if plan.LivePreRollConfiguration != nil { - input.LivePreRollConfiguration = getLivePreRollConfigurationInput(plan.LivePreRollConfiguration) +func (i *putPlaybackConfigurationInputBuilder) addLivePreRollConfigurationToInput() { + if i.model.LivePreRollConfiguration == nil { + return + } + temp := &awsTypes.LivePreRollConfiguration{} + if i.model.LivePreRollConfiguration.AdDecisionServerUrl != nil { + temp.AdDecisionServerUrl = i.model.LivePreRollConfiguration.AdDecisionServerUrl + } + if i.model.LivePreRollConfiguration.MaxDurationSeconds != nil { + temp.MaxDurationSeconds = i.model.LivePreRollConfiguration.MaxDurationSeconds } + i.input.LivePreRollConfiguration = temp +} - if plan.ManifestProcessingRules != nil { - input.ManifestProcessingRules = &mediatailor.ManifestProcessingRules{ - AdMarkerPassthrough: &mediatailor.AdMarkerPassthrough{ - Enabled: plan.ManifestProcessingRules.AdMarkerPassthrough.Enabled, - }, +func (i *putPlaybackConfigurationInputBuilder) addManifestProcessingRulesToInput() { + if i.model.ManifestProcessingRules == nil { + return + } + temp := &awsTypes.ManifestProcessingRules{} + if i.model.ManifestProcessingRules.AdMarkerPassthrough != nil { + temp.AdMarkerPassthrough = &awsTypes.AdMarkerPassthrough{ + Enabled: i.model.ManifestProcessingRules.AdMarkerPassthrough.Enabled, } } + i.input.ManifestProcessingRules = temp +} - input.Name = plan.Name +func (i *putPlaybackConfigurationInputBuilder) addOptionalFieldsToInput() { + if i.model.ConfigurationAliases != nil { + i.input.ConfigurationAliases = i.model.ConfigurationAliases + } - if plan.PersonalizationThresholdSeconds != nil { - input.PersonalizationThresholdSeconds = plan.PersonalizationThresholdSeconds + if i.model.PersonalizationThresholdSeconds != nil { + i.input.PersonalizationThresholdSeconds = i.model.PersonalizationThresholdSeconds } - if plan.SlateAdUrl != nil && *plan.SlateAdUrl != "" { - input.SlateAdUrl = plan.SlateAdUrl + if i.model.SlateAdUrl != nil { + i.input.SlateAdUrl = i.model.SlateAdUrl } - if plan.Tags != nil { - input.Tags = plan.Tags + if i.model.Tags != nil { + i.input.Tags = i.model.Tags } - if plan.TranscodeProfileName != nil && *plan.TranscodeProfileName != "" { - input.TranscodeProfileName = plan.TranscodeProfileName + if i.model.TranscodeProfileName != nil { + i.input.TranscodeProfileName = i.model.TranscodeProfileName } - if plan.VideoContentSourceUrl != nil && *plan.VideoContentSourceUrl != "" { - input.VideoContentSourceUrl = plan.VideoContentSourceUrl + if i.model.VideoContentSourceUrl != nil { + i.input.VideoContentSourceUrl = i.model.VideoContentSourceUrl } +} - return *input +func (i *putPlaybackConfigurationInputBuilder) addRequiredFieldsToInput() { + i.input.AdDecisionServerUrl = i.model.AdDecisionServerUrl + i.input.Name = i.model.Name } -func getAvailSuppressionInput(availSuppression *availSupressionModel) *mediatailor.AvailSuppression { - params := &mediatailor.AvailSuppression{} - if availSuppression != nil { - if availSuppression.Mode != nil { - params.Mode = availSuppression.Mode - } - if availSuppression.Value != nil { - params.Value = availSuppression.Value - } - if availSuppression.FillPolicy != nil { - params.FillPolicy = availSuppression.FillPolicy - } - } - return params +func (m *putPlaybackConfigurationModelbuilder) getModel() playbackConfigurationModel { + + m.addAvailSuppressionToModel() + m.addBumperToModel() + m.addCdnConfigurationToModel() + m.addDashConfigurationToModel() + m.addOptionalFieldsToModel() + m.addLivePreRollConfigurationToModel() + m.addManifestProcessingRulesToModel() + m.addRequiredFieldsToModel() + + return *m.model } -func getBumperInput(bumper *bumperModel) *mediatailor.Bumper { - params := &mediatailor.Bumper{} - if bumper != nil { - if bumper.EndUrl != nil && *bumper.EndUrl != "" { - params.EndUrl = bumper.EndUrl - } - if bumper.StartUrl != nil && *bumper.StartUrl != "" { - params.StartUrl = bumper.StartUrl - } +func (m *putPlaybackConfigurationModelbuilder) addAvailSuppressionToModel() { + if m.output.AvailSuppression == nil { + return } - return params -} + if m.model.AvailSuppression == nil && m.isResource { + return + } + m.model.AvailSuppression = &availSuppressionModel{} -func getCdnConfigurationInput(cdnConfiguration *cdnConfigurationModel) *mediatailor.CdnConfiguration { - params := &mediatailor.CdnConfiguration{} - if cdnConfiguration != nil { - if cdnConfiguration.AdSegmentUrlPrefix != nil && *cdnConfiguration.AdSegmentUrlPrefix != "" { - params.AdSegmentUrlPrefix = cdnConfiguration.AdSegmentUrlPrefix - } - if cdnConfiguration.ContentSegmentUrlPrefix != nil && *cdnConfiguration.ContentSegmentUrlPrefix != "" { - params.ContentSegmentUrlPrefix = cdnConfiguration.ContentSegmentUrlPrefix - } + m.model.AvailSuppression.Mode = aws.String(string(m.output.AvailSuppression.Mode)) + m.model.AvailSuppression.FillPolicy = aws.String(string(m.output.AvailSuppression.FillPolicy)) + if m.output.AvailSuppression.Value != nil { + m.model.AvailSuppression.Value = m.output.AvailSuppression.Value } - return params } -func getDashConfigurationInput(dashConfiguration *dashConfigurationModel) *mediatailor.DashConfigurationForPut { - input := &mediatailor.DashConfigurationForPut{} - if dashConfiguration != nil { - if dashConfiguration.MpdLocation != nil { - input.MpdLocation = dashConfiguration.MpdLocation - } - if dashConfiguration.OriginManifestType != nil { - input.OriginManifestType = dashConfiguration.OriginManifestType - } +func (m *putPlaybackConfigurationModelbuilder) addBumperToModel() { + if m.output.Bumper == nil || (m.output.Bumper.EndUrl == nil || m.output.Bumper.StartUrl == nil) { + return + } + m.model.Bumper = &bumperModel{} + if m.output.Bumper.EndUrl != nil { + m.model.Bumper.EndUrl = m.output.Bumper.EndUrl + } + if m.output.Bumper.StartUrl != nil { + m.model.Bumper.StartUrl = m.output.Bumper.StartUrl } - return input } -func getLivePreRollConfigurationInput(livePreRollConfiguration *livePreRollConfigurationModel) *mediatailor.LivePreRollConfiguration { - input := &mediatailor.LivePreRollConfiguration{} - if livePreRollConfiguration != nil { - if livePreRollConfiguration.AdDecisionServerUrl != nil { - input.AdDecisionServerUrl = livePreRollConfiguration.AdDecisionServerUrl - } - if livePreRollConfiguration.MaxDurationSeconds != nil { - input.MaxDurationSeconds = livePreRollConfiguration.MaxDurationSeconds - } +func (m *putPlaybackConfigurationModelbuilder) addCdnConfigurationToModel() { + if m.output.CdnConfiguration == nil { + return + } + if m.model.CdnConfiguration == nil && m.isResource { + return + } + m.model.CdnConfiguration = &cdnConfigurationModel{} + if m.output.CdnConfiguration.AdSegmentUrlPrefix != nil { + m.model.CdnConfiguration.AdSegmentUrlPrefix = m.output.CdnConfiguration.AdSegmentUrlPrefix + } + if m.output.CdnConfiguration.ContentSegmentUrlPrefix != nil { + m.model.CdnConfiguration.ContentSegmentUrlPrefix = m.output.CdnConfiguration.ContentSegmentUrlPrefix } - return input } -func readPlaybackConfigToPlan(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) playbackConfigurationModel { - plan.PlaybackConfigurationArn = types.StringValue(*playbackConfiguration.PlaybackConfigurationArn) - plan.AdDecisionServerUrl = playbackConfiguration.AdDecisionServerUrl - // AVAIL SUPRESSION - if playbackConfiguration.AvailSuppression != nil { - plan = readAvailSuppression(plan, playbackConfiguration) +func (m *putPlaybackConfigurationModelbuilder) addDashConfigurationToModel() { + if m.output.DashConfiguration == nil { + return } - // BUMPER - if playbackConfiguration.Bumper != nil && (playbackConfiguration.Bumper.EndUrl != nil || playbackConfiguration.Bumper.StartUrl != nil) { - plan = readBumper(plan, playbackConfiguration) + if m.model.DashConfiguration == nil && m.isResource { + return } - // CDN CONFIGURATION - if playbackConfiguration.CdnConfiguration != nil { - plan = readCdnConfiguration(plan, playbackConfiguration) + m.model.DashConfiguration = &dashConfigurationModel{} + m.model.DashConfiguration.ManifestEndpointPrefix = types.StringValue(*m.output.DashConfiguration.MpdLocation) + if m.output.DashConfiguration.MpdLocation != nil { + m.model.DashConfiguration.MpdLocation = m.output.DashConfiguration.MpdLocation } - // CONFIGURATION ALIASES - if playbackConfiguration.ConfigurationAliases != nil { - plan.ConfigurationAliases = playbackConfiguration.ConfigurationAliases + m.model.DashConfiguration.OriginManifestType = aws.String(string(m.output.DashConfiguration.OriginManifestType)) +} + +func (m *putPlaybackConfigurationModelbuilder) addLivePreRollConfigurationToModel() { + if m.output.LivePreRollConfiguration == nil || (m.output.LivePreRollConfiguration.AdDecisionServerUrl == nil || m.output.LivePreRollConfiguration.MaxDurationSeconds == nil) { + return } - // DASH CONFIGURATION - if playbackConfiguration.DashConfiguration != nil { - plan = readDashConfiguration(plan, playbackConfiguration) + m.model.LivePreRollConfiguration = &livePreRollConfigurationModel{} + if m.output.LivePreRollConfiguration.AdDecisionServerUrl != nil { + m.model.LivePreRollConfiguration.AdDecisionServerUrl = m.output.LivePreRollConfiguration.AdDecisionServerUrl } - - // HLS CONFIGURATION - if playbackConfiguration.HlsConfiguration != nil && playbackConfiguration.HlsConfiguration.ManifestEndpointPrefix != nil { - plan.HlsConfigurationManifestEndpointPrefix = types.StringValue(*playbackConfiguration.HlsConfiguration.ManifestEndpointPrefix) + if m.output.LivePreRollConfiguration.MaxDurationSeconds != nil { + m.model.LivePreRollConfiguration.MaxDurationSeconds = m.output.LivePreRollConfiguration.MaxDurationSeconds } +} - // LOG CONFIGURATION - if playbackConfiguration.LogConfiguration != nil { - plan.LogConfigurationPercentEnabled = types.Int64Value(*playbackConfiguration.LogConfiguration.PercentEnabled) - } else { - plan.LogConfigurationPercentEnabled = types.Int64Value(0) +func (m *putPlaybackConfigurationModelbuilder) addManifestProcessingRulesToModel() { + if m.output.ManifestProcessingRules == nil || m.output.ManifestProcessingRules.AdMarkerPassthrough == nil { + return } - - // LIVE PRE ROLL CONFIGURATION - if playbackConfiguration.LivePreRollConfiguration != nil && (playbackConfiguration.LivePreRollConfiguration.AdDecisionServerUrl != nil || playbackConfiguration.LivePreRollConfiguration.MaxDurationSeconds != nil) { - plan = readLivePreRollConfiguration(plan, playbackConfiguration) + if m.model.ManifestProcessingRules == nil && m.isResource { + return } - - // MANIFEST PROCESSING RULES - if playbackConfiguration.ManifestProcessingRules != nil { - var mpr = playbackConfiguration.ManifestProcessingRules - if mpr.AdMarkerPassthrough != nil && mpr.AdMarkerPassthrough.Enabled != nil && *mpr.AdMarkerPassthrough.Enabled { - plan.ManifestProcessingRules = &manifestProcessingRulesModel{AdMarkerPassthrough: &adMarkerPassthroughModel{Enabled: mpr.AdMarkerPassthrough.Enabled}} - } + m.model.ManifestProcessingRules = &manifestProcessingRulesModel{ + AdMarkerPassthrough: &adMarkerPassthroughModel{ + Enabled: m.output.ManifestProcessingRules.AdMarkerPassthrough.Enabled, + }, } +} - plan.Name, plan.PersonalizationThresholdSeconds, plan.PlaybackEndpointPrefix, plan.SessionInitializationEndpointPrefix, plan.SlateAdUrl, plan.TranscodeProfileName, plan.VideoContentSourceUrl, plan.Tags = readPlaybackConfigurationTemps(plan, playbackConfiguration) - - plan.ID = types.StringValue(*playbackConfiguration.Name) - - return plan +func (m *putPlaybackConfigurationModelbuilder) addRequiredFieldsToModel() { + m.model.AdDecisionServerUrl = m.output.AdDecisionServerUrl + m.model.ID = types.StringValue(*m.output.Name) + m.model.Name = m.output.Name + m.model.PlaybackConfigurationArn = types.StringValue(*m.output.PlaybackConfigurationArn) + m.model.PlaybackEndpointPrefix = types.StringValue(*m.output.PlaybackEndpointPrefix) + m.model.SessionInitializationEndpointPrefix = types.StringValue(*m.output.SessionInitializationEndpointPrefix) } -func readPlaybackConfigurationTemps(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) (*string, *int64, types.String, types.String, *string, *string, *string, map[string]*string) { - plan.Name = playbackConfiguration.Name - // PERSONALIZATION THRESHOLD SECONDS - if playbackConfiguration.PersonalizationThresholdSeconds != nil { - plan.PersonalizationThresholdSeconds = playbackConfiguration.PersonalizationThresholdSeconds +func (m *putPlaybackConfigurationModelbuilder) addOptionalFieldsToModel() { + if m.output.ConfigurationAliases != nil { + m.model.ConfigurationAliases = m.output.ConfigurationAliases } - // PLAYBACK ENDPOINT PREFIX - plan.PlaybackEndpointPrefix = types.StringValue(*playbackConfiguration.PlaybackEndpointPrefix) - // SESSION INITIALIZATION ENDPOINT PREFIX - plan.SessionInitializationEndpointPrefix = types.StringValue(*playbackConfiguration.SessionInitializationEndpointPrefix) - // SLATE AD URL - if playbackConfiguration.SlateAdUrl != nil { - plan.SlateAdUrl = playbackConfiguration.SlateAdUrl - } - // TRANSCODE PROFILE NAME - if playbackConfiguration.TranscodeProfileName != nil { - plan.TranscodeProfileName = playbackConfiguration.TranscodeProfileName - } - // VIDEO CONTENT SOURCE URL - if playbackConfiguration.VideoContentSourceUrl != nil { - plan.VideoContentSourceUrl = playbackConfiguration.VideoContentSourceUrl + + if m.output.HlsConfiguration != nil && m.output.HlsConfiguration.ManifestEndpointPrefix != nil { + m.model.HlsConfigurationManifestEndpointPrefix = types.StringValue(*m.output.HlsConfiguration.ManifestEndpointPrefix) } - // TAGS - if len(playbackConfiguration.Tags) > 0 { - plan.Tags = playbackConfiguration.Tags + if m.output.LogConfiguration != nil { + m.model.LogConfigurationPercentEnabled = types.Int64Value(int64(m.output.LogConfiguration.PercentEnabled)) + } else { + m.model.LogConfigurationPercentEnabled = types.Int64Value(0) } - return plan.Name, plan.PersonalizationThresholdSeconds, plan.PlaybackEndpointPrefix, plan.SessionInitializationEndpointPrefix, plan.SlateAdUrl, plan.TranscodeProfileName, plan.VideoContentSourceUrl, plan.Tags -} -func readAvailSuppression(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) playbackConfigurationModel { - if playbackConfiguration.AvailSuppression != nil && *playbackConfiguration.AvailSuppression.Mode != "OFF" { - plan.AvailSupression = &availSupressionModel{} - if playbackConfiguration.AvailSuppression.Mode != nil { - plan.AvailSupression.Mode = playbackConfiguration.AvailSuppression.Mode - } - if playbackConfiguration.AvailSuppression.Value != nil { - plan.AvailSupression.Value = playbackConfiguration.AvailSuppression.Value - } - if playbackConfiguration.AvailSuppression.FillPolicy != nil { - plan.AvailSupression.FillPolicy = playbackConfiguration.AvailSuppression.FillPolicy - } + if m.output.PersonalizationThresholdSeconds != nil { + m.model.PersonalizationThresholdSeconds = m.output.PersonalizationThresholdSeconds } - return plan -} -func readBumper(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) playbackConfigurationModel { - if playbackConfiguration.Bumper != nil && (playbackConfiguration.Bumper.EndUrl != nil || playbackConfiguration.Bumper.StartUrl != nil) { - plan.Bumper = &bumperModel{} - if playbackConfiguration.Bumper.EndUrl != nil { - plan.Bumper.EndUrl = playbackConfiguration.Bumper.EndUrl - } - if playbackConfiguration.Bumper.StartUrl != nil { - plan.Bumper.StartUrl = playbackConfiguration.Bumper.StartUrl - } + if m.output.SlateAdUrl != nil { + m.model.SlateAdUrl = m.output.SlateAdUrl } - return plan -} -func readCdnConfiguration(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) playbackConfigurationModel { - if playbackConfiguration.CdnConfiguration != nil { - plan.CdnConfiguration = &cdnConfigurationModel{} - if playbackConfiguration.CdnConfiguration.AdSegmentUrlPrefix != nil { - plan.CdnConfiguration.AdSegmentUrlPrefix = playbackConfiguration.CdnConfiguration.AdSegmentUrlPrefix - } - if playbackConfiguration.CdnConfiguration.ContentSegmentUrlPrefix != nil { - plan.CdnConfiguration.ContentSegmentUrlPrefix = playbackConfiguration.CdnConfiguration.ContentSegmentUrlPrefix - } + if m.output.VideoContentSourceUrl != nil { + m.model.VideoContentSourceUrl = m.output.VideoContentSourceUrl } - return plan -} -func readDashConfiguration(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) playbackConfigurationModel { - if playbackConfiguration.DashConfiguration != nil { - plan.DashConfiguration = &dashConfigurationModel{} - plan.DashConfiguration.ManifestEndpointPrefix = types.StringValue(*playbackConfiguration.DashConfiguration.MpdLocation) - if playbackConfiguration.DashConfiguration.MpdLocation != nil { - plan.DashConfiguration.MpdLocation = playbackConfiguration.DashConfiguration.MpdLocation - } - if playbackConfiguration.DashConfiguration.OriginManifestType != nil { - plan.DashConfiguration.OriginManifestType = playbackConfiguration.DashConfiguration.OriginManifestType - } + if m.output.TranscodeProfileName != nil { + m.model.TranscodeProfileName = m.output.TranscodeProfileName } - return plan -} -func readLivePreRollConfiguration(plan playbackConfigurationModel, playbackConfiguration mediatailor.PutPlaybackConfigurationOutput) playbackConfigurationModel { - if playbackConfiguration.LivePreRollConfiguration != nil && (playbackConfiguration.LivePreRollConfiguration.AdDecisionServerUrl != nil || playbackConfiguration.LivePreRollConfiguration.MaxDurationSeconds != nil) { - plan.LivePreRollConfiguration = &livePreRollConfigurationModel{} - if playbackConfiguration.LivePreRollConfiguration.AdDecisionServerUrl != nil { - plan.LivePreRollConfiguration.AdDecisionServerUrl = playbackConfiguration.LivePreRollConfiguration.AdDecisionServerUrl - } - if playbackConfiguration.LivePreRollConfiguration.MaxDurationSeconds != nil { - plan.LivePreRollConfiguration.MaxDurationSeconds = playbackConfiguration.LivePreRollConfiguration.MaxDurationSeconds - } + if len(m.output.Tags) > 0 { + m.model.Tags = m.output.Tags } - return plan } diff --git a/awsmt/models_playback_configuration.go b/awsmt/models_playback_configuration.go index d13a062..261eafd 100644 --- a/awsmt/models_playback_configuration.go +++ b/awsmt/models_playback_configuration.go @@ -3,13 +3,13 @@ package awsmt import "github.com/hashicorp/terraform-plugin-framework/types" type playbackConfigurationModel struct { - ID types.String `tfsdk:"id"` - AdDecisionServerUrl *string `tfsdk:"ad_decision_server_url"` - AvailSupression *availSupressionModel `tfsdk:"avail_supression"` - Bumper *bumperModel `tfsdk:"bumper"` - CdnConfiguration *cdnConfigurationModel `tfsdk:"cdn_configuration"` - ConfigurationAliases map[string]map[string]*string `tfsdk:"configuration_aliases"` - DashConfiguration *dashConfigurationModel `tfsdk:"dash_configuration"` + ID types.String `tfsdk:"id"` + AdDecisionServerUrl *string `tfsdk:"ad_decision_server_url"` + AvailSuppression *availSuppressionModel `tfsdk:"avail_suppression"` + Bumper *bumperModel `tfsdk:"bumper"` + CdnConfiguration *cdnConfigurationModel `tfsdk:"cdn_configuration"` + ConfigurationAliases map[string]map[string]string `tfsdk:"configuration_aliases"` + DashConfiguration *dashConfigurationModel `tfsdk:"dash_configuration"` // @ADR // Context: The Provider Framework does not allow computed blocks // Decision: We decided to flatten the Log Configuration and the HLS Configuration blocks into the resource. @@ -19,17 +19,17 @@ type playbackConfigurationModel struct { LivePreRollConfiguration *livePreRollConfigurationModel `tfsdk:"live_pre_roll_configuration"` ManifestProcessingRules *manifestProcessingRulesModel `tfsdk:"manifest_processing_rules"` Name *string `tfsdk:"name"` - PersonalizationThresholdSeconds *int64 `tfsdk:"personalization_threshold_seconds"` + PersonalizationThresholdSeconds *int32 `tfsdk:"personalization_threshold_seconds"` PlaybackConfigurationArn types.String `tfsdk:"playback_configuration_arn"` PlaybackEndpointPrefix types.String `tfsdk:"playback_endpoint_prefix"` SessionInitializationEndpointPrefix types.String `tfsdk:"session_initialization_endpoint_prefix"` SlateAdUrl *string `tfsdk:"slate_ad_url"` - Tags map[string]*string `tfsdk:"tags"` + Tags map[string]string `tfsdk:"tags"` TranscodeProfileName *string `tfsdk:"transcode_profile_name"` VideoContentSourceUrl *string `tfsdk:"video_content_source_url"` } -type availSupressionModel struct { +type availSuppressionModel struct { FillPolicy *string `tfsdk:"fill_policy"` Mode *string `tfsdk:"mode"` Value *string `tfsdk:"value"` @@ -53,12 +53,12 @@ type dashConfigurationModel struct { type livePreRollConfigurationModel struct { AdDecisionServerUrl *string `tfsdk:"ad_decision_server_url"` - MaxDurationSeconds *int64 `tfsdk:"max_duration_seconds"` + MaxDurationSeconds *int32 `tfsdk:"max_duration_seconds"` } type manifestProcessingRulesModel struct { AdMarkerPassthrough *adMarkerPassthroughModel `tfsdk:"ad_marker_passthrough"` } type adMarkerPassthroughModel struct { - Enabled *bool `tfsdk:"enabled"` + Enabled bool `tfsdk:"enabled"` } diff --git a/awsmt/resource_playback_configuration.go b/awsmt/resource_playback_configuration.go index 8acc271..f11f990 100644 --- a/awsmt/resource_playback_configuration.go +++ b/awsmt/resource_playback_configuration.go @@ -2,12 +2,15 @@ package awsmt import ( "context" - "github.com/aws/aws-sdk-go/service/mediatailor" + "github.com/aws/aws-sdk-go-v2/service/mediatailor" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "reflect" ) var ( @@ -21,7 +24,7 @@ func ResourcePlaybackConfiguration() resource.Resource { } type resourcePlaybackConfiguration struct { - client *mediatailor.MediaTailor + client *mediatailor.Client } func (r *resourcePlaybackConfiguration) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { @@ -31,14 +34,24 @@ func (r *resourcePlaybackConfiguration) Metadata(_ context.Context, req resource func (r *resourcePlaybackConfiguration) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ - "id": computedString, + "id": computedStringWithStateForUnknown, "ad_decision_server_url": requiredString, - "avail_supression": schema.SingleNestedAttribute{ + "avail_suppression": schema.SingleNestedAttribute{ Optional: true, Attributes: map[string]schema.Attribute{ - "fill_policy": optionalString, - "mode": optionalString, - "value": optionalString, + "fill_policy": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("FULL_AVAIL_ONLY", "PARTIAL_AVAIL"), + }, + }, + "mode": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("OFF", "BEHIND_LIVE_EDGE", "AFTER_LIVE_EDGE"), + }, + }, + "value": optionalString, }, }, "bumper": schema.SingleNestedAttribute{ @@ -62,15 +75,25 @@ func (r *resourcePlaybackConfiguration) Schema(_ context.Context, _ resource.Sch }, }, "dash_configuration": schema.SingleNestedAttribute{ - Required: true, + Optional: true, Attributes: map[string]schema.Attribute{ - "manifest_endpoint_prefix": computedString, - "mpd_location": optionalString, - "origin_manifest_type": optionalString, + "manifest_endpoint_prefix": computedStringWithStateForUnknown, + "mpd_location": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("DISABLED", "EMT_DEFAULT"), + }, + }, + "origin_manifest_type": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("SINGLE_PERIOD", "MULTI_PERIOD"), + }, + }, }, }, - "hls_configuration_manifest_endpoint_prefix": computedString, - "log_configuration_percent_enabled": computedInt64, + "hls_configuration_manifest_endpoint_prefix": computedStringWithStateForUnknown, + "log_configuration_percent_enabled": computedInt64WithStateForUnknown, "live_pre_roll_configuration": schema.SingleNestedAttribute{ Optional: true, Attributes: map[string]schema.Attribute{ @@ -80,20 +103,26 @@ func (r *resourcePlaybackConfiguration) Schema(_ context.Context, _ resource.Sch }, "manifest_processing_rules": schema.SingleNestedAttribute{ Optional: true, + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.UseStateForUnknown(), + }, Attributes: map[string]schema.Attribute{ "ad_marker_passthrough": schema.SingleNestedAttribute{ Optional: true, Attributes: map[string]schema.Attribute{ - "enabled": optionalBool, + "enabled": schema.BoolAttribute{ + Optional: true, + Computed: true, + }, }, }, }, }, "name": requiredString, "personalization_threshold_seconds": optionalInt64, - "playback_configuration_arn": computedString, - "playback_endpoint_prefix": computedString, - "session_initialization_endpoint_prefix": computedString, + "playback_configuration_arn": computedStringWithStateForUnknown, + "playback_endpoint_prefix": computedStringWithStateForUnknown, + "session_initialization_endpoint_prefix": computedStringWithStateForUnknown, "slate_ad_url": optionalString, "tags": optionalMap, "transcode_profile_name": optionalString, @@ -107,21 +136,20 @@ func (r *resourcePlaybackConfiguration) Configure(_ context.Context, req resourc return } - r.client = req.ProviderData.(clients).v1 + r.client = req.ProviderData.(clients).v2 } func (r *resourcePlaybackConfiguration) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { var plan playbackConfigurationModel - diags := req.Plan.Get(ctx, &plan) - resp.Diagnostics.Append(diags...) + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) if resp.Diagnostics.HasError() { return } - input := playbackConfigurationInput(plan) + p := putPlaybackConfigurationInputBuilder{input: &mediatailor.PutPlaybackConfigurationInput{}, model: plan} - playbackConfiguration, err := r.client.PutPlaybackConfiguration(&input) + playbackConfiguration, err := r.client.PutPlaybackConfiguration(context.TODO(), p.getInput()) if err != nil { resp.Diagnostics.AddError( "Error while creating playback configuration "+err.Error(), @@ -130,10 +158,9 @@ func (r *resourcePlaybackConfiguration) Create(ctx context.Context, req resource return } - plan = readPlaybackConfigToPlan(plan, *playbackConfiguration) + m := putPlaybackConfigurationModelbuilder{model: &plan, output: *playbackConfiguration, isResource: true} - diags = resp.State.Set(ctx, plan) - resp.Diagnostics.Append(diags...) + resp.Diagnostics.Append(resp.State.Set(ctx, m.getModel())...) if resp.Diagnostics.HasError() { return } @@ -141,8 +168,8 @@ func (r *resourcePlaybackConfiguration) Create(ctx context.Context, req resource func (r *resourcePlaybackConfiguration) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var state playbackConfigurationModel - diags := req.State.Get(ctx, &state) - resp.Diagnostics.Append(diags...) + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) if resp.Diagnostics.HasError() { return } @@ -150,7 +177,7 @@ func (r *resourcePlaybackConfiguration) Read(ctx context.Context, req resource.R name := state.Name // Get the playback configuration - playbackConfiguration, err := r.client.GetPlaybackConfiguration(&mediatailor.GetPlaybackConfigurationInput{Name: name}) + playbackConfiguration, err := r.client.GetPlaybackConfiguration(context.TODO(), &mediatailor.GetPlaybackConfigurationInput{Name: name}) if err != nil { resp.Diagnostics.AddError( "Error while retrieving playback configuration "+err.Error(), @@ -159,11 +186,10 @@ func (r *resourcePlaybackConfiguration) Read(ctx context.Context, req resource.R return } - state = readPlaybackConfigToPlan(state, mediatailor.PutPlaybackConfigurationOutput(*playbackConfiguration)) + m := putPlaybackConfigurationModelbuilder{model: &state, output: mediatailor.PutPlaybackConfigurationOutput(*playbackConfiguration), isResource: true} // Set refreshed state - diags = resp.State.Set(ctx, &state) - resp.Diagnostics.Append(diags...) + resp.Diagnostics.Append(resp.State.Set(ctx, m.getModel())...) if resp.Diagnostics.HasError() { return } @@ -172,8 +198,7 @@ func (r *resourcePlaybackConfiguration) Read(ctx context.Context, req resource.R func (r *resourcePlaybackConfiguration) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { var plan playbackConfigurationModel - diags := req.Plan.Get(ctx, &plan) - resp.Diagnostics.Append(diags...) + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) if resp.Diagnostics.HasError() { return } @@ -182,7 +207,7 @@ func (r *resourcePlaybackConfiguration) Update(ctx context.Context, req resource name := plan.Name // Get the playback configuration - playbackConfiguration, err := r.client.GetPlaybackConfiguration(&mediatailor.GetPlaybackConfigurationInput{Name: name}) + playbackConfiguration, err := r.client.GetPlaybackConfiguration(context.TODO(), &mediatailor.GetPlaybackConfigurationInput{Name: name}) if err != nil { resp.Diagnostics.AddError( "Error while retrieving playback configuration "+err.Error(), @@ -197,24 +222,18 @@ func (r *resourcePlaybackConfiguration) Update(ctx context.Context, req resource // the PutPlaybackConfiguration method to add and update tags. We use this approach for every resource in the provider. // Consequences: The Update function logic is now more complicated, but tag removal is supported. - oldTags := playbackConfiguration.Tags - newTags := plan.Tags - - // Check if tags are different - if !reflect.DeepEqual(oldTags, newTags) { - err = untagResource(r.client, oldTags, *playbackConfiguration.PlaybackConfigurationArn) - if err != nil { - resp.Diagnostics.AddError( - "Error while untaging playback configuration tags"+err.Error(), - err.Error(), - ) - } + err = V2UpdatesTags(r.client, playbackConfiguration.Tags, plan.Tags, *playbackConfiguration.PlaybackConfigurationArn) + if err != nil { + resp.Diagnostics.AddError( + "Error while updating playback configuration tags"+err.Error(), + err.Error(), + ) } - input := playbackConfigurationInput(plan) + p := putPlaybackConfigurationInputBuilder{input: &mediatailor.PutPlaybackConfigurationInput{}, model: plan} // Update the playback configuration - playbackConfigurationUpdate, err := r.client.PutPlaybackConfiguration(&input) + playbackConfigurationUpdate, err := r.client.PutPlaybackConfiguration(context.TODO(), p.getInput()) if err != nil { resp.Diagnostics.AddError( "Error while updating playback configuration "+err.Error(), @@ -223,10 +242,9 @@ func (r *resourcePlaybackConfiguration) Update(ctx context.Context, req resource return } - plan = readPlaybackConfigToPlan(plan, *playbackConfigurationUpdate) + m := putPlaybackConfigurationModelbuilder{model: &plan, output: *playbackConfigurationUpdate, isResource: true} - diags = resp.State.Set(ctx, plan) - resp.Diagnostics.Append(diags...) + resp.Diagnostics.Append(resp.State.Set(ctx, m.getModel())...) if resp.Diagnostics.HasError() { return } @@ -234,13 +252,13 @@ func (r *resourcePlaybackConfiguration) Update(ctx context.Context, req resource func (r *resourcePlaybackConfiguration) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { var state playbackConfigurationModel - diags := req.State.Get(ctx, &state) - resp.Diagnostics.Append(diags...) + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) if resp.Diagnostics.HasError() { return } name := state.Name - _, err := r.client.DeletePlaybackConfiguration(&mediatailor.DeletePlaybackConfigurationInput{Name: name}) + _, err := r.client.DeletePlaybackConfiguration(context.TODO(), &mediatailor.DeletePlaybackConfigurationInput{Name: name}) if err != nil { resp.Diagnostics.AddError( "Error while deleting playback configuration "+err.Error(), diff --git a/awsmt/resource_playback_configuration_test.go b/awsmt/resource_playback_configuration_test.go index 20a82ba..21e4f24 100644 --- a/awsmt/resource_playback_configuration_test.go +++ b/awsmt/resource_playback_configuration_test.go @@ -3,23 +3,99 @@ package awsmt import ( "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "regexp" "testing" ) +func TestAccPlaybackConfigurationMinimal(t *testing.T) { + resourceName := "awsmt_playback_configuration.r2" + name := "test-acc-playback-configuration-minimal" + adUrl := "https://www.foo.de/" + videoSourceUrl := "https://www.bar.at" + adUrl2 := "https://www.biz.ch" + videoSourceUrl2 := "https://www.buzz.com" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: minimalPlaybackConfiguration(name, adUrl, videoSourceUrl), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "id", name), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "ad_decision_server_url", adUrl), + resource.TestCheckResourceAttr(resourceName, "video_content_source_url", videoSourceUrl), + ), + }, + { + Config: minimalPlaybackConfiguration(name, adUrl2, videoSourceUrl2), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "id", name), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "ad_decision_server_url", adUrl2), + resource.TestCheckResourceAttr(resourceName, "video_content_source_url", videoSourceUrl2), + ), + }, + }, + }) +} + +func TestAccPlaybackConfigurationCreationFail(t *testing.T) { + name := "test-acc-playback-configuration-delete" + adUrl := "invalid" + videoSourceUrl := "https://www.bar.at" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: minimalPlaybackConfiguration(name, adUrl, videoSourceUrl), + ExpectError: regexp.MustCompile(`.*AdDecisionServerUrl requires a valid URL.*`), + }, + }, + }) +} + +func TestAccPlaybackConfigurationUpdateFail(t *testing.T) { + resourceName := "awsmt_playback_configuration.r2" + name := "test-acc-playback-configuration-delete" + adUrl := "https://www.buzz.com" + adUrl2 := "invalid" + videoSourceUrl := "https://www.bar.at" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: minimalPlaybackConfiguration(name, adUrl, videoSourceUrl), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "id", name), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "ad_decision_server_url", adUrl), + ), + }, + { + Config: minimalPlaybackConfiguration(name, adUrl2, videoSourceUrl), + ExpectError: regexp.MustCompile(`.*AdDecisionServerUrl requires a valid URL.*`), + }, + }, + }) +} + func TestAccPlaybackConfigurationResource(t *testing.T) { name := "example-playback-configuration-awsmt" - ad_url := "https://exampleurl.com/" - ad_url2 := "https://exampleurl2.com/" - bumper_e := "https://wxample.com/endbumper" - bumper_e2 := "https://wxample.com/endbumper2" - bumper_s := "https://wxample.com/startbumper" - bumper_s2 := "https://wxample.com/startbumper2" - cdn_url := "https://exampleurl.com/" - cdn_url2 := "https://exampleurl2.com/" - max_d := "2" - max_d2 := "3" - p_s := "2" - p_s2 := "3" + adUrl := "https://exampleurl.com/" + adUrl2 := "https://exampleurl2.com/" + bumperE := "https://wxample.com/endbumper" + bumperE2 := "https://wxample.com/endbumper2" + bumperS := "https://wxample.com/startbumper" + bumperS2 := "https://wxample.com/startbumper2" + cdnUrl := "https://exampleurl.com/" + cdnUrl2 := "https://exampleurl2.com/" + maxD := "2" + maxD2 := "3" + pS := "2" + pS2 := "3" k1 := "Environment" v1 := "dev" k2 := "Testing" @@ -32,23 +108,23 @@ func TestAccPlaybackConfigurationResource(t *testing.T) { Steps: []resource.TestStep{ // Create and Read testing { - Config: basicPlaybackConfiguration(name, ad_url, bumper_e, bumper_s, cdn_url, max_d, p_s, k1, v1, k2, v2), + Config: completePlaybackConfiguration(name, adUrl, bumperE, bumperS, cdnUrl, maxD, pS, k1, v1, k2, v2), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "id", "example-playback-configuration-awsmt"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "ad_decision_server_url", "https://exampleurl.com/"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "avail_supression.fill_policy", "FULL_AVAIL_ONLY"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "avail_supression.mode", "BEHIND_LIVE_EDGE"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "avail_supression.value", "00:00:00"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "bumper.end_url", "https://wxample.com/endbumper"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "bumper.start_url", "https://wxample.com/startbumper"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "cdn_configuration.ad_segment_url_prefix", "https://exampleurl.com/"), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "id", name), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "ad_decision_server_url", adUrl), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "avail_suppression.fill_policy", "FULL_AVAIL_ONLY"), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "avail_suppression.mode", "BEHIND_LIVE_EDGE"), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "avail_suppression.value", "00:00:00"), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "bumper.end_url", bumperE), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "bumper.start_url", bumperS), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "cdn_configuration.ad_segment_url_prefix", cdnUrl), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "dash_configuration.mpd_location", "DISABLED"), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "dash_configuration.origin_manifest_type", "SINGLE_PERIOD"), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "live_pre_roll_configuration.ad_decision_server_url", "https://exampleurl.com/"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "live_pre_roll_configuration.max_duration_seconds", "2"), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "live_pre_roll_configuration.max_duration_seconds", maxD), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "manifest_processing_rules.ad_marker_passthrough.enabled", "false"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "name", "example-playback-configuration-awsmt"), - resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "personalization_threshold_seconds", "2"), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "name", name), + resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "personalization_threshold_seconds", pS), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "slate_ad_url", "https://exampleurl.com/"), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "tags.Environment", "dev"), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "tags.Testing", "pass"), @@ -62,7 +138,7 @@ func TestAccPlaybackConfigurationResource(t *testing.T) { }, // Update and Read testing { - Config: basicPlaybackConfiguration(name, ad_url2, bumper_e2, bumper_s2, cdn_url2, max_d2, p_s2, k3, v3, k2, v2), + Config: completePlaybackConfiguration(name, adUrl2, bumperE2, bumperS2, cdnUrl2, maxD2, pS2, k3, v3, k2, v2), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "name", "example-playback-configuration-awsmt"), resource.TestCheckResourceAttr("awsmt_playback_configuration.r1", "personalization_threshold_seconds", "3"), @@ -80,51 +156,55 @@ func TestAccPlaybackConfigurationResource(t *testing.T) { }) } -func basicPlaybackConfiguration(name, ad_url, bumper_e, bumper_s, cdn_url, max_d, p_s, k1, v1, k2, v2 string) string { - return fmt.Sprintf(`resource "awsmt_playback_configuration" "r1" { - ad_decision_server_url = "%[2]s" - avail_supression = { - fill_policy = "FULL_AVAIL_ONLY" - mode = "BEHIND_LIVE_EDGE" - value = "00:00:00" - } - bumper = { - end_url = "%[3]s" - start_url = "%[4]s" - } - cdn_configuration = { - ad_segment_url_prefix = "%[5]s" - } - dash_configuration = { - mpd_location = "DISABLED", - origin_manifest_type = "SINGLE_PERIOD" - } - live_pre_roll_configuration = { - ad_decision_server_url = "%[2]s" - max_duration_seconds = "%[6]s" - } - manifest_processing_rules = { - ad_marker_passthrough = { - enabled = "false" - } - } - name = "%[1]s" - personalization_threshold_seconds = "%[7]s" - slate_ad_url = "https://exampleurl.com/" - tags = { - "%[8]s": "%[9]s", - "%[10]s": "%[11]s" - } - video_content_source_url = "%[2]s" - } - - data "awsmt_playback_configuration" "test"{ - name = awsmt_playback_configuration.r1.name - } - - output "playback_configuration_out" { - value = data.awsmt_playback_configuration.test - } - `, name, ad_url, bumper_e, bumper_s, cdn_url, max_d, p_s, k1, v1, k2, v2) +func minimalPlaybackConfiguration(name, adUrl, videoSourceUrl string) string { + return fmt.Sprintf(` + resource "awsmt_playback_configuration" "r2" { + ad_decision_server_url = "%[2]s" + name = "%[1]s" + video_content_source_url = "%[3]s" + } + `, name, adUrl, videoSourceUrl, + ) +} +func completePlaybackConfiguration(name, adUrl, bumperE, bumperS, cdnUrl, maxD, pS, k1, v1, k2, v2 string) string { + return fmt.Sprintf(` + resource "awsmt_playback_configuration" "r1" { + ad_decision_server_url = "%[2]s" + avail_suppression = { + fill_policy = "FULL_AVAIL_ONLY" + mode = "BEHIND_LIVE_EDGE" + value = "00:00:00" + } + bumper = { + end_url = "%[3]s" + start_url = "%[4]s" + } + cdn_configuration = { + ad_segment_url_prefix = "%[5]s" + } + dash_configuration = { + mpd_location = "DISABLED", + origin_manifest_type = "SINGLE_PERIOD" + } + live_pre_roll_configuration = { + ad_decision_server_url = "%[2]s" + max_duration_seconds = "%[6]s" + } + manifest_processing_rules = { + ad_marker_passthrough = { + enabled = "false" + } + } + name = "%[1]s" + personalization_threshold_seconds = "%[7]s" + slate_ad_url = "https://exampleurl.com/" + tags = { + "%[8]s": "%[9]s", + "%[10]s": "%[11]s" + } + video_content_source_url = "%[2]s" + } + `, name, adUrl, bumperE, bumperS, cdnUrl, maxD, pS, k1, v1, k2, v2, + ) } diff --git a/awsmt/schemas.go b/awsmt/schemas.go index 2d4088b..d45040e 100644 --- a/awsmt/schemas.go +++ b/awsmt/schemas.go @@ -23,6 +23,13 @@ var computedInt64 = schema.Int64Attribute{ Computed: true, } +var computedInt64WithStateForUnknown = schema.Int64Attribute{ + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, +} + var computedMap = schema.MapAttribute{ Computed: true, ElementType: types.StringType, @@ -70,10 +77,6 @@ var optionalUnknownList = schema.ListAttribute{ }, } -var optionalBool = schema.BoolAttribute{ - Optional: true, -} - var computedStringWithStateForUnknown = schema.StringAttribute{ Computed: true, PlanModifiers: []planmodifier.String{ diff --git a/examples/playback_configuration.tf b/examples/playback_configuration.tf index 0ac9634..839d50e 100644 --- a/examples/playback_configuration.tf +++ b/examples/playback_configuration.tf @@ -1,13 +1,14 @@ resource "awsmt_playback_configuration" "r1" { ad_decision_server_url = "https://exampleurl.com/" - avail_supression = { - mode = "OFF" + avail_suppression = { + mode = "AFTER_LIVE_EDGE" + fill_policy = "FULL_AVAIL_ONLY" } cdn_configuration = { ad_segment_url_prefix = "https://exampleurl.com/" } dash_configuration = { - mpd_location = "DISABLED", + mpd_location = "DISABLED", origin_manifest_type = "SINGLE_PERIOD" } manifest_processing_rules = { @@ -15,13 +16,13 @@ resource "awsmt_playback_configuration" "r1" { enabled = "false" } } - name = "example-playback-configuration-awsmt" + name = "example-playback-configuration-awsmt" personalization_threshold_seconds = 2 - tags = {"Environment": "dev"} - video_content_source_url = "https://exampleurl.com/" + tags = { "Environment" : "dev" } + video_content_source_url = "https://exampleurl.com/" } -data "awsmt_playback_configuration" "test"{ +data "awsmt_playback_configuration" "test" { name = awsmt_playback_configuration.r1.name } diff --git a/examples/source_location.tf b/examples/source_location.tf index 2dea725..dabf36c 100644 --- a/examples/source_location.tf +++ b/examples/source_location.tf @@ -1,10 +1,10 @@ resource "awsmt_source_location" "example" { name = "examplesourcelocation" http_configuration = { - hc_base_url = "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com" + base_url = "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com" } default_segment_delivery_configuration = { - dsdc_base_url = "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com/test-img.jpeg" + base_url = "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com/test-img.jpeg" } }