diff --git a/.changelog/10932.txt b/.changelog/10932.txt new file mode 100644 index 00000000000..4157e11c820 --- /dev/null +++ b/.changelog/10932.txt @@ -0,0 +1,6 @@ +```release-note:new-resource +`google_transcoder_job` +``` +```release-note:new-resource +`google_transcoder_job_template` +``` \ No newline at end of file diff --git a/.teamcity/components/inputs/services_beta.kt b/.teamcity/components/inputs/services_beta.kt index 5835aa5bf54..9e603729ef7 100644 --- a/.teamcity/components/inputs/services_beta.kt +++ b/.teamcity/components/inputs/services_beta.kt @@ -730,6 +730,11 @@ var ServicesListBeta = mapOf( "name" to "tpuv2", "displayName" to "Tpuv2", "path" to "./google-beta/services/tpuv2" + ), + "transcoder" to mapOf( + "name" to "transcoder", + "displayName" to "Transcoder", + "path" to "./google-beta/services/transcoder" ), "vertexai" to mapOf( "name" to "vertexai", diff --git a/.teamcity/components/inputs/services_ga.kt b/.teamcity/components/inputs/services_ga.kt index 80a77899b4d..fd82f4c01ba 100644 --- a/.teamcity/components/inputs/services_ga.kt +++ b/.teamcity/components/inputs/services_ga.kt @@ -726,6 +726,11 @@ var ServicesListGa = mapOf( "displayName" to "Tpuv2", "path" to "./google/services/tpuv2" ), + "transcoder" to mapOf( + "name" to "transcoder", + "displayName" to "Transcoder", + "path" to "./google/services/transcoder" + ), "vertexai" to mapOf( "name" to "vertexai", "displayName" to "Vertexai", diff --git a/google/fwmodels/provider_model.go b/google/fwmodels/provider_model.go index 78914a1f0b6..5bc29182cb5 100644 --- a/google/fwmodels/provider_model.go +++ b/google/fwmodels/provider_model.go @@ -145,6 +145,7 @@ type ProviderModel struct { StorageTransferCustomEndpoint types.String `tfsdk:"storage_transfer_custom_endpoint"` TagsCustomEndpoint types.String `tfsdk:"tags_custom_endpoint"` TPUCustomEndpoint types.String `tfsdk:"tpu_custom_endpoint"` + TranscoderCustomEndpoint types.String `tfsdk:"transcoder_custom_endpoint"` VertexAICustomEndpoint types.String `tfsdk:"vertex_ai_custom_endpoint"` VmwareengineCustomEndpoint types.String `tfsdk:"vmwareengine_custom_endpoint"` VPCAccessCustomEndpoint types.String `tfsdk:"vpc_access_custom_endpoint"` diff --git a/google/fwprovider/framework_provider.go b/google/fwprovider/framework_provider.go index a34a738cd6c..2dfd2b62d55 100644 --- a/google/fwprovider/framework_provider.go +++ b/google/fwprovider/framework_provider.go @@ -847,6 +847,12 @@ func (p *FrameworkProvider) Schema(_ context.Context, _ provider.SchemaRequest, transport_tpg.CustomEndpointValidator(), }, }, + "transcoder_custom_endpoint": &schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + transport_tpg.CustomEndpointValidator(), + }, + }, "vertex_ai_custom_endpoint": &schema.StringAttribute{ Optional: true, Validators: []validator.String{ diff --git a/google/fwtransport/framework_config.go b/google/fwtransport/framework_config.go index c862b33d3fd..7fdc29d45d7 100644 --- a/google/fwtransport/framework_config.go +++ b/google/fwtransport/framework_config.go @@ -180,6 +180,7 @@ type FrameworkProviderConfig struct { StorageTransferBasePath string TagsBasePath string TPUBasePath string + TranscoderBasePath string VertexAIBasePath string VmwareengineBasePath string VPCAccessBasePath string @@ -341,6 +342,7 @@ func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context, p.StorageTransferBasePath = data.StorageTransferCustomEndpoint.ValueString() p.TagsBasePath = data.TagsCustomEndpoint.ValueString() p.TPUBasePath = data.TPUCustomEndpoint.ValueString() + p.TranscoderBasePath = data.TranscoderCustomEndpoint.ValueString() p.VertexAIBasePath = data.VertexAICustomEndpoint.ValueString() p.VmwareengineBasePath = data.VmwareengineCustomEndpoint.ValueString() p.VPCAccessBasePath = data.VPCAccessCustomEndpoint.ValueString() @@ -1421,6 +1423,14 @@ func (p *FrameworkProviderConfig) HandleDefaults(ctx context.Context, data *fwmo data.TPUCustomEndpoint = types.StringValue(customEndpoint.(string)) } } + if data.TranscoderCustomEndpoint.IsNull() { + customEndpoint := transport_tpg.MultiEnvDefault([]string{ + "GOOGLE_TRANSCODER_CUSTOM_ENDPOINT", + }, transport_tpg.DefaultBasePaths[transport_tpg.TranscoderBasePathKey]) + if customEndpoint != nil { + data.TranscoderCustomEndpoint = types.StringValue(customEndpoint.(string)) + } + } if data.VertexAICustomEndpoint.IsNull() { customEndpoint := transport_tpg.MultiEnvDefault([]string{ "GOOGLE_VERTEX_AI_CUSTOM_ENDPOINT", diff --git a/google/provider/provider.go b/google/provider/provider.go index 4e8e94b433c..9d361ed473e 100644 --- a/google/provider/provider.go +++ b/google/provider/provider.go @@ -730,6 +730,11 @@ func Provider() *schema.Provider { Optional: true, ValidateFunc: transport_tpg.ValidateCustomEndpoint, }, + "transcoder_custom_endpoint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: transport_tpg.ValidateCustomEndpoint, + }, "vertex_ai_custom_endpoint": { Type: schema.TypeString, Optional: true, @@ -1063,6 +1068,7 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr config.StorageTransferBasePath = d.Get("storage_transfer_custom_endpoint").(string) config.TagsBasePath = d.Get("tags_custom_endpoint").(string) config.TPUBasePath = d.Get("tpu_custom_endpoint").(string) + config.TranscoderBasePath = d.Get("transcoder_custom_endpoint").(string) config.VertexAIBasePath = d.Get("vertex_ai_custom_endpoint").(string) config.VmwareengineBasePath = d.Get("vmwareengine_custom_endpoint").(string) config.VPCAccessBasePath = d.Get("vpc_access_custom_endpoint").(string) diff --git a/google/provider/provider_mmv1_resources.go b/google/provider/provider_mmv1_resources.go index 8eea5fc321d..b07f586fa5f 100644 --- a/google/provider/provider_mmv1_resources.go +++ b/google/provider/provider_mmv1_resources.go @@ -119,6 +119,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/services/storagetransfer" "github.com/hashicorp/terraform-provider-google/google/services/tags" "github.com/hashicorp/terraform-provider-google/google/services/tpu" + "github.com/hashicorp/terraform-provider-google/google/services/transcoder" "github.com/hashicorp/terraform-provider-google/google/services/vertexai" "github.com/hashicorp/terraform-provider-google/google/services/vmwareengine" "github.com/hashicorp/terraform-provider-google/google/services/vpcaccess" @@ -439,9 +440,9 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{ } // Resources -// Generated resources: 471 +// Generated resources: 473 // Generated IAM resources: 261 -// Total generated resources: 732 +// Total generated resources: 734 var generatedResources = map[string]*schema.Resource{ "google_folder_access_approval_settings": accessapproval.ResourceAccessApprovalFolderSettings(), "google_organization_access_approval_settings": accessapproval.ResourceAccessApprovalOrganizationSettings(), @@ -1129,6 +1130,8 @@ var generatedResources = map[string]*schema.Resource{ "google_tags_tag_value_iam_member": tpgiamresource.ResourceIamMember(tags.TagsTagValueIamSchema, tags.TagsTagValueIamUpdaterProducer, tags.TagsTagValueIdParseFunc), "google_tags_tag_value_iam_policy": tpgiamresource.ResourceIamPolicy(tags.TagsTagValueIamSchema, tags.TagsTagValueIamUpdaterProducer, tags.TagsTagValueIdParseFunc), "google_tpu_node": tpu.ResourceTPUNode(), + "google_transcoder_job": transcoder.ResourceTranscoderJob(), + "google_transcoder_job_template": transcoder.ResourceTranscoderJobTemplate(), "google_vertex_ai_dataset": vertexai.ResourceVertexAIDataset(), "google_vertex_ai_deployment_resource_pool": vertexai.ResourceVertexAIDeploymentResourcePool(), "google_vertex_ai_endpoint": vertexai.ResourceVertexAIEndpoint(), diff --git a/google/services/transcoder/resource_transcoder_job.go b/google/services/transcoder/resource_transcoder_job.go new file mode 100644 index 00000000000..9fe9319568a --- /dev/null +++ b/google/services/transcoder/resource_transcoder_job.go @@ -0,0 +1,2976 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package transcoder + +import ( + "fmt" + "log" + "net/http" + "reflect" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func ResourceTranscoderJob() *schema.Resource { + return &schema.Resource{ + Create: resourceTranscoderJobCreate, + Read: resourceTranscoderJobRead, + Update: resourceTranscoderJobUpdate, + Delete: resourceTranscoderJobDelete, + + Importer: &schema.ResourceImporter{ + State: resourceTranscoderJobImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the transcoding job resource.`, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The configuration for this template.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ad_breaks": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Ad break.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Start time in seconds for the ad break, relative to the output file timeline`, + }, + }, + }, + }, + "edit_list": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of input assets stored in Cloud Storage.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "inputs": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of values identifying files that should be used in this atom.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this atom.`, + }, + "start_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Start time in seconds for the atom, relative to the input file timeline. The default is '0s'.`, + }, + }, + }, + }, + "elementary_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of input assets stored in Cloud Storage.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "audio_stream": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Encoding of an audio stream.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bitrate_bps": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: `Audio bitrate in bits per second.`, + }, + "channel_count": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Number of audio channels. The default is '2'.`, + }, + "channel_layout": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A list of channel names specifying layout of the audio channels. The default is ["fl", "fr"].`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "codec": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The codec for this audio stream. The default is 'aac'.`, + }, + "sample_rate_hertz": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The audio sample rate in Hertz. The default is '48000'.`, + }, + }, + }, + }, + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this atom.`, + }, + "video_stream": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Encoding of a video stream.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "h264": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `H264 codec settings`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bitrate_bps": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: `The video bitrate in bits per second.`, + }, + "frame_rate": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: `The target video frame rate in frames per second (FPS).`, + }, + "crf_level": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Target CRF level. The default is '21'.`, + }, + "entropy_coder": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The entropy coder to use. The default is 'cabac'.`, + }, + "gop_duration": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Select the GOP size based on the specified duration. The default is '3s'.`, + }, + "height_pixels": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The height of the video in pixels.`, + }, + "hlg": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `HLG color format setting for H264.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "pixel_format": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Pixel format to use. The default is 'yuv420p'.`, + }, + "preset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Enforces the specified codec preset. The default is 'veryfast'.`, + }, + "profile": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Enforces the specified codec profile.`, + }, + "rate_control_mode": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Specify the mode. The default is 'vbr'.`, + }, + "sdr": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `SDR color format setting for H264.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "vbv_fullness_bits": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Initial fullness of the Video Buffering Verifier (VBV) buffer in bits.`, + }, + "vbv_size_bits": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Size of the Video Buffering Verifier (VBV) buffer in bits.`, + }, + "width_pixels": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The width of the video in pixels.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "encryptions": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of encryption configurations for the content.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Identifier for this set of encryption options.`, + }, + "aes128": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Configuration for AES-128 encryption.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "drm_systems": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `DRM system(s) to use; at least one must be specified. If a DRM system is omitted, it is considered disabled.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "clearkey": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Clearkey configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "fairplay": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Fairplay configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "playready": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Playready configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "widevine": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Widevine configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + }, + }, + }, + "mpeg_cenc": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Configuration for MPEG Common Encryption (MPEG-CENC).`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "scheme": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Specify the encryption scheme.`, + }, + }, + }, + }, + "sample_aes": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Configuration for SAMPLE-AES encryption.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "secret_manager_key_source": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Configuration for secrets stored in Google Secret Manager.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "secret_version": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the Secret Version containing the encryption key in the following format: projects/{project}/secrets/{secret_id}/versions/{version_number}.`, + }, + }, + }, + }, + }, + }, + }, + "inputs": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of input assets stored in Cloud Storage.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this input. Must be specified when using advanced mapping and edit lists.`, + }, + "uri": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `URI of the media. Input files must be at least 5 seconds in duration and stored in Cloud Storage (for example, gs://bucket/inputs/file.mp4). +If empty, the value is populated from Job.input_uri.`, + }, + }, + }, + }, + "manifests": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Manifest configuration.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + ValidateFunc: verify.ValidateEnum([]string{"MANIFEST_TYPE_UNSPECIFIED", "HLS", "DASH"}), + Description: `Type of the manifest. Possible values: ["MANIFEST_TYPE_UNSPECIFIED", "HLS", "DASH"]`, + }, + "file_name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The name of the generated file. The default is 'manifest'.`, + }, + "mux_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of user supplied MuxStream.key values that should appear in this manifest.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "mux_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Multiplexing settings for output stream.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "container": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The container format. The default is 'mp4'.`, + }, + "elementary_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of ElementaryStream.key values multiplexed in this stream.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "encryption_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Identifier of the encryption configuration to use.`, + }, + "file_name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The name of the generated file.`, + }, + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this multiplexed stream.`, + }, + "segment_settings": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Segment settings for ts, fmp4 and vtt.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "segment_duration": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Duration of the segments in seconds. The default is '6.0s'.`, + }, + }, + }, + }, + }, + }, + }, + "output": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Location of output file(s) in a Cloud Storage bucket.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `URI for the output file(s). For example, gs://my-bucket/outputs/.`, + }, + }, + }, + }, + "overlays": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of overlays on the output video, in descending Z-order.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "animations": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of animations. The list should be chronological, without any time overlap.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "animation_fade": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Display overlay object with fade animation.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "fade_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidateEnum([]string{"FADE_TYPE_UNSPECIFIED", "FADE_IN", "FADE_OUT"}), + Description: `Required. Type of fade animation: 'FADE_IN' or 'FADE_OUT'. +The possible values are: + +* 'FADE_TYPE_UNSPECIFIED': The fade type is not specified. + +* 'FADE_IN': Fade the overlay object into view. + +* 'FADE_OUT': Fade the overlay object out of view. Possible values: ["FADE_TYPE_UNSPECIFIED", "FADE_IN", "FADE_OUT"]`, + }, + "end_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The time to end the fade animation, in seconds.`, + }, + "start_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The time to start the fade animation, in seconds.`, + }, + "xy": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Normalized coordinates based on output video resolution.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "x": { + Type: schema.TypeFloat, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Normalized x coordinate.`, + }, + "y": { + Type: schema.TypeFloat, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Normalized y coordinate.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "image": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Image overlay.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `URI of the image in Cloud Storage. For example, gs://bucket/inputs/image.png.`, + }, + }, + }, + }, + }, + }, + }, + "pubsub_destination": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Pub/Sub destination.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topic": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The name of the Pub/Sub topic to publish job completion notification to. For example: projects/{project}/topics/{topic}.`, + }, + }, + }, + }, + }, + }, + }, + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The labels associated with this job. You can use these to organize and group your jobs. + + +**Note**: This field is non-authoritative, and will only manage the labels present in your configuration. +Please refer to the field 'effective_labels' for all of the labels present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "template_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Specify the templateId to use for populating Job.config. +The default is preset/web-hd, which is the only supported preset.`, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the job was created.`, + }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "end_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the transcoding finished.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The resource name of the job.`, + }, + "start_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the transcoding started.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The current state of the job.`, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceTranscoderJobCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + templateIdProp, err := expandTranscoderJobTemplateId(d.Get("template_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("template_id"); !tpgresource.IsEmptyValue(reflect.ValueOf(templateIdProp)) && (ok || !reflect.DeepEqual(v, templateIdProp)) { + obj["templateId"] = templateIdProp + } + configProp, err := expandTranscoderJobConfig(d.Get("config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("config"); !tpgresource.IsEmptyValue(reflect.ValueOf(configProp)) && (ok || !reflect.DeepEqual(v, configProp)) { + obj["config"] = configProp + } + labelsProp, err := expandTranscoderJobEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{TranscoderBasePath}}projects/{{project}}/locations/{{location}}/jobs") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Job: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Job: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + Headers: headers, + }) + if err != nil { + return fmt.Errorf("Error creating Job: %s", err) + } + if err := d.Set("name", flattenTranscoderJobName(res["name"], d, config)); err != nil { + return fmt.Errorf(`Error setting computed identity field "name": %s`, err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Job %q: %#v", d.Id(), res) + + return resourceTranscoderJobRead(d, meta) +} + +func resourceTranscoderJobRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{TranscoderBasePath}}{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Job: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Headers: headers, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("TranscoderJob %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + + if err := d.Set("name", flattenTranscoderJobName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("create_time", flattenTranscoderJobCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("start_time", flattenTranscoderJobStartTime(res["startTime"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("end_time", flattenTranscoderJobEndTime(res["endTime"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("state", flattenTranscoderJobState(res["state"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("labels", flattenTranscoderJobLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("config", flattenTranscoderJobConfig(res["config"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("terraform_labels", flattenTranscoderJobTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("effective_labels", flattenTranscoderJobEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + + return nil +} + +func resourceTranscoderJobUpdate(d *schema.ResourceData, meta interface{}) error { + // Only the root field "labels" and "terraform_labels" are mutable + return resourceTranscoderJobRead(d, meta) +} + +func resourceTranscoderJobDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Job: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{TranscoderBasePath}}{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + + log.Printf("[DEBUG] Deleting Job %q", d.Id()) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + Headers: headers, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "Job") + } + + log.Printf("[DEBUG] Finished deleting Job %q: %#v", d.Id(), res) + return nil +} + +func resourceTranscoderJobImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + + config := meta.(*transport_tpg.Config) + + // current import_formats can't import fields with forward slashes in their value + if err := tpgresource.ParseImportId([]string{"(?P[^ ]+) (?P[^ ]+)", "(?P[^ ]+)"}, d, config); err != nil { + return nil, err + } + + return []*schema.ResourceData{d}, nil +} + +func flattenTranscoderJobName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobStartTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobEndTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("labels"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenTranscoderJobConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["inputs"] = + flattenTranscoderJobConfigInputs(original["inputs"], d, config) + transformed["edit_list"] = + flattenTranscoderJobConfigEditList(original["editList"], d, config) + transformed["elementary_streams"] = + flattenTranscoderJobConfigElementaryStreams(original["elementaryStreams"], d, config) + transformed["mux_streams"] = + flattenTranscoderJobConfigMuxStreams(original["muxStreams"], d, config) + transformed["manifests"] = + flattenTranscoderJobConfigManifests(original["manifests"], d, config) + transformed["output"] = + flattenTranscoderJobConfigOutput(original["output"], d, config) + transformed["ad_breaks"] = + flattenTranscoderJobConfigAdBreaks(original["adBreaks"], d, config) + transformed["pubsub_destination"] = + flattenTranscoderJobConfigPubsubDestination(original["pubsubDestination"], d, config) + transformed["overlays"] = + flattenTranscoderJobConfigOverlays(original["overlays"], d, config) + transformed["encryptions"] = + flattenTranscoderJobConfigEncryptions(original["encryptions"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigInputs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobConfigInputsKey(original["key"], d, config), + "uri": flattenTranscoderJobConfigInputsUri(original["uri"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigInputsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigInputsUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigEditList(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobConfigEditListKey(original["key"], d, config), + "inputs": flattenTranscoderJobConfigEditListInputs(original["inputs"], d, config), + "start_time_offset": flattenTranscoderJobConfigEditListStartTimeOffset(original["startTimeOffset"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigEditListKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigEditListInputs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigEditListStartTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobConfigElementaryStreamsKey(original["key"], d, config), + "video_stream": flattenTranscoderJobConfigElementaryStreamsVideoStream(original["videoStream"], d, config), + "audio_stream": flattenTranscoderJobConfigElementaryStreamsAudioStream(original["audioStream"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigElementaryStreamsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStream(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["h264"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264(original["h264"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["width_pixels"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264WidthPixels(original["widthPixels"], d, config) + transformed["height_pixels"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264HeightPixels(original["heightPixels"], d, config) + transformed["frame_rate"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264FrameRate(original["frameRate"], d, config) + transformed["bitrate_bps"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264BitrateBps(original["bitrateBps"], d, config) + transformed["pixel_format"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264PixelFormat(original["pixelFormat"], d, config) + transformed["rate_control_mode"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264RateControlMode(original["rateControlMode"], d, config) + transformed["crf_level"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264CrfLevel(original["crfLevel"], d, config) + transformed["vbv_size_bits"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264VbvSizeBits(original["vbvSizeBits"], d, config) + transformed["vbv_fullness_bits"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264VbvFullnessBits(original["vbvFullnessBits"], d, config) + transformed["entropy_coder"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264EntropyCoder(original["entropyCoder"], d, config) + transformed["profile"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Profile(original["profile"], d, config) + transformed["preset"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Preset(original["preset"], d, config) + transformed["gop_duration"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264GopDuration(original["gopDuration"], d, config) + transformed["sdr"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Sdr(original["sdr"], d, config) + transformed["hlg"] = + flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Hlg(original["hlg"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264WidthPixels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264HeightPixels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264FrameRate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264BitrateBps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264PixelFormat(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264RateControlMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264CrfLevel(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264VbvSizeBits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264VbvFullnessBits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264EntropyCoder(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Profile(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Preset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264GopDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Sdr(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigElementaryStreamsVideoStreamH264Hlg(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigElementaryStreamsAudioStream(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["codec"] = + flattenTranscoderJobConfigElementaryStreamsAudioStreamCodec(original["codec"], d, config) + transformed["bitrate_bps"] = + flattenTranscoderJobConfigElementaryStreamsAudioStreamBitrateBps(original["bitrateBps"], d, config) + transformed["channel_count"] = + flattenTranscoderJobConfigElementaryStreamsAudioStreamChannelCount(original["channelCount"], d, config) + transformed["channel_layout"] = + flattenTranscoderJobConfigElementaryStreamsAudioStreamChannelLayout(original["channelLayout"], d, config) + transformed["sample_rate_hertz"] = + flattenTranscoderJobConfigElementaryStreamsAudioStreamSampleRateHertz(original["sampleRateHertz"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigElementaryStreamsAudioStreamCodec(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsAudioStreamBitrateBps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsAudioStreamChannelCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigElementaryStreamsAudioStreamChannelLayout(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigElementaryStreamsAudioStreamSampleRateHertz(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobConfigMuxStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobConfigMuxStreamsKey(original["key"], d, config), + "file_name": flattenTranscoderJobConfigMuxStreamsFileName(original["fileName"], d, config), + "container": flattenTranscoderJobConfigMuxStreamsContainer(original["container"], d, config), + "elementary_streams": flattenTranscoderJobConfigMuxStreamsElementaryStreams(original["elementaryStreams"], d, config), + "segment_settings": flattenTranscoderJobConfigMuxStreamsSegmentSettings(original["segmentSettings"], d, config), + "encryption_id": flattenTranscoderJobConfigMuxStreamsEncryptionId(original["encryptionId"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigMuxStreamsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigMuxStreamsFileName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigMuxStreamsContainer(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigMuxStreamsElementaryStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigMuxStreamsSegmentSettings(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["segment_duration"] = + flattenTranscoderJobConfigMuxStreamsSegmentSettingsSegmentDuration(original["segmentDuration"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigMuxStreamsSegmentSettingsSegmentDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigMuxStreamsEncryptionId(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigManifests(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "file_name": flattenTranscoderJobConfigManifestsFileName(original["fileName"], d, config), + "type": flattenTranscoderJobConfigManifestsType(original["type"], d, config), + "mux_streams": flattenTranscoderJobConfigManifestsMuxStreams(original["muxStreams"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigManifestsFileName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigManifestsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigManifestsMuxStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOutput(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["uri"] = + flattenTranscoderJobConfigOutputUri(original["uri"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigOutputUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigAdBreaks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "start_time_offset": flattenTranscoderJobConfigAdBreaksStartTimeOffset(original["startTimeOffset"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigAdBreaksStartTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigPubsubDestination(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["topic"] = + flattenTranscoderJobConfigPubsubDestinationTopic(original["topic"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigPubsubDestinationTopic(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOverlays(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "image": flattenTranscoderJobConfigOverlaysImage(original["image"], d, config), + "animations": flattenTranscoderJobConfigOverlaysAnimations(original["animations"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigOverlaysImage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["uri"] = + flattenTranscoderJobConfigOverlaysImageUri(original["uri"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigOverlaysImageUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOverlaysAnimations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "animation_fade": flattenTranscoderJobConfigOverlaysAnimationsAnimationFade(original["animationFade"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFade(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["xy"] = + flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeXy(original["xy"], d, config) + transformed["start_time_offset"] = + flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeStartTimeOffset(original["startTimeOffset"], d, config) + transformed["end_time_offset"] = + flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeEndTimeOffset(original["endTimeOffset"], d, config) + transformed["fade_type"] = + flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeFadeType(original["fadeType"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeXy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["x"] = + flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeXyX(original["x"], d, config) + transformed["y"] = + flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeXyY(original["y"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeXyX(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeXyY(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeStartTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeEndTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigOverlaysAnimationsAnimationFadeFadeType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigEncryptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "id": flattenTranscoderJobConfigEncryptionsId(original["id"], d, config), + "drm_systems": flattenTranscoderJobConfigEncryptionsDrmSystems(original["drmSystems"], d, config), + "aes128": flattenTranscoderJobConfigEncryptionsAes128(original["aes128"], d, config), + "sample_aes": flattenTranscoderJobConfigEncryptionsSampleAes(original["sampleAes"], d, config), + "mpeg_cenc": flattenTranscoderJobConfigEncryptionsMpegCenc(original["mpegCenc"], d, config), + "secret_manager_key_source": flattenTranscoderJobConfigEncryptionsSecretManagerKeySource(original["secretManagerKeySource"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobConfigEncryptionsId(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigEncryptionsDrmSystems(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["widevine"] = + flattenTranscoderJobConfigEncryptionsDrmSystemsWidevine(original["widevine"], d, config) + transformed["fairplay"] = + flattenTranscoderJobConfigEncryptionsDrmSystemsFairplay(original["fairplay"], d, config) + transformed["playready"] = + flattenTranscoderJobConfigEncryptionsDrmSystemsPlayready(original["playready"], d, config) + transformed["clearkey"] = + flattenTranscoderJobConfigEncryptionsDrmSystemsClearkey(original["clearkey"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigEncryptionsDrmSystemsWidevine(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigEncryptionsDrmSystemsFairplay(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigEncryptionsDrmSystemsPlayready(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigEncryptionsDrmSystemsClearkey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigEncryptionsAes128(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigEncryptionsSampleAes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobConfigEncryptionsMpegCenc(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["scheme"] = + flattenTranscoderJobConfigEncryptionsMpegCencScheme(original["scheme"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigEncryptionsMpegCencScheme(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobConfigEncryptionsSecretManagerKeySource(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["secret_version"] = + flattenTranscoderJobConfigEncryptionsSecretManagerKeySourceSecretVersion(original["secretVersion"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobConfigEncryptionsSecretManagerKeySourceSecretVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("terraform_labels"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenTranscoderJobEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandTranscoderJobTemplateId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedInputs, err := expandTranscoderJobConfigInputs(original["inputs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedInputs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["inputs"] = transformedInputs + } + + transformedEditList, err := expandTranscoderJobConfigEditList(original["edit_list"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEditList); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["editList"] = transformedEditList + } + + transformedElementaryStreams, err := expandTranscoderJobConfigElementaryStreams(original["elementary_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedElementaryStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["elementaryStreams"] = transformedElementaryStreams + } + + transformedMuxStreams, err := expandTranscoderJobConfigMuxStreams(original["mux_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMuxStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["muxStreams"] = transformedMuxStreams + } + + transformedManifests, err := expandTranscoderJobConfigManifests(original["manifests"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManifests); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manifests"] = transformedManifests + } + + transformedOutput, err := expandTranscoderJobConfigOutput(original["output"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOutput); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["output"] = transformedOutput + } + + transformedAdBreaks, err := expandTranscoderJobConfigAdBreaks(original["ad_breaks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdBreaks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["adBreaks"] = transformedAdBreaks + } + + transformedPubsubDestination, err := expandTranscoderJobConfigPubsubDestination(original["pubsub_destination"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPubsubDestination); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pubsubDestination"] = transformedPubsubDestination + } + + transformedOverlays, err := expandTranscoderJobConfigOverlays(original["overlays"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOverlays); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["overlays"] = transformedOverlays + } + + transformedEncryptions, err := expandTranscoderJobConfigEncryptions(original["encryptions"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEncryptions); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["encryptions"] = transformedEncryptions + } + + return transformed, nil +} + +func expandTranscoderJobConfigInputs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobConfigInputsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedUri, err := expandTranscoderJobConfigInputsUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigInputsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigInputsUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigEditList(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobConfigEditListKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedInputs, err := expandTranscoderJobConfigEditListInputs(original["inputs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedInputs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["inputs"] = transformedInputs + } + + transformedStartTimeOffset, err := expandTranscoderJobConfigEditListStartTimeOffset(original["start_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStartTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["startTimeOffset"] = transformedStartTimeOffset + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigEditListKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigEditListInputs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigEditListStartTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobConfigElementaryStreamsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedVideoStream, err := expandTranscoderJobConfigElementaryStreamsVideoStream(original["video_stream"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVideoStream); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["videoStream"] = transformedVideoStream + } + + transformedAudioStream, err := expandTranscoderJobConfigElementaryStreamsAudioStream(original["audio_stream"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAudioStream); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["audioStream"] = transformedAudioStream + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigElementaryStreamsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStream(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedH264, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264(original["h264"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedH264); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["h264"] = transformedH264 + } + + return transformed, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedWidthPixels, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264WidthPixels(original["width_pixels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedWidthPixels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["widthPixels"] = transformedWidthPixels + } + + transformedHeightPixels, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264HeightPixels(original["height_pixels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHeightPixels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["heightPixels"] = transformedHeightPixels + } + + transformedFrameRate, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264FrameRate(original["frame_rate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFrameRate); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["frameRate"] = transformedFrameRate + } + + transformedBitrateBps, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264BitrateBps(original["bitrate_bps"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBitrateBps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bitrateBps"] = transformedBitrateBps + } + + transformedPixelFormat, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264PixelFormat(original["pixel_format"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPixelFormat); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pixelFormat"] = transformedPixelFormat + } + + transformedRateControlMode, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264RateControlMode(original["rate_control_mode"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRateControlMode); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["rateControlMode"] = transformedRateControlMode + } + + transformedCrfLevel, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264CrfLevel(original["crf_level"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCrfLevel); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["crfLevel"] = transformedCrfLevel + } + + transformedVbvSizeBits, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264VbvSizeBits(original["vbv_size_bits"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVbvSizeBits); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vbvSizeBits"] = transformedVbvSizeBits + } + + transformedVbvFullnessBits, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264VbvFullnessBits(original["vbv_fullness_bits"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVbvFullnessBits); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vbvFullnessBits"] = transformedVbvFullnessBits + } + + transformedEntropyCoder, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264EntropyCoder(original["entropy_coder"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEntropyCoder); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["entropyCoder"] = transformedEntropyCoder + } + + transformedProfile, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264Profile(original["profile"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedProfile); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["profile"] = transformedProfile + } + + transformedPreset, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264Preset(original["preset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPreset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["preset"] = transformedPreset + } + + transformedGopDuration, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264GopDuration(original["gop_duration"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedGopDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["gopDuration"] = transformedGopDuration + } + + transformedSdr, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264Sdr(original["sdr"], d, config) + if err != nil { + return nil, err + } else { + transformed["sdr"] = transformedSdr + } + + transformedHlg, err := expandTranscoderJobConfigElementaryStreamsVideoStreamH264Hlg(original["hlg"], d, config) + if err != nil { + return nil, err + } else { + transformed["hlg"] = transformedHlg + } + + return transformed, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264WidthPixels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264HeightPixels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264FrameRate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264BitrateBps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264PixelFormat(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264RateControlMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264CrfLevel(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264VbvSizeBits(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264VbvFullnessBits(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264EntropyCoder(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264Profile(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264Preset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264GopDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264Sdr(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigElementaryStreamsVideoStreamH264Hlg(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigElementaryStreamsAudioStream(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedCodec, err := expandTranscoderJobConfigElementaryStreamsAudioStreamCodec(original["codec"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCodec); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["codec"] = transformedCodec + } + + transformedBitrateBps, err := expandTranscoderJobConfigElementaryStreamsAudioStreamBitrateBps(original["bitrate_bps"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBitrateBps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bitrateBps"] = transformedBitrateBps + } + + transformedChannelCount, err := expandTranscoderJobConfigElementaryStreamsAudioStreamChannelCount(original["channel_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedChannelCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["channelCount"] = transformedChannelCount + } + + transformedChannelLayout, err := expandTranscoderJobConfigElementaryStreamsAudioStreamChannelLayout(original["channel_layout"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedChannelLayout); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["channelLayout"] = transformedChannelLayout + } + + transformedSampleRateHertz, err := expandTranscoderJobConfigElementaryStreamsAudioStreamSampleRateHertz(original["sample_rate_hertz"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSampleRateHertz); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["sampleRateHertz"] = transformedSampleRateHertz + } + + return transformed, nil +} + +func expandTranscoderJobConfigElementaryStreamsAudioStreamCodec(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsAudioStreamBitrateBps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsAudioStreamChannelCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsAudioStreamChannelLayout(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigElementaryStreamsAudioStreamSampleRateHertz(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigMuxStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobConfigMuxStreamsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedFileName, err := expandTranscoderJobConfigMuxStreamsFileName(original["file_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFileName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["fileName"] = transformedFileName + } + + transformedContainer, err := expandTranscoderJobConfigMuxStreamsContainer(original["container"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedContainer); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["container"] = transformedContainer + } + + transformedElementaryStreams, err := expandTranscoderJobConfigMuxStreamsElementaryStreams(original["elementary_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedElementaryStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["elementaryStreams"] = transformedElementaryStreams + } + + transformedSegmentSettings, err := expandTranscoderJobConfigMuxStreamsSegmentSettings(original["segment_settings"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSegmentSettings); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["segmentSettings"] = transformedSegmentSettings + } + + transformedEncryptionId, err := expandTranscoderJobConfigMuxStreamsEncryptionId(original["encryption_id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEncryptionId); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["encryptionId"] = transformedEncryptionId + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigMuxStreamsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigMuxStreamsFileName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigMuxStreamsContainer(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigMuxStreamsElementaryStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigMuxStreamsSegmentSettings(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSegmentDuration, err := expandTranscoderJobConfigMuxStreamsSegmentSettingsSegmentDuration(original["segment_duration"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSegmentDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["segmentDuration"] = transformedSegmentDuration + } + + return transformed, nil +} + +func expandTranscoderJobConfigMuxStreamsSegmentSettingsSegmentDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigMuxStreamsEncryptionId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigManifests(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedFileName, err := expandTranscoderJobConfigManifestsFileName(original["file_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFileName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["fileName"] = transformedFileName + } + + transformedType, err := expandTranscoderJobConfigManifestsType(original["type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedType); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["type"] = transformedType + } + + transformedMuxStreams, err := expandTranscoderJobConfigManifestsMuxStreams(original["mux_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMuxStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["muxStreams"] = transformedMuxStreams + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigManifestsFileName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigManifestsType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigManifestsMuxStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOutput(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedUri, err := expandTranscoderJobConfigOutputUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + return transformed, nil +} + +func expandTranscoderJobConfigOutputUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigAdBreaks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedStartTimeOffset, err := expandTranscoderJobConfigAdBreaksStartTimeOffset(original["start_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStartTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["startTimeOffset"] = transformedStartTimeOffset + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigAdBreaksStartTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigPubsubDestination(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedTopic, err := expandTranscoderJobConfigPubsubDestinationTopic(original["topic"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTopic); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["topic"] = transformedTopic + } + + return transformed, nil +} + +func expandTranscoderJobConfigPubsubDestinationTopic(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOverlays(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedImage, err := expandTranscoderJobConfigOverlaysImage(original["image"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedImage); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["image"] = transformedImage + } + + transformedAnimations, err := expandTranscoderJobConfigOverlaysAnimations(original["animations"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAnimations); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["animations"] = transformedAnimations + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigOverlaysImage(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedUri, err := expandTranscoderJobConfigOverlaysImageUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + return transformed, nil +} + +func expandTranscoderJobConfigOverlaysImageUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOverlaysAnimations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedAnimationFade, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFade(original["animation_fade"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAnimationFade); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["animationFade"] = transformedAnimationFade + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFade(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedXy, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFadeXy(original["xy"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedXy); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["xy"] = transformedXy + } + + transformedStartTimeOffset, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFadeStartTimeOffset(original["start_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStartTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["startTimeOffset"] = transformedStartTimeOffset + } + + transformedEndTimeOffset, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFadeEndTimeOffset(original["end_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEndTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["endTimeOffset"] = transformedEndTimeOffset + } + + transformedFadeType, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFadeFadeType(original["fade_type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFadeType); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["fadeType"] = transformedFadeType + } + + return transformed, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFadeXy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedX, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFadeXyX(original["x"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedX); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["x"] = transformedX + } + + transformedY, err := expandTranscoderJobConfigOverlaysAnimationsAnimationFadeXyY(original["y"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedY); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["y"] = transformedY + } + + return transformed, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFadeXyX(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFadeXyY(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFadeStartTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFadeEndTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigOverlaysAnimationsAnimationFadeFadeType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigEncryptions(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedId, err := expandTranscoderJobConfigEncryptionsId(original["id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedId); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["id"] = transformedId + } + + transformedDrmSystems, err := expandTranscoderJobConfigEncryptionsDrmSystems(original["drm_systems"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDrmSystems); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["drmSystems"] = transformedDrmSystems + } + + transformedAes128, err := expandTranscoderJobConfigEncryptionsAes128(original["aes128"], d, config) + if err != nil { + return nil, err + } else { + transformed["aes128"] = transformedAes128 + } + + transformedSampleAes, err := expandTranscoderJobConfigEncryptionsSampleAes(original["sample_aes"], d, config) + if err != nil { + return nil, err + } else { + transformed["sampleAes"] = transformedSampleAes + } + + transformedMpegCenc, err := expandTranscoderJobConfigEncryptionsMpegCenc(original["mpeg_cenc"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMpegCenc); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["mpegCenc"] = transformedMpegCenc + } + + transformedSecretManagerKeySource, err := expandTranscoderJobConfigEncryptionsSecretManagerKeySource(original["secret_manager_key_source"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSecretManagerKeySource); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["secretManagerKeySource"] = transformedSecretManagerKeySource + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobConfigEncryptionsId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigEncryptionsDrmSystems(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedWidevine, err := expandTranscoderJobConfigEncryptionsDrmSystemsWidevine(original["widevine"], d, config) + if err != nil { + return nil, err + } else { + transformed["widevine"] = transformedWidevine + } + + transformedFairplay, err := expandTranscoderJobConfigEncryptionsDrmSystemsFairplay(original["fairplay"], d, config) + if err != nil { + return nil, err + } else { + transformed["fairplay"] = transformedFairplay + } + + transformedPlayready, err := expandTranscoderJobConfigEncryptionsDrmSystemsPlayready(original["playready"], d, config) + if err != nil { + return nil, err + } else { + transformed["playready"] = transformedPlayready + } + + transformedClearkey, err := expandTranscoderJobConfigEncryptionsDrmSystemsClearkey(original["clearkey"], d, config) + if err != nil { + return nil, err + } else { + transformed["clearkey"] = transformedClearkey + } + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsDrmSystemsWidevine(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsDrmSystemsFairplay(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsDrmSystemsPlayready(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsDrmSystemsClearkey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsAes128(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsSampleAes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsMpegCenc(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedScheme, err := expandTranscoderJobConfigEncryptionsMpegCencScheme(original["scheme"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedScheme); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["scheme"] = transformedScheme + } + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsMpegCencScheme(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobConfigEncryptionsSecretManagerKeySource(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSecretVersion, err := expandTranscoderJobConfigEncryptionsSecretManagerKeySourceSecretVersion(original["secret_version"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSecretVersion); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["secretVersion"] = transformedSecretVersion + } + + return transformed, nil +} + +func expandTranscoderJobConfigEncryptionsSecretManagerKeySourceSecretVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/transcoder/resource_transcoder_job_generated_test.go b/google/services/transcoder/resource_transcoder_job_generated_test.go new file mode 100644 index 00000000000..db9f313747e --- /dev/null +++ b/google/services/transcoder/resource_transcoder_job_generated_test.go @@ -0,0 +1,688 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package transcoder_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccTranscoderJob_transcoderJobBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJob_transcoderJobBasicExample(context), + }, + { + ResourceName: "google_transcoder_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"end_time", "labels", "location", "state", "template_id", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJob_transcoderJobBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_storage_bucket" "default" { + name = "tf-test-transcoder-job%{random_suffix}" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_transcoder_job" "default" { + template_id = google_transcoder_job_template.default.name + location = "us-central1" + + labels = { + "label" = "key" + } +} + +resource "google_transcoder_job_template" "default" { + job_template_id = "tf-test-example-job-template%{random_suffix}" + location = "us-central1" + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func TestAccTranscoderJob_transcoderJobPubsubExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJob_transcoderJobPubsubExample(context), + }, + { + ResourceName: "google_transcoder_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"end_time", "labels", "location", "state", "template_id", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJob_transcoderJobPubsubExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_storage_bucket" "default" { + name = "tf-test-transcoder-job%{random_suffix}" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_pubsub_topic" "transcoder_notifications" { + name = "tf-test-transcoder-notifications%{random_suffix}" +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + pubsub_destination { + topic = google_pubsub_topic.transcoder_notifications.id + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func TestAccTranscoderJob_transcoderJobOverlaysExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJob_transcoderJobOverlaysExample(context), + }, + { + ResourceName: "google_transcoder_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"end_time", "labels", "location", "state", "template_id", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJob_transcoderJobOverlaysExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_storage_bucket" "default" { + name = "tf-test-transcoder-job%{random_suffix}" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_storage_bucket_object" "overlay_png" { + name = "overlay.png" + source = "./test-fixtures/overlay.png" + bucket = google_storage_bucket.default.name +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + overlays { + animations { + animation_fade { + fade_type = "FADE_IN" + start_time_offset = "1.500s" + end_time_offset = "3.500s" + xy { + x = 1 + y = 0.5 + } + } + } + image { + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.overlay_png.name}" + } + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func TestAccTranscoderJob_transcoderJobManifestsExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJob_transcoderJobManifestsExample(context), + }, + { + ResourceName: "google_transcoder_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"end_time", "labels", "location", "state", "template_id", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJob_transcoderJobManifestsExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_storage_bucket" "default" { + name = "tf-test-transcoder-job%{random_suffix}" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + + edit_list { + key = "atom0" + start_time_offset = "0s" + inputs = ["input0"] + } + + ad_breaks { + start_time_offset = "3.500s" + } + + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + + mux_streams { + key = "media-sd" + file_name = "media-sd.ts" + container = "ts" + elementary_streams = ["video-stream0", "audio-stream0"] + } + + mux_streams { + key = "media-hd" + file_name = "media-hd.ts" + container = "ts" + elementary_streams = ["video-stream1", "audio-stream0"] + } + + mux_streams { + key = "video-only-sd" + file_name = "video-only-sd.m4s" + container = "fmp4" + elementary_streams = ["video-stream0"] + } + + mux_streams { + key = "video-only-hd" + file_name = "video-only-hd.m4s" + container = "fmp4" + elementary_streams = ["video-stream1"] + } + + mux_streams { + key = "audio-only" + file_name = "audio-only.m4s" + container = "fmp4" + elementary_streams = ["audio-stream0"] + } + + manifests { + file_name = "manifest.m3u8" + type = "HLS" + mux_streams = ["media-sd", "media-hd"] + } + + manifests { + file_name = "manifest.mpd" + type = "DASH" + mux_streams = ["video-only-sd", "video-only-hd", "audio-only"] + } + + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func testAccCheckTranscoderJobDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_transcoder_job" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{TranscoderBasePath}}{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("TranscoderJob still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/services/transcoder/resource_transcoder_job_sweeper.go b/google/services/transcoder/resource_transcoder_job_sweeper.go new file mode 100644 index 00000000000..63567478ec9 --- /dev/null +++ b/google/services/transcoder/resource_transcoder_job_sweeper.go @@ -0,0 +1,139 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package transcoder + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("TranscoderJob", testSweepTranscoderJob) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepTranscoderJob(region string) error { + resourceName := "TranscoderJob" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://transcoder.googleapis.com/v1/projects/{{project}}/locations/{{location}}/jobs", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["jobs"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + if obj["name"] == nil { + log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) + return nil + } + + name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://transcoder.googleapis.com/v1/{{name}}" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/google/services/transcoder/resource_transcoder_job_template.go b/google/services/transcoder/resource_transcoder_job_template.go new file mode 100644 index 00000000000..68c25d28b05 --- /dev/null +++ b/google/services/transcoder/resource_transcoder_job_template.go @@ -0,0 +1,2927 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package transcoder + +import ( + "fmt" + "log" + "net/http" + "reflect" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func ResourceTranscoderJobTemplate() *schema.Resource { + return &schema.Resource{ + Create: resourceTranscoderJobTemplateCreate, + Read: resourceTranscoderJobTemplateRead, + Update: resourceTranscoderJobTemplateUpdate, + Delete: resourceTranscoderJobTemplateDelete, + + Importer: &schema.ResourceImporter{ + State: resourceTranscoderJobTemplateImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "job_template_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `ID to use for the Transcoding job template.`, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the transcoding job template resource.`, + }, + "config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The configuration for this template.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ad_breaks": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Ad break.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Start time in seconds for the ad break, relative to the output file timeline`, + }, + }, + }, + }, + "edit_list": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of input assets stored in Cloud Storage.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "inputs": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of values identifying files that should be used in this atom.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this atom.`, + }, + "start_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Start time in seconds for the atom, relative to the input file timeline. The default is '0s'.`, + }, + }, + }, + }, + "elementary_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of input assets stored in Cloud Storage.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "audio_stream": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Encoding of an audio stream.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bitrate_bps": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: `Audio bitrate in bits per second.`, + }, + "channel_count": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Number of audio channels. The default is '2'.`, + }, + "channel_layout": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A list of channel names specifying layout of the audio channels. The default is ["fl", "fr"].`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "codec": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The codec for this audio stream. The default is 'aac'.`, + }, + "sample_rate_hertz": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The audio sample rate in Hertz. The default is '48000'.`, + }, + }, + }, + }, + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this atom.`, + }, + "video_stream": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Encoding of a video stream.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "h264": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `H264 codec settings`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bitrate_bps": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: `The video bitrate in bits per second.`, + }, + "frame_rate": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: `The target video frame rate in frames per second (FPS).`, + }, + "crf_level": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Target CRF level. The default is '21'.`, + }, + "entropy_coder": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The entropy coder to use. The default is 'cabac'.`, + }, + "gop_duration": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Select the GOP size based on the specified duration. The default is '3s'.`, + }, + "height_pixels": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The height of the video in pixels.`, + }, + "hlg": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `HLG color format setting for H264.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "pixel_format": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Pixel format to use. The default is 'yuv420p'.`, + }, + "preset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Enforces the specified codec preset. The default is 'veryfast'.`, + }, + "profile": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Enforces the specified codec profile.`, + }, + "rate_control_mode": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Specify the mode. The default is 'vbr'.`, + }, + "sdr": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `SDR color format setting for H264.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "vbv_fullness_bits": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Initial fullness of the Video Buffering Verifier (VBV) buffer in bits.`, + }, + "vbv_size_bits": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Size of the Video Buffering Verifier (VBV) buffer in bits.`, + }, + "width_pixels": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The width of the video in pixels.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "encryptions": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of encryption configurations for the content.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Identifier for this set of encryption options.`, + }, + "aes128": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Configuration for AES-128 encryption.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "drm_systems": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `DRM system(s) to use; at least one must be specified. If a DRM system is omitted, it is considered disabled.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "clearkey": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Clearkey configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "fairplay": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Fairplay configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "playready": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Playready configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "widevine": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Widevine configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + }, + }, + }, + "mpeg_cenc": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Configuration for MPEG Common Encryption (MPEG-CENC).`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "scheme": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Specify the encryption scheme.`, + }, + }, + }, + }, + "sample_aes": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Configuration for SAMPLE-AES encryption.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{}, + }, + }, + "secret_manager_key_source": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Configuration for secrets stored in Google Secret Manager.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "secret_version": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the Secret Version containing the encryption key in the following format: projects/{project}/secrets/{secret_id}/versions/{version_number}.`, + }, + }, + }, + }, + }, + }, + }, + "inputs": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of input assets stored in Cloud Storage.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this input. Must be specified when using advanced mapping and edit lists.`, + }, + "uri": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `URI of the media. Input files must be at least 5 seconds in duration and stored in Cloud Storage (for example, gs://bucket/inputs/file.mp4). +If empty, the value is populated from Job.input_uri.`, + }, + }, + }, + }, + "manifests": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Manifest configuration.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + ValidateFunc: verify.ValidateEnum([]string{"MANIFEST_TYPE_UNSPECIFIED", "HLS", "DASH"}), + Description: `Type of the manifest. Possible values: ["MANIFEST_TYPE_UNSPECIFIED", "HLS", "DASH"]`, + }, + "file_name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The name of the generated file. The default is 'manifest'.`, + }, + "mux_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of user supplied MuxStream.key values that should appear in this manifest.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "mux_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Multiplexing settings for output stream.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "container": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The container format. The default is 'mp4'.`, + }, + "elementary_streams": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of ElementaryStream.key values multiplexed in this stream.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "encryption_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Identifier of the encryption configuration to use.`, + }, + "file_name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The name of the generated file.`, + }, + "key": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `A unique key for this multiplexed stream.`, + }, + "segment_settings": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Segment settings for ts, fmp4 and vtt.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "segment_duration": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Duration of the segments in seconds. The default is '6.0s'.`, + }, + }, + }, + }, + }, + }, + }, + "output": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Location of output file(s) in a Cloud Storage bucket.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `URI for the output file(s). For example, gs://my-bucket/outputs/.`, + }, + }, + }, + }, + "overlays": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of overlays on the output video, in descending Z-order.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "animations": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `List of animations. The list should be chronological, without any time overlap.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "animation_fade": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Display overlay object with fade animation.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "fade_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidateEnum([]string{"FADE_TYPE_UNSPECIFIED", "FADE_IN", "FADE_OUT"}), + Description: `Required. Type of fade animation: 'FADE_IN' or 'FADE_OUT'. +The possible values are: + +* 'FADE_TYPE_UNSPECIFIED': The fade type is not specified. + +* 'FADE_IN': Fade the overlay object into view. + +* 'FADE_OUT': Fade the overlay object out of view. Possible values: ["FADE_TYPE_UNSPECIFIED", "FADE_IN", "FADE_OUT"]`, + }, + "end_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The time to end the fade animation, in seconds.`, + }, + "start_time_offset": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The time to start the fade animation, in seconds.`, + }, + "xy": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Normalized coordinates based on output video resolution.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "x": { + Type: schema.TypeFloat, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Normalized x coordinate.`, + }, + "y": { + Type: schema.TypeFloat, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Normalized y coordinate.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "image": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Image overlay.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `URI of the image in Cloud Storage. For example, gs://bucket/inputs/image.png.`, + }, + }, + }, + }, + }, + }, + }, + "pubsub_destination": { + Type: schema.TypeList, + Computed: true, + Optional: true, + ForceNew: true, + Description: `Pub/Sub destination.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "topic": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The name of the Pub/Sub topic to publish job completion notification to. For example: projects/{project}/topics/{topic}.`, + }, + }, + }, + }, + }, + }, + }, + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The labels associated with this job template. You can use these to organize and group your job templates. + + +**Note**: This field is non-authoritative, and will only manage the labels present in your configuration. +Please refer to the field 'effective_labels' for all of the labels present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The resource name of the job template.`, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceTranscoderJobTemplateCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + configProp, err := expandTranscoderJobTemplateConfig(d.Get("config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("config"); !tpgresource.IsEmptyValue(reflect.ValueOf(configProp)) && (ok || !reflect.DeepEqual(v, configProp)) { + obj["config"] = configProp + } + labelsProp, err := expandTranscoderJobTemplateEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{TranscoderBasePath}}projects/{{project}}/locations/{{location}}/jobTemplates?jobTemplateId={{job_template_id}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new JobTemplate: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for JobTemplate: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + Headers: headers, + }) + if err != nil { + return fmt.Errorf("Error creating JobTemplate: %s", err) + } + if err := d.Set("name", flattenTranscoderJobTemplateName(res["name"], d, config)); err != nil { + return fmt.Errorf(`Error setting computed identity field "name": %s`, err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating JobTemplate %q: %#v", d.Id(), res) + + return resourceTranscoderJobTemplateRead(d, meta) +} + +func resourceTranscoderJobTemplateRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{TranscoderBasePath}}projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for JobTemplate: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Headers: headers, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("TranscoderJobTemplate %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading JobTemplate: %s", err) + } + + if err := d.Set("name", flattenTranscoderJobTemplateName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading JobTemplate: %s", err) + } + if err := d.Set("labels", flattenTranscoderJobTemplateLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading JobTemplate: %s", err) + } + if err := d.Set("config", flattenTranscoderJobTemplateConfig(res["config"], d, config)); err != nil { + return fmt.Errorf("Error reading JobTemplate: %s", err) + } + if err := d.Set("terraform_labels", flattenTranscoderJobTemplateTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading JobTemplate: %s", err) + } + if err := d.Set("effective_labels", flattenTranscoderJobTemplateEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading JobTemplate: %s", err) + } + + return nil +} + +func resourceTranscoderJobTemplateUpdate(d *schema.ResourceData, meta interface{}) error { + // Only the root field "labels" and "terraform_labels" are mutable + return resourceTranscoderJobTemplateRead(d, meta) +} + +func resourceTranscoderJobTemplateDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for JobTemplate: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{TranscoderBasePath}}projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}") + if err != nil { + return err + } + + var obj map[string]interface{} + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + + log.Printf("[DEBUG] Deleting JobTemplate %q", d.Id()) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + Headers: headers, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "JobTemplate") + } + + log.Printf("[DEBUG] Finished deleting JobTemplate %q: %#v", d.Id(), res) + return nil +} + +func resourceTranscoderJobTemplateImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/jobTemplates/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenTranscoderJobTemplateName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + return tpgresource.NameFromSelfLinkStateFunc(v) +} + +func flattenTranscoderJobTemplateLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("labels"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenTranscoderJobTemplateConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["inputs"] = + flattenTranscoderJobTemplateConfigInputs(original["inputs"], d, config) + transformed["edit_list"] = + flattenTranscoderJobTemplateConfigEditList(original["editList"], d, config) + transformed["elementary_streams"] = + flattenTranscoderJobTemplateConfigElementaryStreams(original["elementaryStreams"], d, config) + transformed["mux_streams"] = + flattenTranscoderJobTemplateConfigMuxStreams(original["muxStreams"], d, config) + transformed["manifests"] = + flattenTranscoderJobTemplateConfigManifests(original["manifests"], d, config) + transformed["output"] = + flattenTranscoderJobTemplateConfigOutput(original["output"], d, config) + transformed["ad_breaks"] = + flattenTranscoderJobTemplateConfigAdBreaks(original["adBreaks"], d, config) + transformed["pubsub_destination"] = + flattenTranscoderJobTemplateConfigPubsubDestination(original["pubsubDestination"], d, config) + transformed["overlays"] = + flattenTranscoderJobTemplateConfigOverlays(original["overlays"], d, config) + transformed["encryptions"] = + flattenTranscoderJobTemplateConfigEncryptions(original["encryptions"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigInputs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobTemplateConfigInputsKey(original["key"], d, config), + "uri": flattenTranscoderJobTemplateConfigInputsUri(original["uri"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigInputsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigInputsUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigEditList(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobTemplateConfigEditListKey(original["key"], d, config), + "inputs": flattenTranscoderJobTemplateConfigEditListInputs(original["inputs"], d, config), + "start_time_offset": flattenTranscoderJobTemplateConfigEditListStartTimeOffset(original["startTimeOffset"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigEditListKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigEditListInputs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigEditListStartTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobTemplateConfigElementaryStreamsKey(original["key"], d, config), + "video_stream": flattenTranscoderJobTemplateConfigElementaryStreamsVideoStream(original["videoStream"], d, config), + "audio_stream": flattenTranscoderJobTemplateConfigElementaryStreamsAudioStream(original["audioStream"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigElementaryStreamsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStream(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["h264"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264(original["h264"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["width_pixels"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264WidthPixels(original["widthPixels"], d, config) + transformed["height_pixels"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264HeightPixels(original["heightPixels"], d, config) + transformed["frame_rate"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264FrameRate(original["frameRate"], d, config) + transformed["bitrate_bps"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264BitrateBps(original["bitrateBps"], d, config) + transformed["pixel_format"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264PixelFormat(original["pixelFormat"], d, config) + transformed["rate_control_mode"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264RateControlMode(original["rateControlMode"], d, config) + transformed["crf_level"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264CrfLevel(original["crfLevel"], d, config) + transformed["vbv_size_bits"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvSizeBits(original["vbvSizeBits"], d, config) + transformed["vbv_fullness_bits"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvFullnessBits(original["vbvFullnessBits"], d, config) + transformed["entropy_coder"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264EntropyCoder(original["entropyCoder"], d, config) + transformed["profile"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Profile(original["profile"], d, config) + transformed["preset"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Preset(original["preset"], d, config) + transformed["gop_duration"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264GopDuration(original["gopDuration"], d, config) + transformed["sdr"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Sdr(original["sdr"], d, config) + transformed["hlg"] = + flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Hlg(original["hlg"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264WidthPixels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264HeightPixels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264FrameRate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264BitrateBps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264PixelFormat(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264RateControlMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264CrfLevel(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvSizeBits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvFullnessBits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264EntropyCoder(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Profile(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Preset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264GopDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Sdr(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Hlg(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsAudioStream(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["codec"] = + flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamCodec(original["codec"], d, config) + transformed["bitrate_bps"] = + flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamBitrateBps(original["bitrateBps"], d, config) + transformed["channel_count"] = + flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelCount(original["channelCount"], d, config) + transformed["channel_layout"] = + flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelLayout(original["channelLayout"], d, config) + transformed["sample_rate_hertz"] = + flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamSampleRateHertz(original["sampleRateHertz"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamCodec(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamBitrateBps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelLayout(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigElementaryStreamsAudioStreamSampleRateHertz(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenTranscoderJobTemplateConfigMuxStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "key": flattenTranscoderJobTemplateConfigMuxStreamsKey(original["key"], d, config), + "file_name": flattenTranscoderJobTemplateConfigMuxStreamsFileName(original["fileName"], d, config), + "container": flattenTranscoderJobTemplateConfigMuxStreamsContainer(original["container"], d, config), + "elementary_streams": flattenTranscoderJobTemplateConfigMuxStreamsElementaryStreams(original["elementaryStreams"], d, config), + "segment_settings": flattenTranscoderJobTemplateConfigMuxStreamsSegmentSettings(original["segmentSettings"], d, config), + "encryption_id": flattenTranscoderJobTemplateConfigMuxStreamsEncryptionId(original["encryptionId"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigMuxStreamsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigMuxStreamsFileName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigMuxStreamsContainer(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigMuxStreamsElementaryStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigMuxStreamsSegmentSettings(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["segment_duration"] = + flattenTranscoderJobTemplateConfigMuxStreamsSegmentSettingsSegmentDuration(original["segmentDuration"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigMuxStreamsSegmentSettingsSegmentDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigMuxStreamsEncryptionId(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigManifests(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "file_name": flattenTranscoderJobTemplateConfigManifestsFileName(original["fileName"], d, config), + "type": flattenTranscoderJobTemplateConfigManifestsType(original["type"], d, config), + "mux_streams": flattenTranscoderJobTemplateConfigManifestsMuxStreams(original["muxStreams"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigManifestsFileName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigManifestsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigManifestsMuxStreams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOutput(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["uri"] = + flattenTranscoderJobTemplateConfigOutputUri(original["uri"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigOutputUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigAdBreaks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "start_time_offset": flattenTranscoderJobTemplateConfigAdBreaksStartTimeOffset(original["startTimeOffset"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigAdBreaksStartTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigPubsubDestination(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["topic"] = + flattenTranscoderJobTemplateConfigPubsubDestinationTopic(original["topic"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigPubsubDestinationTopic(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOverlays(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "image": flattenTranscoderJobTemplateConfigOverlaysImage(original["image"], d, config), + "animations": flattenTranscoderJobTemplateConfigOverlaysAnimations(original["animations"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigOverlaysImage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["uri"] = + flattenTranscoderJobTemplateConfigOverlaysImageUri(original["uri"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigOverlaysImageUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOverlaysAnimations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "animation_fade": flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFade(original["animationFade"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFade(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["xy"] = + flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXy(original["xy"], d, config) + transformed["start_time_offset"] = + flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeStartTimeOffset(original["startTimeOffset"], d, config) + transformed["end_time_offset"] = + flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeEndTimeOffset(original["endTimeOffset"], d, config) + transformed["fade_type"] = + flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeFadeType(original["fadeType"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["x"] = + flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyX(original["x"], d, config) + transformed["y"] = + flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyY(original["y"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyX(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyY(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeStartTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeEndTimeOffset(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeFadeType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigEncryptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "id": flattenTranscoderJobTemplateConfigEncryptionsId(original["id"], d, config), + "drm_systems": flattenTranscoderJobTemplateConfigEncryptionsDrmSystems(original["drmSystems"], d, config), + "aes128": flattenTranscoderJobTemplateConfigEncryptionsAes128(original["aes128"], d, config), + "sample_aes": flattenTranscoderJobTemplateConfigEncryptionsSampleAes(original["sampleAes"], d, config), + "mpeg_cenc": flattenTranscoderJobTemplateConfigEncryptionsMpegCenc(original["mpegCenc"], d, config), + "secret_manager_key_source": flattenTranscoderJobTemplateConfigEncryptionsSecretManagerKeySource(original["secretManagerKeySource"], d, config), + }) + } + return transformed +} +func flattenTranscoderJobTemplateConfigEncryptionsId(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigEncryptionsDrmSystems(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["widevine"] = + flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsWidevine(original["widevine"], d, config) + transformed["fairplay"] = + flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsFairplay(original["fairplay"], d, config) + transformed["playready"] = + flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsPlayready(original["playready"], d, config) + transformed["clearkey"] = + flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsClearkey(original["clearkey"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsWidevine(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsFairplay(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsPlayready(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigEncryptionsDrmSystemsClearkey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigEncryptionsAes128(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigEncryptionsSampleAes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + transformed := make(map[string]interface{}) + return []interface{}{transformed} +} + +func flattenTranscoderJobTemplateConfigEncryptionsMpegCenc(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["scheme"] = + flattenTranscoderJobTemplateConfigEncryptionsMpegCencScheme(original["scheme"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigEncryptionsMpegCencScheme(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateConfigEncryptionsSecretManagerKeySource(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["secret_version"] = + flattenTranscoderJobTemplateConfigEncryptionsSecretManagerKeySourceSecretVersion(original["secretVersion"], d, config) + return []interface{}{transformed} +} +func flattenTranscoderJobTemplateConfigEncryptionsSecretManagerKeySourceSecretVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenTranscoderJobTemplateTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("terraform_labels"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenTranscoderJobTemplateEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandTranscoderJobTemplateConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedInputs, err := expandTranscoderJobTemplateConfigInputs(original["inputs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedInputs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["inputs"] = transformedInputs + } + + transformedEditList, err := expandTranscoderJobTemplateConfigEditList(original["edit_list"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEditList); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["editList"] = transformedEditList + } + + transformedElementaryStreams, err := expandTranscoderJobTemplateConfigElementaryStreams(original["elementary_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedElementaryStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["elementaryStreams"] = transformedElementaryStreams + } + + transformedMuxStreams, err := expandTranscoderJobTemplateConfigMuxStreams(original["mux_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMuxStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["muxStreams"] = transformedMuxStreams + } + + transformedManifests, err := expandTranscoderJobTemplateConfigManifests(original["manifests"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManifests); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manifests"] = transformedManifests + } + + transformedOutput, err := expandTranscoderJobTemplateConfigOutput(original["output"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOutput); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["output"] = transformedOutput + } + + transformedAdBreaks, err := expandTranscoderJobTemplateConfigAdBreaks(original["ad_breaks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdBreaks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["adBreaks"] = transformedAdBreaks + } + + transformedPubsubDestination, err := expandTranscoderJobTemplateConfigPubsubDestination(original["pubsub_destination"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPubsubDestination); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pubsubDestination"] = transformedPubsubDestination + } + + transformedOverlays, err := expandTranscoderJobTemplateConfigOverlays(original["overlays"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOverlays); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["overlays"] = transformedOverlays + } + + transformedEncryptions, err := expandTranscoderJobTemplateConfigEncryptions(original["encryptions"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEncryptions); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["encryptions"] = transformedEncryptions + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigInputs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobTemplateConfigInputsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedUri, err := expandTranscoderJobTemplateConfigInputsUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigInputsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigInputsUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigEditList(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobTemplateConfigEditListKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedInputs, err := expandTranscoderJobTemplateConfigEditListInputs(original["inputs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedInputs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["inputs"] = transformedInputs + } + + transformedStartTimeOffset, err := expandTranscoderJobTemplateConfigEditListStartTimeOffset(original["start_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStartTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["startTimeOffset"] = transformedStartTimeOffset + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigEditListKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigEditListInputs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigEditListStartTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobTemplateConfigElementaryStreamsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedVideoStream, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStream(original["video_stream"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVideoStream); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["videoStream"] = transformedVideoStream + } + + transformedAudioStream, err := expandTranscoderJobTemplateConfigElementaryStreamsAudioStream(original["audio_stream"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAudioStream); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["audioStream"] = transformedAudioStream + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStream(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedH264, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264(original["h264"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedH264); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["h264"] = transformedH264 + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedWidthPixels, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264WidthPixels(original["width_pixels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedWidthPixels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["widthPixels"] = transformedWidthPixels + } + + transformedHeightPixels, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264HeightPixels(original["height_pixels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHeightPixels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["heightPixels"] = transformedHeightPixels + } + + transformedFrameRate, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264FrameRate(original["frame_rate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFrameRate); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["frameRate"] = transformedFrameRate + } + + transformedBitrateBps, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264BitrateBps(original["bitrate_bps"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBitrateBps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bitrateBps"] = transformedBitrateBps + } + + transformedPixelFormat, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264PixelFormat(original["pixel_format"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPixelFormat); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pixelFormat"] = transformedPixelFormat + } + + transformedRateControlMode, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264RateControlMode(original["rate_control_mode"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRateControlMode); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["rateControlMode"] = transformedRateControlMode + } + + transformedCrfLevel, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264CrfLevel(original["crf_level"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCrfLevel); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["crfLevel"] = transformedCrfLevel + } + + transformedVbvSizeBits, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvSizeBits(original["vbv_size_bits"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVbvSizeBits); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vbvSizeBits"] = transformedVbvSizeBits + } + + transformedVbvFullnessBits, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvFullnessBits(original["vbv_fullness_bits"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVbvFullnessBits); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vbvFullnessBits"] = transformedVbvFullnessBits + } + + transformedEntropyCoder, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264EntropyCoder(original["entropy_coder"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEntropyCoder); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["entropyCoder"] = transformedEntropyCoder + } + + transformedProfile, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Profile(original["profile"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedProfile); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["profile"] = transformedProfile + } + + transformedPreset, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Preset(original["preset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPreset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["preset"] = transformedPreset + } + + transformedGopDuration, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264GopDuration(original["gop_duration"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedGopDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["gopDuration"] = transformedGopDuration + } + + transformedSdr, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Sdr(original["sdr"], d, config) + if err != nil { + return nil, err + } else { + transformed["sdr"] = transformedSdr + } + + transformedHlg, err := expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Hlg(original["hlg"], d, config) + if err != nil { + return nil, err + } else { + transformed["hlg"] = transformedHlg + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264WidthPixels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264HeightPixels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264FrameRate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264BitrateBps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264PixelFormat(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264RateControlMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264CrfLevel(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvSizeBits(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264VbvFullnessBits(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264EntropyCoder(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Profile(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Preset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264GopDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Sdr(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsVideoStreamH264Hlg(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsAudioStream(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedCodec, err := expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamCodec(original["codec"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCodec); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["codec"] = transformedCodec + } + + transformedBitrateBps, err := expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamBitrateBps(original["bitrate_bps"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBitrateBps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bitrateBps"] = transformedBitrateBps + } + + transformedChannelCount, err := expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelCount(original["channel_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedChannelCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["channelCount"] = transformedChannelCount + } + + transformedChannelLayout, err := expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelLayout(original["channel_layout"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedChannelLayout); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["channelLayout"] = transformedChannelLayout + } + + transformedSampleRateHertz, err := expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamSampleRateHertz(original["sample_rate_hertz"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSampleRateHertz); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["sampleRateHertz"] = transformedSampleRateHertz + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamCodec(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamBitrateBps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamChannelLayout(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigElementaryStreamsAudioStreamSampleRateHertz(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigMuxStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandTranscoderJobTemplateConfigMuxStreamsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedFileName, err := expandTranscoderJobTemplateConfigMuxStreamsFileName(original["file_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFileName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["fileName"] = transformedFileName + } + + transformedContainer, err := expandTranscoderJobTemplateConfigMuxStreamsContainer(original["container"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedContainer); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["container"] = transformedContainer + } + + transformedElementaryStreams, err := expandTranscoderJobTemplateConfigMuxStreamsElementaryStreams(original["elementary_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedElementaryStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["elementaryStreams"] = transformedElementaryStreams + } + + transformedSegmentSettings, err := expandTranscoderJobTemplateConfigMuxStreamsSegmentSettings(original["segment_settings"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSegmentSettings); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["segmentSettings"] = transformedSegmentSettings + } + + transformedEncryptionId, err := expandTranscoderJobTemplateConfigMuxStreamsEncryptionId(original["encryption_id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEncryptionId); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["encryptionId"] = transformedEncryptionId + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsFileName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsContainer(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsElementaryStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsSegmentSettings(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSegmentDuration, err := expandTranscoderJobTemplateConfigMuxStreamsSegmentSettingsSegmentDuration(original["segment_duration"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSegmentDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["segmentDuration"] = transformedSegmentDuration + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsSegmentSettingsSegmentDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigMuxStreamsEncryptionId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigManifests(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedFileName, err := expandTranscoderJobTemplateConfigManifestsFileName(original["file_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFileName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["fileName"] = transformedFileName + } + + transformedType, err := expandTranscoderJobTemplateConfigManifestsType(original["type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedType); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["type"] = transformedType + } + + transformedMuxStreams, err := expandTranscoderJobTemplateConfigManifestsMuxStreams(original["mux_streams"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMuxStreams); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["muxStreams"] = transformedMuxStreams + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigManifestsFileName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigManifestsType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigManifestsMuxStreams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOutput(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedUri, err := expandTranscoderJobTemplateConfigOutputUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigOutputUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigAdBreaks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedStartTimeOffset, err := expandTranscoderJobTemplateConfigAdBreaksStartTimeOffset(original["start_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStartTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["startTimeOffset"] = transformedStartTimeOffset + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigAdBreaksStartTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigPubsubDestination(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedTopic, err := expandTranscoderJobTemplateConfigPubsubDestinationTopic(original["topic"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTopic); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["topic"] = transformedTopic + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigPubsubDestinationTopic(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOverlays(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedImage, err := expandTranscoderJobTemplateConfigOverlaysImage(original["image"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedImage); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["image"] = transformedImage + } + + transformedAnimations, err := expandTranscoderJobTemplateConfigOverlaysAnimations(original["animations"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAnimations); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["animations"] = transformedAnimations + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigOverlaysImage(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedUri, err := expandTranscoderJobTemplateConfigOverlaysImageUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigOverlaysImageUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedAnimationFade, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFade(original["animation_fade"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAnimationFade); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["animationFade"] = transformedAnimationFade + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFade(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedXy, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXy(original["xy"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedXy); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["xy"] = transformedXy + } + + transformedStartTimeOffset, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeStartTimeOffset(original["start_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStartTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["startTimeOffset"] = transformedStartTimeOffset + } + + transformedEndTimeOffset, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeEndTimeOffset(original["end_time_offset"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEndTimeOffset); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["endTimeOffset"] = transformedEndTimeOffset + } + + transformedFadeType, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeFadeType(original["fade_type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFadeType); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["fadeType"] = transformedFadeType + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedX, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyX(original["x"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedX); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["x"] = transformedX + } + + transformedY, err := expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyY(original["y"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedY); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["y"] = transformedY + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyX(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeXyY(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeStartTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeEndTimeOffset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigOverlaysAnimationsAnimationFadeFadeType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigEncryptions(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedId, err := expandTranscoderJobTemplateConfigEncryptionsId(original["id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedId); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["id"] = transformedId + } + + transformedDrmSystems, err := expandTranscoderJobTemplateConfigEncryptionsDrmSystems(original["drm_systems"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDrmSystems); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["drmSystems"] = transformedDrmSystems + } + + transformedAes128, err := expandTranscoderJobTemplateConfigEncryptionsAes128(original["aes128"], d, config) + if err != nil { + return nil, err + } else { + transformed["aes128"] = transformedAes128 + } + + transformedSampleAes, err := expandTranscoderJobTemplateConfigEncryptionsSampleAes(original["sample_aes"], d, config) + if err != nil { + return nil, err + } else { + transformed["sampleAes"] = transformedSampleAes + } + + transformedMpegCenc, err := expandTranscoderJobTemplateConfigEncryptionsMpegCenc(original["mpeg_cenc"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMpegCenc); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["mpegCenc"] = transformedMpegCenc + } + + transformedSecretManagerKeySource, err := expandTranscoderJobTemplateConfigEncryptionsSecretManagerKeySource(original["secret_manager_key_source"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSecretManagerKeySource); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["secretManagerKeySource"] = transformedSecretManagerKeySource + } + + req = append(req, transformed) + } + return req, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsDrmSystems(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedWidevine, err := expandTranscoderJobTemplateConfigEncryptionsDrmSystemsWidevine(original["widevine"], d, config) + if err != nil { + return nil, err + } else { + transformed["widevine"] = transformedWidevine + } + + transformedFairplay, err := expandTranscoderJobTemplateConfigEncryptionsDrmSystemsFairplay(original["fairplay"], d, config) + if err != nil { + return nil, err + } else { + transformed["fairplay"] = transformedFairplay + } + + transformedPlayready, err := expandTranscoderJobTemplateConfigEncryptionsDrmSystemsPlayready(original["playready"], d, config) + if err != nil { + return nil, err + } else { + transformed["playready"] = transformedPlayready + } + + transformedClearkey, err := expandTranscoderJobTemplateConfigEncryptionsDrmSystemsClearkey(original["clearkey"], d, config) + if err != nil { + return nil, err + } else { + transformed["clearkey"] = transformedClearkey + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsDrmSystemsWidevine(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsDrmSystemsFairplay(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsDrmSystemsPlayready(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsDrmSystemsClearkey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsAes128(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsSampleAes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + transformed := make(map[string]interface{}) + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsMpegCenc(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedScheme, err := expandTranscoderJobTemplateConfigEncryptionsMpegCencScheme(original["scheme"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedScheme); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["scheme"] = transformedScheme + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsMpegCencScheme(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsSecretManagerKeySource(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSecretVersion, err := expandTranscoderJobTemplateConfigEncryptionsSecretManagerKeySourceSecretVersion(original["secret_version"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSecretVersion); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["secretVersion"] = transformedSecretVersion + } + + return transformed, nil +} + +func expandTranscoderJobTemplateConfigEncryptionsSecretManagerKeySourceSecretVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandTranscoderJobTemplateEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/transcoder/resource_transcoder_job_template_generated_test.go b/google/services/transcoder/resource_transcoder_job_template_generated_test.go new file mode 100644 index 00000000000..d146d363883 --- /dev/null +++ b/google/services/transcoder/resource_transcoder_job_template_generated_test.go @@ -0,0 +1,619 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package transcoder_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccTranscoderJobTemplate_transcoderJobTemplateBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJobTemplate_transcoderJobTemplateBasicExample(context), + }, + { + ResourceName: "google_transcoder_job_template.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"job_template_id", "labels", "location", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJobTemplate_transcoderJobTemplateBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_transcoder_job_template" "default" { + job_template_id = "tf-test-example-job-template%{random_suffix}" + location = "us-central1" + + config { + inputs { + key = "input0" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func TestAccTranscoderJobTemplate_transcoderJobTemplateOverlaysExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJobTemplate_transcoderJobTemplateOverlaysExample(context), + }, + { + ResourceName: "google_transcoder_job_template.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"job_template_id", "labels", "location", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJobTemplate_transcoderJobTemplateOverlaysExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_transcoder_job_template" "default" { + job_template_id = "tf-test-example-job-template%{random_suffix}" + location = "us-central1" + config { + inputs { + key = "input0" + uri = "gs://example/example.mp4" + } + output { + uri = "gs://example/outputs/" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + overlays { + animations { + animation_fade { + fade_type = "FADE_IN" + start_time_offset = "1.500s" + end_time_offset = "3.500s" + xy { + x = 1 + y = 0.5 + } + } + } + image { + uri = "gs://example/overlay.png" + } + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func TestAccTranscoderJobTemplate_transcoderJobTemplateEncryptionsExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJobTemplate_transcoderJobTemplateEncryptionsExample(context), + }, + { + ResourceName: "google_transcoder_job_template.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"job_template_id", "labels", "location", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJobTemplate_transcoderJobTemplateEncryptionsExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_secret_manager_secret" "encryption_key" { + secret_id = "tf-test-transcoder-encryption-key%{random_suffix}" + replication { + auto {} + } +} + +resource "google_secret_manager_secret_version" "encryption_key" { + secret = google_secret_manager_secret.encryption_key.name + secret_data = "4A67F2C1B8E93A4F6D3E7890A1BC23DF" +} + +resource "google_transcoder_job_template" "default" { + job_template_id = "tf-test-example-job-template%{random_suffix}" + location = "us-central1" + + config { + elementary_streams { + key = "es_video" + video_stream { + h264 { + profile = "main" + height_pixels = 600 + width_pixels = 800 + bitrate_bps = 1000000 + frame_rate = 60 + } + } + } + + elementary_streams { + key = "es_audio" + audio_stream { + codec = "aac" + channel_count = 2 + bitrate_bps = 160000 + } + } + + encryptions { + id = "aes-128" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + clearkey {} + } + aes128 {} + } + + encryptions { + id = "cenc" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + widevine {} + } + mpeg_cenc { + scheme = "cenc" + } + } + + encryptions { + id = "cbcs" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + widevine {} + } + mpeg_cenc { + scheme = "cbcs" + } + } + + mux_streams { + key = "ts_aes128" + container = "ts" + elementary_streams = ["es_video", "es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "aes-128" + } + + mux_streams { + key = "fmp4_cenc_video" + container = "fmp4" + elementary_streams = ["es_video"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cenc" + } + + mux_streams { + key = "fmp4_cenc_audio" + container = "fmp4" + elementary_streams = ["es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cenc" + } + + mux_streams { + key = "fmp4_cbcs_video" + container = "fmp4" + elementary_streams = ["es_video"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cbcs" + } + + mux_streams { + key = "fmp4_cbcs_audio" + container = "fmp4" + elementary_streams = ["es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cbcs" + } + + manifests { + file_name = "manifest_aes128.m3u8" + type = "HLS" + mux_streams = ["ts_aes128"] + } + + manifests { + file_name = "manifest_cenc.mpd" + type = "DASH" + mux_streams = ["fmp4_cenc_video", "fmp4_cenc_audio"] + } + + manifests { + file_name = "manifest_cbcs.mpd" + type = "DASH" + mux_streams = ["fmp4_cbcs_video", "fmp4_cbcs_audio"] + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func TestAccTranscoderJobTemplate_transcoderJobTemplatePubsubExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckTranscoderJobTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTranscoderJobTemplate_transcoderJobTemplatePubsubExample(context), + }, + { + ResourceName: "google_transcoder_job_template.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"job_template_id", "labels", "location", "terraform_labels"}, + }, + }, + }) +} + +func testAccTranscoderJobTemplate_transcoderJobTemplatePubsubExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_pubsub_topic" "transcoder_notifications" { + name = "tf-test-transcoder-notifications%{random_suffix}" +} + +resource "google_transcoder_job_template" "default" { + job_template_id = "tf-test-example-job-template%{random_suffix}" + location = "us-central1" + config { + inputs { + key = "input0" + uri = "gs://example/example.mp4" + } + output { + uri = "gs://example/outputs/" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + pubsub_destination { + topic = google_pubsub_topic.transcoder_notifications.id + } + } + labels = { + "label" = "key" + } +} +`, context) +} + +func testAccCheckTranscoderJobTemplateDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_transcoder_job_template" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{TranscoderBasePath}}projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("TranscoderJobTemplate still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/services/transcoder/resource_transcoder_job_template_sweeper.go b/google/services/transcoder/resource_transcoder_job_template_sweeper.go new file mode 100644 index 00000000000..3162ab341fb --- /dev/null +++ b/google/services/transcoder/resource_transcoder_job_template_sweeper.go @@ -0,0 +1,143 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package transcoder + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("TranscoderJobTemplate", testSweepTranscoderJobTemplate) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepTranscoderJobTemplate(region string) error { + resourceName := "TranscoderJobTemplate" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://transcoder.googleapis.com/v1/projects/{{project}}/locations/{{location}}/jobTemplates", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["jobTemplates"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + var name string + // Id detected in the delete URL, attempt to use id. + if obj["id"] != nil { + name = tpgresource.GetResourceNameFromSelfLink(obj["id"].(string)) + } else if obj["name"] != nil { + name = tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + } else { + log.Printf("[INFO][SWEEPER_LOG] %s resource name and id were nil", resourceName) + return nil + } + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://transcoder.googleapis.com/v1/projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/google/services/transcoder/test-fixtures/example.mp4 b/google/services/transcoder/test-fixtures/example.mp4 new file mode 100644 index 00000000000..b11552f9cb6 Binary files /dev/null and b/google/services/transcoder/test-fixtures/example.mp4 differ diff --git a/google/services/transcoder/test-fixtures/overlay.png b/google/services/transcoder/test-fixtures/overlay.png new file mode 100644 index 00000000000..276ac341265 Binary files /dev/null and b/google/services/transcoder/test-fixtures/overlay.png differ diff --git a/google/sweeper/gcp_sweeper_test.go b/google/sweeper/gcp_sweeper_test.go index 3b3394d0997..10dd4dddf08 100644 --- a/google/sweeper/gcp_sweeper_test.go +++ b/google/sweeper/gcp_sweeper_test.go @@ -123,6 +123,7 @@ import ( _ "github.com/hashicorp/terraform-provider-google/google/services/storagetransfer" _ "github.com/hashicorp/terraform-provider-google/google/services/tags" _ "github.com/hashicorp/terraform-provider-google/google/services/tpu" + _ "github.com/hashicorp/terraform-provider-google/google/services/transcoder" _ "github.com/hashicorp/terraform-provider-google/google/services/vertexai" _ "github.com/hashicorp/terraform-provider-google/google/services/vmwareengine" _ "github.com/hashicorp/terraform-provider-google/google/services/vpcaccess" diff --git a/google/transport/config.go b/google/transport/config.go index 623251e02c3..6738c6191cd 100644 --- a/google/transport/config.go +++ b/google/transport/config.go @@ -305,6 +305,7 @@ type Config struct { StorageTransferBasePath string TagsBasePath string TPUBasePath string + TranscoderBasePath string VertexAIBasePath string VmwareengineBasePath string VPCAccessBasePath string @@ -446,6 +447,7 @@ const StorageInsightsBasePathKey = "StorageInsights" const StorageTransferBasePathKey = "StorageTransfer" const TagsBasePathKey = "Tags" const TPUBasePathKey = "TPU" +const TranscoderBasePathKey = "Transcoder" const VertexAIBasePathKey = "VertexAI" const VmwareengineBasePathKey = "Vmwareengine" const VPCAccessBasePathKey = "VPCAccess" @@ -581,6 +583,7 @@ var DefaultBasePaths = map[string]string{ StorageTransferBasePathKey: "https://storagetransfer.googleapis.com/v1/", TagsBasePathKey: "https://cloudresourcemanager.googleapis.com/v3/", TPUBasePathKey: "https://tpu.googleapis.com/v1/", + TranscoderBasePathKey: "https://transcoder.googleapis.com/v1/", VertexAIBasePathKey: "https://{{region}}-aiplatform.googleapis.com/v1/", VmwareengineBasePathKey: "https://vmwareengine.googleapis.com/v1/", VPCAccessBasePathKey: "https://vpcaccess.googleapis.com/v1/", @@ -1255,6 +1258,11 @@ func SetEndpointDefaults(d *schema.ResourceData) error { "GOOGLE_TPU_CUSTOM_ENDPOINT", }, DefaultBasePaths[TPUBasePathKey])) } + if d.Get("transcoder_custom_endpoint") == "" { + d.Set("transcoder_custom_endpoint", MultiEnvDefault([]string{ + "GOOGLE_TRANSCODER_CUSTOM_ENDPOINT", + }, DefaultBasePaths[TranscoderBasePathKey])) + } if d.Get("vertex_ai_custom_endpoint") == "" { d.Set("vertex_ai_custom_endpoint", MultiEnvDefault([]string{ "GOOGLE_VERTEX_AI_CUSTOM_ENDPOINT", @@ -2304,6 +2312,7 @@ func ConfigureBasePaths(c *Config) { c.StorageTransferBasePath = DefaultBasePaths[StorageTransferBasePathKey] c.TagsBasePath = DefaultBasePaths[TagsBasePathKey] c.TPUBasePath = DefaultBasePaths[TPUBasePathKey] + c.TranscoderBasePath = DefaultBasePaths[TranscoderBasePathKey] c.VertexAIBasePath = DefaultBasePaths[VertexAIBasePathKey] c.VmwareengineBasePath = DefaultBasePaths[VmwareengineBasePathKey] c.VPCAccessBasePath = DefaultBasePaths[VPCAccessBasePathKey] diff --git a/website/docs/r/transcoder_job.html.markdown b/website/docs/r/transcoder_job.html.markdown new file mode 100644 index 00000000000..f4c198af76c --- /dev/null +++ b/website/docs/r/transcoder_job.html.markdown @@ -0,0 +1,1234 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Transcoder" +description: |- + Transcoding Job Resource +--- + +# google_transcoder_job + +Transcoding Job Resource + + +To get more information about Job, see: + +* [API documentation](https://cloud.google.com/transcoder/docs/reference/rest/v1/projects.locations.jobs) +* How-to Guides + * [Transcoder](https://cloud.google.com/transcoder/docs/) + + +## Example Usage - Transcoder Job Basic + + +```hcl +resource "google_storage_bucket" "default" { + name = "transcoder-job" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_transcoder_job" "default" { + template_id = google_transcoder_job_template.default.name + location = "us-central1" + + labels = { + "label" = "key" + } +} + +resource "google_transcoder_job_template" "default" { + job_template_id = "example-job-template" + location = "us-central1" + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + } + labels = { + "label" = "key" + } +} +``` + +## Example Usage - Transcoder Job Pubsub + + +```hcl +resource "google_storage_bucket" "default" { + name = "transcoder-job" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_pubsub_topic" "transcoder_notifications" { + name = "transcoder-notifications" +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + pubsub_destination { + topic = google_pubsub_topic.transcoder_notifications.id + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } +} +``` + +## Example Usage - Transcoder Job Encryptions + + +```hcl +resource "google_storage_bucket" "default" { + name = "transcoder-job" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" + provider = google-beta +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name + provider = google-beta +} + +resource "google_secret_manager_secret" "encryption_key" { + secret_id = "transcoder-encryption-key" + replication { + auto {} + } + provider = google-beta +} + +resource "google_secret_manager_secret_version" "encryption_key" { + secret = google_secret_manager_secret.encryption_key.name + secret_data = "4A67F2C1B8E93A4F6D3E7890A1BC23DF" + provider = google-beta +} + +data "google_project" "project" { + provider = google-beta +} + +# this is required to allow the transcoder service identity to access the secret +resource "google_project_service_identity" "transcoder" { + project = data.google_project.project.project_id + service = "transcoder.googleapis.com" + provider = google-beta +} + +resource "google_secret_manager_secret_iam_member" "transcoder_encryption_key_accessor" { + secret_id = google_secret_manager_secret.encryption_key.secret_id + project = google_secret_manager_secret.encryption_key.project + role = "roles/secretmanager.secretAccessor" + member = "serviceAccount:${google_project_service_identity.transcoder.email}" + provider = google-beta +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + elementary_streams { + key = "es_video" + video_stream { + h264 { + profile = "main" + height_pixels = 600 + width_pixels = 800 + bitrate_bps = 1000000 + frame_rate = 60 + } + } + } + elementary_streams { + key = "es_audio" + audio_stream { + codec = "aac" + channel_count = 2 + bitrate_bps = 160000 + } + } + encryptions { + id = "aes-128" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + clearkey {} + } + aes128 {} + } + encryptions { + id = "cenc" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + widevine {} + } + mpeg_cenc { + scheme = "cenc" + } + } + encryptions { + id = "cbcs" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + widevine {} + } + mpeg_cenc { + scheme = "cbcs" + } + } + mux_streams { + key = "ts_aes128" + container = "ts" + elementary_streams = ["es_video", "es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "aes-128" + } + mux_streams { + key = "fmp4_cenc_video" + container = "fmp4" + elementary_streams = ["es_video"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cenc" + } + mux_streams { + key = "fmp4_cenc_audio" + container = "fmp4" + elementary_streams = ["es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cenc" + } + mux_streams { + key = "fmp4_cbcs_video" + container = "fmp4" + elementary_streams = ["es_video"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cbcs" + } + mux_streams { + key = "fmp4_cbcs_audio" + container = "fmp4" + elementary_streams = ["es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cbcs" + } + manifests { + file_name = "manifest_aes128.m3u8" + type = "HLS" + mux_streams = ["ts_aes128"] + } + manifests { + file_name = "manifest_cenc.mpd" + type = "DASH" + mux_streams = ["fmp4_cenc_video", "fmp4_cenc_audio"] + } + manifests { + file_name = "manifest_cbcs.mpd" + type = "DASH" + mux_streams = ["fmp4_cbcs_video", "fmp4_cbcs_audio"] + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } + provider = google-beta +} +``` + +## Example Usage - Transcoder Job Overlays + + +```hcl +resource "google_storage_bucket" "default" { + name = "transcoder-job" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_storage_bucket_object" "overlay_png" { + name = "overlay.png" + source = "./test-fixtures/overlay.png" + bucket = google_storage_bucket.default.name +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + overlays { + animations { + animation_fade { + fade_type = "FADE_IN" + start_time_offset = "1.500s" + end_time_offset = "3.500s" + xy { + x = 1 + y = 0.5 + } + } + } + image { + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.overlay_png.name}" + } + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } +} +``` + +## Example Usage - Transcoder Job Manifests + + +```hcl +resource "google_storage_bucket" "default" { + name = "transcoder-job" + location = "US" + force_destroy = true + + uniform_bucket_level_access = true + public_access_prevention = "enforced" +} + +resource "google_storage_bucket_object" "example_mp4" { + name = "example.mp4" + source = "./test-fixtures/example.mp4" + bucket = google_storage_bucket.default.name +} + +resource "google_transcoder_job" "default" { + location = "us-central1" + + config { + inputs { + key = "input0" + uri = "gs://${google_storage_bucket.default.name}/${google_storage_bucket_object.example_mp4.name}" + } + + edit_list { + key = "atom0" + start_time_offset = "0s" + inputs = ["input0"] + } + + ad_breaks { + start_time_offset = "3.500s" + } + + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + + mux_streams { + key = "media-sd" + file_name = "media-sd.ts" + container = "ts" + elementary_streams = ["video-stream0", "audio-stream0"] + } + + mux_streams { + key = "media-hd" + file_name = "media-hd.ts" + container = "ts" + elementary_streams = ["video-stream1", "audio-stream0"] + } + + mux_streams { + key = "video-only-sd" + file_name = "video-only-sd.m4s" + container = "fmp4" + elementary_streams = ["video-stream0"] + } + + mux_streams { + key = "video-only-hd" + file_name = "video-only-hd.m4s" + container = "fmp4" + elementary_streams = ["video-stream1"] + } + + mux_streams { + key = "audio-only" + file_name = "audio-only.m4s" + container = "fmp4" + elementary_streams = ["audio-stream0"] + } + + manifests { + file_name = "manifest.m3u8" + type = "HLS" + mux_streams = ["media-sd", "media-hd"] + } + + manifests { + file_name = "manifest.mpd" + type = "DASH" + mux_streams = ["video-only-sd", "video-only-hd", "audio-only"] + } + + output { + uri = "gs://${google_storage_bucket.default.name}/outputs/" + } + } + labels = { + "label" = "key" + } +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `location` - + (Required) + The location of the transcoding job resource. + + +- - - + + +* `labels` - + (Optional) + The labels associated with this job. You can use these to organize and group your jobs. + + **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. + Please refer to the field `effective_labels` for all of the labels present on the resource. + +* `template_id` - + (Optional) + Specify the templateId to use for populating Job.config. + The default is preset/web-hd, which is the only supported preset. + +* `config` - + (Optional) + The configuration for this template. + Structure is [documented below](#nested_config). + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +The `config` block supports: + +* `inputs` - + (Optional) + List of input assets stored in Cloud Storage. + Structure is [documented below](#nested_inputs). + +* `edit_list` - + (Optional) + List of input assets stored in Cloud Storage. + Structure is [documented below](#nested_edit_list). + +* `elementary_streams` - + (Optional) + List of input assets stored in Cloud Storage. + Structure is [documented below](#nested_elementary_streams). + +* `mux_streams` - + (Optional) + Multiplexing settings for output stream. + Structure is [documented below](#nested_mux_streams). + +* `manifests` - + (Optional) + Manifest configuration. + Structure is [documented below](#nested_manifests). + +* `output` - + (Optional) + Location of output file(s) in a Cloud Storage bucket. + Structure is [documented below](#nested_output). + +* `ad_breaks` - + (Optional) + Ad break. + Structure is [documented below](#nested_ad_breaks). + +* `pubsub_destination` - + (Optional) + Pub/Sub destination. + Structure is [documented below](#nested_pubsub_destination). + +* `overlays` - + (Optional) + List of overlays on the output video, in descending Z-order. + Structure is [documented below](#nested_overlays). + +* `encryptions` - + (Optional) + List of encryption configurations for the content. + Structure is [documented below](#nested_encryptions). + + +The `inputs` block supports: + +* `key` - + (Optional) + A unique key for this input. Must be specified when using advanced mapping and edit lists. + +* `uri` - + (Optional) + URI of the media. Input files must be at least 5 seconds in duration and stored in Cloud Storage (for example, gs://bucket/inputs/file.mp4). + If empty, the value is populated from Job.input_uri. + +The `edit_list` block supports: + +* `key` - + (Optional) + A unique key for this atom. + +* `inputs` - + (Optional) + List of values identifying files that should be used in this atom. + +* `start_time_offset` - + (Optional) + Start time in seconds for the atom, relative to the input file timeline. The default is `0s`. + +The `elementary_streams` block supports: + +* `key` - + (Optional) + A unique key for this atom. + +* `video_stream` - + (Optional) + Encoding of a video stream. + Structure is [documented below](#nested_video_stream). + +* `audio_stream` - + (Optional) + Encoding of an audio stream. + Structure is [documented below](#nested_audio_stream). + + +The `video_stream` block supports: + +* `h264` - + (Optional) + H264 codec settings + Structure is [documented below](#nested_h264). + + +The `h264` block supports: + +* `width_pixels` - + (Optional) + The width of the video in pixels. + +* `height_pixels` - + (Optional) + The height of the video in pixels. + +* `frame_rate` - + (Required) + The target video frame rate in frames per second (FPS). + +* `bitrate_bps` - + (Required) + The video bitrate in bits per second. + +* `pixel_format` - + (Optional) + Pixel format to use. The default is `yuv420p`. + +* `rate_control_mode` - + (Optional) + Specify the mode. The default is `vbr`. + +* `crf_level` - + (Optional) + Target CRF level. The default is `21`. + +* `vbv_size_bits` - + (Optional) + Size of the Video Buffering Verifier (VBV) buffer in bits. + +* `vbv_fullness_bits` - + (Optional) + Initial fullness of the Video Buffering Verifier (VBV) buffer in bits. + +* `entropy_coder` - + (Optional) + The entropy coder to use. The default is `cabac`. + +* `profile` - + (Optional) + Enforces the specified codec profile. + +* `preset` - + (Optional) + Enforces the specified codec preset. The default is `veryfast`. + +* `gop_duration` - + (Optional) + Select the GOP size based on the specified duration. The default is `3s`. + +* `sdr` - + (Optional) + SDR color format setting for H264. + +* `hlg` - + (Optional) + HLG color format setting for H264. + +The `audio_stream` block supports: + +* `codec` - + (Optional) + The codec for this audio stream. The default is `aac`. + +* `bitrate_bps` - + (Required) + Audio bitrate in bits per second. + +* `channel_count` - + (Optional) + Number of audio channels. The default is `2`. + +* `channel_layout` - + (Optional) + A list of channel names specifying layout of the audio channels. The default is ["fl", "fr"]. + +* `sample_rate_hertz` - + (Optional) + The audio sample rate in Hertz. The default is `48000`. + +The `mux_streams` block supports: + +* `key` - + (Optional) + A unique key for this multiplexed stream. + +* `file_name` - + (Optional) + The name of the generated file. + +* `container` - + (Optional) + The container format. The default is `mp4`. + +* `elementary_streams` - + (Optional) + List of ElementaryStream.key values multiplexed in this stream. + +* `segment_settings` - + (Optional) + Segment settings for ts, fmp4 and vtt. + Structure is [documented below](#nested_segment_settings). + +* `encryption_id` - + (Optional) + Identifier of the encryption configuration to use. + + +The `segment_settings` block supports: + +* `segment_duration` - + (Optional) + Duration of the segments in seconds. The default is `6.0s`. + +The `manifests` block supports: + +* `file_name` - + (Optional) + The name of the generated file. The default is `manifest`. + +* `type` - + (Required) + Type of the manifest. + Possible values are: `MANIFEST_TYPE_UNSPECIFIED`, `HLS`, `DASH`. + +* `mux_streams` - + (Optional) + List of user supplied MuxStream.key values that should appear in this manifest. + +The `output` block supports: + +* `uri` - + (Optional) + URI for the output file(s). For example, gs://my-bucket/outputs/. + +The `ad_breaks` block supports: + +* `start_time_offset` - + (Optional) + Start time in seconds for the ad break, relative to the output file timeline + +The `pubsub_destination` block supports: + +* `topic` - + (Optional) + The name of the Pub/Sub topic to publish job completion notification to. For example: projects/{project}/topics/{topic}. + +The `overlays` block supports: + +* `image` - + (Optional) + Image overlay. + Structure is [documented below](#nested_image). + +* `animations` - + (Optional) + List of animations. The list should be chronological, without any time overlap. + Structure is [documented below](#nested_animations). + + +The `image` block supports: + +* `uri` - + (Required) + URI of the image in Cloud Storage. For example, gs://bucket/inputs/image.png. + +The `animations` block supports: + +* `animation_fade` - + (Optional) + Display overlay object with fade animation. + Structure is [documented below](#nested_animation_fade). + + +The `animation_fade` block supports: + +* `xy` - + (Optional) + Normalized coordinates based on output video resolution. + Structure is [documented below](#nested_xy). + +* `start_time_offset` - + (Optional) + The time to start the fade animation, in seconds. + +* `end_time_offset` - + (Optional) + The time to end the fade animation, in seconds. + +* `fade_type` - + (Required) + Required. Type of fade animation: `FADE_IN` or `FADE_OUT`. + The possible values are: + * `FADE_TYPE_UNSPECIFIED`: The fade type is not specified. + * `FADE_IN`: Fade the overlay object into view. + * `FADE_OUT`: Fade the overlay object out of view. + Possible values are: `FADE_TYPE_UNSPECIFIED`, `FADE_IN`, `FADE_OUT`. + + +The `xy` block supports: + +* `x` - + (Optional) + Normalized x coordinate. + +* `y` - + (Optional) + Normalized y coordinate. + +The `encryptions` block supports: + +* `id` - + (Required) + Identifier for this set of encryption options. + +* `drm_systems` - + (Optional) + DRM system(s) to use; at least one must be specified. If a DRM system is omitted, it is considered disabled. + Structure is [documented below](#nested_drm_systems). + +* `aes128` - + (Optional) + Configuration for AES-128 encryption. + +* `sample_aes` - + (Optional) + Configuration for SAMPLE-AES encryption. + +* `mpeg_cenc` - + (Optional) + Configuration for MPEG Common Encryption (MPEG-CENC). + Structure is [documented below](#nested_mpeg_cenc). + +* `secret_manager_key_source` - + (Optional) + Configuration for secrets stored in Google Secret Manager. + Structure is [documented below](#nested_secret_manager_key_source). + + +The `drm_systems` block supports: + +* `widevine` - + (Optional) + Widevine configuration. + +* `fairplay` - + (Optional) + Fairplay configuration. + +* `playready` - + (Optional) + Playready configuration. + +* `clearkey` - + (Optional) + Clearkey configuration. + +The `mpeg_cenc` block supports: + +* `scheme` - + (Required) + Specify the encryption scheme. + +The `secret_manager_key_source` block supports: + +* `secret_version` - + (Required) + The name of the Secret Version containing the encryption key in the following format: projects/{project}/secrets/{secret_id}/versions/{version_number}. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `{{name}}` + +* `name` - + The resource name of the job. + +* `create_time` - + The time the job was created. + +* `start_time` - + The time the transcoding started. + +* `end_time` - + The time the transcoding finished. + +* `state` - + The current state of the job. + +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `update` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +Job can be imported using any of these accepted formats: + +* `{{name}}` + + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Job using one of the formats above. For example: + +```tf +import { + id = "{{name}}" + to = google_transcoder_job.default +} +``` + +When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), Job can be imported using one of the formats above. For example: + +``` +$ terraform import google_transcoder_job.default {{name}} +``` + +## User Project Overrides + +This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override). diff --git a/website/docs/r/transcoder_job_template.html.markdown b/website/docs/r/transcoder_job_template.html.markdown new file mode 100644 index 00000000000..772bbba3ebc --- /dev/null +++ b/website/docs/r/transcoder_job_template.html.markdown @@ -0,0 +1,965 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Transcoder" +description: |- + Transcoding Job Template Resource +--- + +# google_transcoder_job_template + +Transcoding Job Template Resource + + +To get more information about JobTemplate, see: + +* [API documentation](https://cloud.google.com/transcoder/docs/reference/rest/v1/projects.locations.jobTemplates) +* How-to Guides + * [Transcoder](https://cloud.google.com/transcoder/docs/) + + +## Example Usage - Transcoder Job Template Basic + + +```hcl +resource "google_transcoder_job_template" "default" { + job_template_id = "example-job-template" + location = "us-central1" + + config { + inputs { + key = "input0" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + } + labels = { + "label" = "key" + } +} +``` + +## Example Usage - Transcoder Job Template Overlays + + +```hcl +resource "google_transcoder_job_template" "default" { + job_template_id = "example-job-template" + location = "us-central1" + config { + inputs { + key = "input0" + uri = "gs://example/example.mp4" + } + output { + uri = "gs://example/outputs/" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + overlays { + animations { + animation_fade { + fade_type = "FADE_IN" + start_time_offset = "1.500s" + end_time_offset = "3.500s" + xy { + x = 1 + y = 0.5 + } + } + } + image { + uri = "gs://example/overlay.png" + } + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + } + labels = { + "label" = "key" + } +} +``` + +## Example Usage - Transcoder Job Template Encryptions + + +```hcl +resource "google_secret_manager_secret" "encryption_key" { + secret_id = "transcoder-encryption-key" + replication { + auto {} + } +} + +resource "google_secret_manager_secret_version" "encryption_key" { + secret = google_secret_manager_secret.encryption_key.name + secret_data = "4A67F2C1B8E93A4F6D3E7890A1BC23DF" +} + +resource "google_transcoder_job_template" "default" { + job_template_id = "example-job-template" + location = "us-central1" + + config { + elementary_streams { + key = "es_video" + video_stream { + h264 { + profile = "main" + height_pixels = 600 + width_pixels = 800 + bitrate_bps = 1000000 + frame_rate = 60 + } + } + } + + elementary_streams { + key = "es_audio" + audio_stream { + codec = "aac" + channel_count = 2 + bitrate_bps = 160000 + } + } + + encryptions { + id = "aes-128" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + clearkey {} + } + aes128 {} + } + + encryptions { + id = "cenc" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + widevine {} + } + mpeg_cenc { + scheme = "cenc" + } + } + + encryptions { + id = "cbcs" + secret_manager_key_source { + secret_version = google_secret_manager_secret_version.encryption_key.name + } + drm_systems { + widevine {} + } + mpeg_cenc { + scheme = "cbcs" + } + } + + mux_streams { + key = "ts_aes128" + container = "ts" + elementary_streams = ["es_video", "es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "aes-128" + } + + mux_streams { + key = "fmp4_cenc_video" + container = "fmp4" + elementary_streams = ["es_video"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cenc" + } + + mux_streams { + key = "fmp4_cenc_audio" + container = "fmp4" + elementary_streams = ["es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cenc" + } + + mux_streams { + key = "fmp4_cbcs_video" + container = "fmp4" + elementary_streams = ["es_video"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cbcs" + } + + mux_streams { + key = "fmp4_cbcs_audio" + container = "fmp4" + elementary_streams = ["es_audio"] + segment_settings { + segment_duration = "6s" + } + encryption_id = "cbcs" + } + + manifests { + file_name = "manifest_aes128.m3u8" + type = "HLS" + mux_streams = ["ts_aes128"] + } + + manifests { + file_name = "manifest_cenc.mpd" + type = "DASH" + mux_streams = ["fmp4_cenc_video", "fmp4_cenc_audio"] + } + + manifests { + file_name = "manifest_cbcs.mpd" + type = "DASH" + mux_streams = ["fmp4_cbcs_video", "fmp4_cbcs_audio"] + } + } + labels = { + "label" = "key" + } +} +``` + +## Example Usage - Transcoder Job Template Pubsub + + +```hcl +resource "google_pubsub_topic" "transcoder_notifications" { + name = "transcoder-notifications" +} + +resource "google_transcoder_job_template" "default" { + job_template_id = "example-job-template" + location = "us-central1" + config { + inputs { + key = "input0" + uri = "gs://example/example.mp4" + } + output { + uri = "gs://example/outputs/" + } + edit_list { + key = "atom0" + inputs = ["input0"] + start_time_offset = "0s" + } + ad_breaks { + start_time_offset = "3.500s" + } + elementary_streams { + key = "video-stream0" + video_stream { + h264 { + width_pixels = 640 + height_pixels = 360 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 550000 + vbv_fullness_bits = 495000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + + } + } + } + elementary_streams { + key = "video-stream1" + video_stream { + h264 { + width_pixels = 1280 + height_pixels = 720 + bitrate_bps = 550000 + frame_rate = 60 + pixel_format = "yuv420p" + rate_control_mode = "vbr" + crf_level = 21 + gop_duration = "3s" + vbv_size_bits = 2500000 + vbv_fullness_bits = 2250000 + entropy_coder = "cabac" + profile = "high" + preset = "veryfast" + } + } + } + elementary_streams { + key = "audio-stream0" + audio_stream { + codec = "aac" + bitrate_bps = 64000 + channel_count = 2 + channel_layout = ["fl", "fr"] + sample_rate_hertz = 48000 + } + } + mux_streams { + key = "sd" + file_name = "sd.mp4" + container = "mp4" + elementary_streams = ["video-stream0", "audio-stream0"] + } + mux_streams { + key = "hd" + file_name = "hd.mp4" + container = "mp4" + elementary_streams = ["video-stream1", "audio-stream0"] + } + pubsub_destination { + topic = google_pubsub_topic.transcoder_notifications.id + } + } + labels = { + "label" = "key" + } +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `job_template_id` - + (Required) + ID to use for the Transcoding job template. + +* `location` - + (Required) + The location of the transcoding job template resource. + + +- - - + + +* `labels` - + (Optional) + The labels associated with this job template. You can use these to organize and group your job templates. + + **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. + Please refer to the field `effective_labels` for all of the labels present on the resource. + +* `config` - + (Optional) + The configuration for this template. + Structure is [documented below](#nested_config). + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +The `config` block supports: + +* `inputs` - + (Optional) + List of input assets stored in Cloud Storage. + Structure is [documented below](#nested_inputs). + +* `edit_list` - + (Optional) + List of input assets stored in Cloud Storage. + Structure is [documented below](#nested_edit_list). + +* `elementary_streams` - + (Optional) + List of input assets stored in Cloud Storage. + Structure is [documented below](#nested_elementary_streams). + +* `mux_streams` - + (Optional) + Multiplexing settings for output stream. + Structure is [documented below](#nested_mux_streams). + +* `manifests` - + (Optional) + Manifest configuration. + Structure is [documented below](#nested_manifests). + +* `output` - + (Optional) + Location of output file(s) in a Cloud Storage bucket. + Structure is [documented below](#nested_output). + +* `ad_breaks` - + (Optional) + Ad break. + Structure is [documented below](#nested_ad_breaks). + +* `pubsub_destination` - + (Optional) + Pub/Sub destination. + Structure is [documented below](#nested_pubsub_destination). + +* `overlays` - + (Optional) + List of overlays on the output video, in descending Z-order. + Structure is [documented below](#nested_overlays). + +* `encryptions` - + (Optional) + List of encryption configurations for the content. + Structure is [documented below](#nested_encryptions). + + +The `inputs` block supports: + +* `key` - + (Optional) + A unique key for this input. Must be specified when using advanced mapping and edit lists. + +* `uri` - + (Optional) + URI of the media. Input files must be at least 5 seconds in duration and stored in Cloud Storage (for example, gs://bucket/inputs/file.mp4). + If empty, the value is populated from Job.input_uri. + +The `edit_list` block supports: + +* `key` - + (Optional) + A unique key for this atom. + +* `inputs` - + (Optional) + List of values identifying files that should be used in this atom. + +* `start_time_offset` - + (Optional) + Start time in seconds for the atom, relative to the input file timeline. The default is `0s`. + +The `elementary_streams` block supports: + +* `key` - + (Optional) + A unique key for this atom. + +* `video_stream` - + (Optional) + Encoding of a video stream. + Structure is [documented below](#nested_video_stream). + +* `audio_stream` - + (Optional) + Encoding of an audio stream. + Structure is [documented below](#nested_audio_stream). + + +The `video_stream` block supports: + +* `h264` - + (Optional) + H264 codec settings + Structure is [documented below](#nested_h264). + + +The `h264` block supports: + +* `width_pixels` - + (Optional) + The width of the video in pixels. + +* `height_pixels` - + (Optional) + The height of the video in pixels. + +* `frame_rate` - + (Required) + The target video frame rate in frames per second (FPS). + +* `bitrate_bps` - + (Required) + The video bitrate in bits per second. + +* `pixel_format` - + (Optional) + Pixel format to use. The default is `yuv420p`. + +* `rate_control_mode` - + (Optional) + Specify the mode. The default is `vbr`. + +* `crf_level` - + (Optional) + Target CRF level. The default is `21`. + +* `vbv_size_bits` - + (Optional) + Size of the Video Buffering Verifier (VBV) buffer in bits. + +* `vbv_fullness_bits` - + (Optional) + Initial fullness of the Video Buffering Verifier (VBV) buffer in bits. + +* `entropy_coder` - + (Optional) + The entropy coder to use. The default is `cabac`. + +* `profile` - + (Optional) + Enforces the specified codec profile. + +* `preset` - + (Optional) + Enforces the specified codec preset. The default is `veryfast`. + +* `gop_duration` - + (Optional) + Select the GOP size based on the specified duration. The default is `3s`. + +* `sdr` - + (Optional) + SDR color format setting for H264. + +* `hlg` - + (Optional) + HLG color format setting for H264. + +The `audio_stream` block supports: + +* `codec` - + (Optional) + The codec for this audio stream. The default is `aac`. + +* `bitrate_bps` - + (Required) + Audio bitrate in bits per second. + +* `channel_count` - + (Optional) + Number of audio channels. The default is `2`. + +* `channel_layout` - + (Optional) + A list of channel names specifying layout of the audio channels. The default is ["fl", "fr"]. + +* `sample_rate_hertz` - + (Optional) + The audio sample rate in Hertz. The default is `48000`. + +The `mux_streams` block supports: + +* `key` - + (Optional) + A unique key for this multiplexed stream. + +* `file_name` - + (Optional) + The name of the generated file. + +* `container` - + (Optional) + The container format. The default is `mp4`. + +* `elementary_streams` - + (Optional) + List of ElementaryStream.key values multiplexed in this stream. + +* `segment_settings` - + (Optional) + Segment settings for ts, fmp4 and vtt. + Structure is [documented below](#nested_segment_settings). + +* `encryption_id` - + (Optional) + Identifier of the encryption configuration to use. + + +The `segment_settings` block supports: + +* `segment_duration` - + (Optional) + Duration of the segments in seconds. The default is `6.0s`. + +The `manifests` block supports: + +* `file_name` - + (Optional) + The name of the generated file. The default is `manifest`. + +* `type` - + (Required) + Type of the manifest. + Possible values are: `MANIFEST_TYPE_UNSPECIFIED`, `HLS`, `DASH`. + +* `mux_streams` - + (Optional) + List of user supplied MuxStream.key values that should appear in this manifest. + +The `output` block supports: + +* `uri` - + (Optional) + URI for the output file(s). For example, gs://my-bucket/outputs/. + +The `ad_breaks` block supports: + +* `start_time_offset` - + (Optional) + Start time in seconds for the ad break, relative to the output file timeline + +The `pubsub_destination` block supports: + +* `topic` - + (Optional) + The name of the Pub/Sub topic to publish job completion notification to. For example: projects/{project}/topics/{topic}. + +The `overlays` block supports: + +* `image` - + (Optional) + Image overlay. + Structure is [documented below](#nested_image). + +* `animations` - + (Optional) + List of animations. The list should be chronological, without any time overlap. + Structure is [documented below](#nested_animations). + + +The `image` block supports: + +* `uri` - + (Required) + URI of the image in Cloud Storage. For example, gs://bucket/inputs/image.png. + +The `animations` block supports: + +* `animation_fade` - + (Optional) + Display overlay object with fade animation. + Structure is [documented below](#nested_animation_fade). + + +The `animation_fade` block supports: + +* `xy` - + (Optional) + Normalized coordinates based on output video resolution. + Structure is [documented below](#nested_xy). + +* `start_time_offset` - + (Optional) + The time to start the fade animation, in seconds. + +* `end_time_offset` - + (Optional) + The time to end the fade animation, in seconds. + +* `fade_type` - + (Required) + Required. Type of fade animation: `FADE_IN` or `FADE_OUT`. + The possible values are: + * `FADE_TYPE_UNSPECIFIED`: The fade type is not specified. + * `FADE_IN`: Fade the overlay object into view. + * `FADE_OUT`: Fade the overlay object out of view. + Possible values are: `FADE_TYPE_UNSPECIFIED`, `FADE_IN`, `FADE_OUT`. + + +The `xy` block supports: + +* `x` - + (Optional) + Normalized x coordinate. + +* `y` - + (Optional) + Normalized y coordinate. + +The `encryptions` block supports: + +* `id` - + (Required) + Identifier for this set of encryption options. + +* `drm_systems` - + (Optional) + DRM system(s) to use; at least one must be specified. If a DRM system is omitted, it is considered disabled. + Structure is [documented below](#nested_drm_systems). + +* `aes128` - + (Optional) + Configuration for AES-128 encryption. + +* `sample_aes` - + (Optional) + Configuration for SAMPLE-AES encryption. + +* `mpeg_cenc` - + (Optional) + Configuration for MPEG Common Encryption (MPEG-CENC). + Structure is [documented below](#nested_mpeg_cenc). + +* `secret_manager_key_source` - + (Optional) + Configuration for secrets stored in Google Secret Manager. + Structure is [documented below](#nested_secret_manager_key_source). + + +The `drm_systems` block supports: + +* `widevine` - + (Optional) + Widevine configuration. + +* `fairplay` - + (Optional) + Fairplay configuration. + +* `playready` - + (Optional) + Playready configuration. + +* `clearkey` - + (Optional) + Clearkey configuration. + +The `mpeg_cenc` block supports: + +* `scheme` - + (Required) + Specify the encryption scheme. + +The `secret_manager_key_source` block supports: + +* `secret_version` - + (Required) + The name of the Secret Version containing the encryption key in the following format: projects/{project}/secrets/{secret_id}/versions/{version_number}. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}` + +* `name` - + The resource name of the job template. + +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `update` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +JobTemplate can be imported using any of these accepted formats: + +* `projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}` +* `{{project}}/{{location}}/{{job_template_id}}` +* `{{location}}/{{job_template_id}}` + + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import JobTemplate using one of the formats above. For example: + +```tf +import { + id = "projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}}" + to = google_transcoder_job_template.default +} +``` + +When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), JobTemplate can be imported using one of the formats above. For example: + +``` +$ terraform import google_transcoder_job_template.default projects/{{project}}/locations/{{location}}/jobTemplates/{{job_template_id}} +$ terraform import google_transcoder_job_template.default {{project}}/{{location}}/{{job_template_id}} +$ terraform import google_transcoder_job_template.default {{location}}/{{job_template_id}} +``` + +## User Project Overrides + +This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override).