From 430fad0b89d254d924d529c98d143d9a70e9615d Mon Sep 17 00:00:00 2001 From: Marco Reni Date: Mon, 22 Oct 2018 14:05:57 +0200 Subject: [PATCH 1/2] resource/pinpoint_apns_voip_channel --- aws/provider.go | 1 + ...resource_aws_pinpoint_apns_voip_channel.go | 159 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 aws/resource_aws_pinpoint_apns_voip_channel.go diff --git a/aws/provider.go b/aws/provider.go index d6e8ac73f7e..81753ffb6f4 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -683,6 +683,7 @@ func Provider() terraform.ResourceProvider { "aws_pinpoint_app": resourceAwsPinpointApp(), "aws_pinpoint_adm_channel": resourceAwsPinpointADMChannel(), "aws_pinpoint_apns_channel": resourceAwsPinpointAPNSChannel(), + "aws_pinpoint_apns_voip_channel": resourceAwsPinpointAPNSVoipChannel(), "aws_pinpoint_baidu_channel": resourceAwsPinpointBaiduChannel(), "aws_pinpoint_email_channel": resourceAwsPinpointEmailChannel(), "aws_pinpoint_event_stream": resourceAwsPinpointEventStream(), diff --git a/aws/resource_aws_pinpoint_apns_voip_channel.go b/aws/resource_aws_pinpoint_apns_voip_channel.go new file mode 100644 index 00000000000..0663b95be7f --- /dev/null +++ b/aws/resource_aws_pinpoint_apns_voip_channel.go @@ -0,0 +1,159 @@ +package aws + +import ( + "errors" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/pinpoint" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsPinpointAPNSVoipChannel() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsPinpointAPNSVoipChannelUpsert, + Read: resourceAwsPinpointAPNSVoipChannelRead, + Update: resourceAwsPinpointAPNSVoipChannelUpsert, + Delete: resourceAwsPinpointAPNSVoipChannelDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "application_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "bundle_id": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "certificate": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "default_authentication_method": { + Type: schema.TypeString, + Optional: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "private_key": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "team_id": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "token_key": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "token_key_id": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + }, + } +} + +func resourceAwsPinpointAPNSVoipChannelUpsert(d *schema.ResourceData, meta interface{}) error { + certificate, certificateOk := d.GetOk("certificate") + privateKey, privateKeyOk := d.GetOk("private_key") + + bundleId, bundleIdOk := d.GetOk("bundle_id") + teamId, teamIdOk := d.GetOk("team_id") + tokenKey, tokenKeyOk := d.GetOk("token_key") + tokenKeyId, tokenKeyIdOk := d.GetOk("token_key_id") + + if !(certificateOk && privateKeyOk) && !(bundleIdOk && teamIdOk && tokenKeyOk && tokenKeyIdOk) { + return errors.New("At least one set of credentials is required; either [certificate, private_key] or [bundle_id, team_id, token_key, token_key_id]") + } + + conn := meta.(*AWSClient).pinpointconn + + applicationId := d.Get("application_id").(string) + + params := &pinpoint.APNSVoipChannelRequest{} + + params.DefaultAuthenticationMethod = aws.String(d.Get("default_authentication_method").(string)) + params.Enabled = aws.Bool(d.Get("enabled").(bool)) + + params.Certificate = aws.String(certificate.(string)) + params.PrivateKey = aws.String(privateKey.(string)) + + params.BundleId = aws.String(bundleId.(string)) + params.TeamId = aws.String(teamId.(string)) + params.TokenKey = aws.String(tokenKey.(string)) + params.TokenKeyId = aws.String(tokenKeyId.(string)) + + req := pinpoint.UpdateApnsVoipChannelInput{ + ApplicationId: aws.String(applicationId), + APNSVoipChannelRequest: params, + } + + _, err := conn.UpdateApnsVoipChannel(&req) + if err != nil { + return fmt.Errorf("error updating Pinpoint APNs Voip Channel for Application %s: %s", applicationId, err) + } + + d.SetId(applicationId) + + return resourceAwsPinpointAPNSVoipChannelRead(d, meta) +} + +func resourceAwsPinpointAPNSVoipChannelRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).pinpointconn + + log.Printf("[INFO] Reading Pinpoint APNs Voip Channel for Application %s", d.Id()) + + output, err := conn.GetApnsVoipChannel(&pinpoint.GetApnsVoipChannelInput{ + ApplicationId: aws.String(d.Id()), + }) + if err != nil { + if isAWSErr(err, pinpoint.ErrCodeNotFoundException, "") { + log.Printf("[WARN] Pinpoint APNs Voip Channel for application %s not found, error code (404)", d.Id()) + d.SetId("") + return nil + } + + return fmt.Errorf("error getting Pinpoint APNs Voip Channel for application %s: %s", d.Id(), err) + } + + d.Set("application_id", output.APNSVoipChannelResponse.ApplicationId) + d.Set("default_authentication_method", output.APNSVoipChannelResponse.DefaultAuthenticationMethod) + d.Set("enabled", output.APNSVoipChannelResponse.Enabled) + // Sensitive params are not returned + + return nil +} + +func resourceAwsPinpointAPNSVoipChannelDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).pinpointconn + + log.Printf("[DEBUG] Deleting Pinpoint APNs Voip Channel: %s", d.Id()) + _, err := conn.DeleteApnsVoipChannel(&pinpoint.DeleteApnsVoipChannelInput{ + ApplicationId: aws.String(d.Id()), + }) + + if isAWSErr(err, pinpoint.ErrCodeNotFoundException, "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Pinpoint APNs Voip Channel for Application %s: %s", d.Id(), err) + } + return nil +} From c92c78d400b3531d106bae7c101dfe65ec4d71df Mon Sep 17 00:00:00 2001 From: Marco Reni Date: Mon, 22 Oct 2018 14:06:32 +0200 Subject: [PATCH 2/2] resource/aws_pinpoint_apns_voip_channel: docs + tests --- ...rce_aws_pinpoint_apns_voip_channel_test.go | 257 ++++++++++++++++++ website/aws.erb | 3 + .../r/pinpoint_apns_voip_channel.markdown | 59 ++++ 3 files changed, 319 insertions(+) create mode 100644 aws/resource_aws_pinpoint_apns_voip_channel_test.go create mode 100644 website/docs/r/pinpoint_apns_voip_channel.markdown diff --git a/aws/resource_aws_pinpoint_apns_voip_channel_test.go b/aws/resource_aws_pinpoint_apns_voip_channel_test.go new file mode 100644 index 00000000000..42e327e4838 --- /dev/null +++ b/aws/resource_aws_pinpoint_apns_voip_channel_test.go @@ -0,0 +1,257 @@ +package aws + +import ( + "fmt" + "os" + "strconv" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/service/pinpoint" + + "github.com/aws/aws-sdk-go/aws" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +/** + Before running this test, one of the following two ENV variables set must be defined. See here for details: + https://docs.aws.amazon.com/pinpoint/latest/userguide/channels-mobile-manage.html + + * Key Configuration (ref. https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns ) + APNS_VOIP_BUNDLE_ID - APNs Bundle ID + APNS_VOIP_TEAM_ID - APNs Team ID + APNS_VOIP_TOKEN_KEY - Token key file content (.p8 file) + APNS_VOIP_TOKEN_KEY_ID - APNs Token Key ID + + * Certificate Configuration (ref. https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns - Select "VoIP Services Certificate" ) + APNS_VOIP_CERTIFICATE - APNs Certificate content (.pem file content) + APNS_VOIP_CERTIFICATE_PRIVATE_KEY - APNs Certificate Private Key File content +**/ + +type testAccAwsPinpointAPNSVoipChannelCertConfiguration struct { + Certificate string + PrivateKey string +} + +type testAccAwsPinpointAPNSVoipChannelTokenConfiguration struct { + BundleId string + TeamId string + TokenKey string + TokenKeyId string +} + +func testAccAwsPinpointAPNSVoipChannelCertConfigurationFromEnv(t *testing.T) *testAccAwsPinpointAPNSVoipChannelCertConfiguration { + var conf *testAccAwsPinpointAPNSVoipChannelCertConfiguration + if os.Getenv("APNS_VOIP_CERTIFICATE") != "" { + if os.Getenv("APNS_VOIP_CERTIFICATE_PRIVATE_KEY") == "" { + t.Fatalf("APNS_VOIP_CERTIFICATE set but missing APNS_VOIP_CERTIFICATE_PRIVATE_KEY") + } + + conf = &testAccAwsPinpointAPNSVoipChannelCertConfiguration{ + Certificate: fmt.Sprintf("<> aws_pinpoint_apns_channel + > + aws_pinpoint_apns_voip_channel + > aws_pinpoint_baidu_channel diff --git a/website/docs/r/pinpoint_apns_voip_channel.markdown b/website/docs/r/pinpoint_apns_voip_channel.markdown new file mode 100644 index 00000000000..ef3bbed8dc4 --- /dev/null +++ b/website/docs/r/pinpoint_apns_voip_channel.markdown @@ -0,0 +1,59 @@ +--- +layout: "aws" +page_title: "AWS: aws_pinpoint_apns_voip_channel" +sidebar_current: "docs-aws-resource-pinpoint-apns-voip-channel" +description: |- + Provides a Pinpoint APNs VoIP Channel resource. +--- + +# aws_pinpoint_apns_voip_channel + +Provides a Pinpoint APNs VoIP Channel resource. + +~> **Note:** All arguments, including certificates and tokens, will be stored in the raw state as plain-text. +[Read more about sensitive data in state](/docs/state/sensitive-data.html). + +## Example Usage + +```hcl +resource "aws_pinpoint_apns_voip_channel" "apns_voip" { + application_id = "${aws_pinpoint_app.app.application_id}" + + certificate = "${file("./certificate.pem")}" + private_key = "${file("./private_key.key")}" +} + +resource "aws_pinpoint_app" "app" {} +``` + + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The application ID. +* `enabled` - (Optional) Whether the channel is enabled or disabled. Defaults to `true`. +* `default_authentication_method` - (Optional) The default authentication method used for APNs. + __NOTE__: Amazon Pinpoint uses this default for every APNs push notification that you send using the console. + You can override the default when you send a message programmatically using the Amazon Pinpoint API, the AWS CLI, or an AWS SDK. + If your default authentication type fails, Amazon Pinpoint doesn't attempt to use the other authentication type. + +One of the following sets of credentials is also required. + +If you choose to use __Certificate credentials__ you will have to provide: +* `certificate` - (Required) The pem encoded TLS Certificate from Apple. +* `private_key` - (Required) The Certificate Private Key file (ie. `.key` file). + +If you choose to use __Key credentials__ you will have to provide: +* `bundle_id` - (Required) The ID assigned to your iOS app. To find this value, choose Certificates, IDs & Profiles, choose App IDs in the Identifiers section, and choose your app. +* `team_id` - (Required) The ID assigned to your Apple developer account team. This value is provided on the Membership page. +* `token_key` - (Required) The `.p8` file that you download from your Apple developer account when you create an authentication key. +* `token_key_id` - (Required) The ID assigned to your signing key. To find this value, choose Certificates, IDs & Profiles, and choose your key in the Keys section. + +## Import + +Pinpoint APNs VoIP Channel can be imported using the `application-id`, e.g. + +``` +$ terraform import aws_pinpoint_apns_voip_channel.apns_voip application-id +```