From cde8b4a94f8b2186b18793856a7ca4572efa3b05 Mon Sep 17 00:00:00 2001 From: Stuart Auld Date: Fri, 21 Dec 2018 12:40:45 +1100 Subject: [PATCH 1/2] Added MediaPackage Channel resource --- aws/config.go | 3 + aws/provider.go | 1 + aws/resource_aws_media_package_channel.go | 156 ++++++++++++++++++ ...resource_aws_media_package_channel_test.go | 88 ++++++++++ website/aws.erb | 11 ++ .../r/media_package_channel.html.markdown | 41 +++++ 6 files changed, 300 insertions(+) create mode 100644 aws/resource_aws_media_package_channel.go create mode 100644 aws/resource_aws_media_package_channel_test.go create mode 100644 website/docs/r/media_package_channel.html.markdown diff --git a/aws/config.go b/aws/config.go index 03a1b69d2b6a..9ac2ad3cbbcc 100644 --- a/aws/config.go +++ b/aws/config.go @@ -77,6 +77,7 @@ import ( "github.com/aws/aws-sdk-go/service/licensemanager" "github.com/aws/aws-sdk-go/service/lightsail" "github.com/aws/aws-sdk-go/service/macie" + "github.com/aws/aws-sdk-go/service/mediapackage" "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" @@ -253,6 +254,7 @@ type AWSClient struct { glueconn *glue.Glue athenaconn *athena.Athena dxconn *directconnect.DirectConnect + mediapackageconn *mediapackage.MediaPackage mediastoreconn *mediastore.MediaStore appsyncconn *appsync.AppSync lexmodelconn *lexmodelbuildingservice.LexModelBuildingService @@ -592,6 +594,7 @@ func (c *Config) Client() (interface{}, error) { client.glueconn = glue.New(sess) client.athenaconn = athena.New(sess) client.dxconn = directconnect.New(sess) + client.mediapackageconn = mediapackage.New(sess) client.mediastoreconn = mediastore.New(sess) client.appsyncconn = appsync.New(sess) client.neptuneconn = neptune.New(sess) diff --git a/aws/provider.go b/aws/provider.go index 531bdf313b85..8097336eb1c5 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -544,6 +544,7 @@ func Provider() terraform.ResourceProvider { "aws_main_route_table_association": resourceAwsMainRouteTableAssociation(), "aws_mq_broker": resourceAwsMqBroker(), "aws_mq_configuration": resourceAwsMqConfiguration(), + "aws_media_package_channel": resourceAwsMediaPackageChannel(), "aws_media_store_container": resourceAwsMediaStoreContainer(), "aws_media_store_container_policy": resourceAwsMediaStoreContainerPolicy(), "aws_nat_gateway": resourceAwsNatGateway(), diff --git a/aws/resource_aws_media_package_channel.go b/aws/resource_aws_media_package_channel.go new file mode 100644 index 000000000000..ee1f8e375872 --- /dev/null +++ b/aws/resource_aws_media_package_channel.go @@ -0,0 +1,156 @@ +package aws + +import ( + "fmt" + "regexp" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/mediapackage" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" +) + +func resourceAwsMediaPackageChannel() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsMediaPackageChannelCreate, + Read: resourceAwsMediaPackageChannelRead, + Update: resourceAwsMediaPackageChannelUpdate, + Delete: resourceAwsMediaPackageChannelDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "channel_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[\w-]+$`), "must only contain alphanumeric characters, dashes or underscores"), + }, + "description": { + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + }, + "ingest_endpoints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "password": { + Type: schema.TypeString, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func resourceAwsMediaPackageChannelCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mediapackageconn + + input := &mediapackage.CreateChannelInput{ + Id: aws.String(d.Get("channel_id").(string)), + Description: aws.String(d.Get("description").(string)), + } + + _, err := conn.CreateChannel(input) + if err != nil { + return err + } + + d.SetId(d.Get("channel_id").(string)) + return resourceAwsMediaPackageChannelRead(d, meta) +} + +func resourceAwsMediaPackageChannelRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mediapackageconn + + input := &mediapackage.DescribeChannelInput{ + Id: aws.String(d.Id()), + } + resp, err := conn.DescribeChannel(input) + if err != nil { + return err + } + d.Set("arn", resp.Arn) + d.Set("description", resp.Description) + d.Set("ingest_endpoints", convertIngestEndpoints(resp.HlsIngest.IngestEndpoints)) + + return nil +} + +func resourceAwsMediaPackageChannelUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mediapackageconn + + input := &mediapackage.UpdateChannelInput{ + Id: aws.String(d.Id()), + Description: aws.String(d.Get("description").(string)), + } + + _, err := conn.UpdateChannel(input) + if err != nil { + return err + } + + return resourceAwsMediaPackageChannelRead(d, meta) +} + +func resourceAwsMediaPackageChannelDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mediapackageconn + + input := &mediapackage.DeleteChannelInput{ + Id: aws.String(d.Id()), + } + _, err := conn.DeleteChannel(input) + if err != nil { + if isAWSErr(err, mediapackage.ErrCodeNotFoundException, "") { + return nil + } + return err + } + + err = resource.Retry(5*time.Minute, func() *resource.RetryError { + dcinput := &mediapackage.DescribeChannelInput{ + Id: aws.String(d.Id()), + } + _, err := conn.DescribeChannel(dcinput) + if err != nil { + if isAWSErr(err, mediapackage.ErrCodeNotFoundException, "") { + return nil + } + return resource.NonRetryableError(err) + } + return resource.RetryableError(fmt.Errorf("Media Package Channel (%s) still exists", d.Id())) + }) + if err != nil { + return fmt.Errorf("error waiting for Media Package Channel (%s) deletion: %s", d.Id(), err) + } + + return nil +} + +func convertIngestEndpoints(es []*mediapackage.IngestEndpoint) (ingestEndpoints []map[string]interface{}) { + for _, e := range es { + endpoint := map[string]interface{}{ + "password": *e.Password, + "url": *e.Url, + "username": *e.Username, + } + + ingestEndpoints = append(ingestEndpoints, endpoint) + } + + return +} diff --git a/aws/resource_aws_media_package_channel_test.go b/aws/resource_aws_media_package_channel_test.go new file mode 100644 index 000000000000..68516f39064e --- /dev/null +++ b/aws/resource_aws_media_package_channel_test.go @@ -0,0 +1,88 @@ +package aws + +import ( + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/mediapackage" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSMediaPackageChannel_basic(t *testing.T) { + resourceName := "aws_media_package_channel.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsMediaPackageChannelDestroy, + Steps: []resource.TestStep{ + { + Config: testAccMediaPackageChannelConfig(acctest.RandString(5)), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsMediaPackageChannelExists(resourceName), + resource.TestMatchResourceAttr(resourceName, "ingest_endpoints.0.password", regexp.MustCompile("^[0-9a-f]*$")), + resource.TestMatchResourceAttr(resourceName, "ingest_endpoints.0.url", regexp.MustCompile("^https://")), + resource.TestMatchResourceAttr(resourceName, "ingest_endpoints.0.username", regexp.MustCompile("^[0-9a-f]*$")), + resource.TestMatchResourceAttr(resourceName, "ingest_endpoints.1.password", regexp.MustCompile("^[0-9a-f]*$")), + resource.TestMatchResourceAttr(resourceName, "ingest_endpoints.1.url", regexp.MustCompile("^https://")), + resource.TestMatchResourceAttr(resourceName, "ingest_endpoints.1.username", regexp.MustCompile("^[0-9a-f]*$")), + ), + }, + }, + }) +} + +func testAccCheckAwsMediaPackageChannelDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).mediapackageconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_media_package_channel" { + continue + } + + input := &mediapackage.DescribeChannelInput{ + Id: aws.String(rs.Primary.ID), + } + + _, err := conn.DescribeChannel(input) + if err == nil { + return fmt.Errorf("MediaPackage Channel (%s) not deleted", rs.Primary.ID) + } + + if !isAWSErr(err, mediapackage.ErrCodeNotFoundException, "") { + return err + } + } + + return nil +} + +func testAccCheckAwsMediaPackageChannelExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + conn := testAccProvider.Meta().(*AWSClient).mediapackageconn + + input := &mediapackage.DescribeChannelInput{ + Id: aws.String(rs.Primary.ID), + } + + _, err := conn.DescribeChannel(input) + + return err + } +} + +func testAccMediaPackageChannelConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_media_package_channel" "test" { + channel_id = "tf_mediachannel_%s" +}`, rName) +} diff --git a/website/aws.erb b/website/aws.erb index 785fb089252b..2c0727a65d28 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -1725,6 +1725,17 @@ + > + MediaPackage Resources + + + > MediaStore Resources