terraform/builtin/providers/aws/resource_aws_dms_endpoint.go

344 lines
8.3 KiB
Go
Raw Normal View History

package aws
import (
"log"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/private/waiter"
dms "github.com/aws/aws-sdk-go/service/databasemigrationservice"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceAwsDmsEndpoint() *schema.Resource {
return &schema.Resource{
Create: resourceAwsDmsEndpointCreate,
Read: resourceAwsDmsEndpointRead,
Update: resourceAwsDmsEndpointUpdate,
Delete: resourceAwsDmsEndpointDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"certificate_arn": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validateArn,
},
"database_name": {
Type: schema.TypeString,
Required: true,
},
"endpoint_arn": {
Type: schema.TypeString,
Computed: true,
},
"endpoint_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateDmsEndpointId,
},
"endpoint_type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
"source",
"target",
}, false),
},
"engine_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
"mysql",
"oracle",
"postgres",
"mariadb",
"aurora",
"redshift",
"sybase",
"sqlserver",
}, false),
},
"extra_connection_attributes": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"kms_key_arn": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
ValidateFunc: validateArn,
},
"password": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
},
"port": {
Type: schema.TypeInt,
Required: true,
},
"server_name": {
Type: schema.TypeString,
Required: true,
},
"ssl_mode": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"none",
"require",
"verify-ca",
"verify-full",
}, false),
},
"tags": {
Type: schema.TypeMap,
Optional: true,
},
"username": {
Type: schema.TypeString,
Required: true,
},
},
}
}
func resourceAwsDmsEndpointCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn
request := &dms.CreateEndpointInput{
DatabaseName: aws.String(d.Get("database_name").(string)),
EndpointIdentifier: aws.String(d.Get("endpoint_id").(string)),
EndpointType: aws.String(d.Get("endpoint_type").(string)),
EngineName: aws.String(d.Get("engine_name").(string)),
Password: aws.String(d.Get("password").(string)),
Port: aws.Int64(int64(d.Get("port").(int))),
ServerName: aws.String(d.Get("server_name").(string)),
Tags: dmsTagsFromMap(d.Get("tags").(map[string]interface{})),
Username: aws.String(d.Get("username").(string)),
}
if v, ok := d.GetOk("certificate_arn"); ok {
request.CertificateArn = aws.String(v.(string))
}
if v, ok := d.GetOk("extra_connection_attributes"); ok {
request.ExtraConnectionAttributes = aws.String(v.(string))
}
if v, ok := d.GetOk("kms_key_arn"); ok {
request.KmsKeyId = aws.String(v.(string))
}
if v, ok := d.GetOk("ssl_mode"); ok {
request.SslMode = aws.String(v.(string))
}
log.Println("[DEBUG] DMS create endpoint:", request)
_, err := conn.CreateEndpoint(request)
if err != nil {
return err
}
d.SetId(d.Get("endpoint_id").(string))
return resourceAwsDmsEndpointRead(d, meta)
}
func resourceAwsDmsEndpointRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn
response, err := conn.DescribeEndpoints(&dms.DescribeEndpointsInput{
Filters: []*dms.Filter{
{
Name: aws.String("endpoint-id"),
Values: []*string{aws.String(d.Id())}, // Must use d.Id() to work with import.
},
},
})
if err != nil {
if dmserr, ok := err.(awserr.Error); ok && dmserr.Code() == "ResourceNotFoundFault" {
d.SetId("")
return nil
}
return err
}
err = resourceAwsDmsEndpointSetState(d, response.Endpoints[0])
if err != nil {
return err
}
tagsResp, err := conn.ListTagsForResource(&dms.ListTagsForResourceInput{
ResourceArn: aws.String(d.Get("endpoint_arn").(string)),
})
if err != nil {
return err
}
d.Set("tags", dmsTagsToMap(tagsResp.TagList))
return nil
}
func resourceAwsDmsEndpointUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn
request := &dms.ModifyEndpointInput{
EndpointArn: aws.String(d.Get("endpoint_arn").(string)),
}
hasChanges := false
if d.HasChange("certificate_arn") {
request.CertificateArn = aws.String(d.Get("certificate_arn").(string))
hasChanges = true
}
if d.HasChange("database_name") {
request.DatabaseName = aws.String(d.Get("database_name").(string))
hasChanges = true
}
if d.HasChange("endpoint_type") {
request.EndpointType = aws.String(d.Get("endpoint_type").(string))
hasChanges = true
}
if d.HasChange("engine_name") {
request.EngineName = aws.String(d.Get("engine_name").(string))
hasChanges = true
}
if d.HasChange("extra_connection_attributes") {
request.ExtraConnectionAttributes = aws.String(d.Get("extra_connection_attributes").(string))
hasChanges = true
}
if d.HasChange("password") {
request.Password = aws.String(d.Get("password").(string))
hasChanges = true
}
if d.HasChange("port") {
request.Port = aws.Int64(int64(d.Get("port").(int)))
hasChanges = true
}
if d.HasChange("server_name") {
request.ServerName = aws.String(d.Get("server_name").(string))
hasChanges = true
}
if d.HasChange("ssl_mode") {
request.SslMode = aws.String(d.Get("ssl_mode").(string))
hasChanges = true
}
if d.HasChange("username") {
request.Username = aws.String(d.Get("username").(string))
hasChanges = true
}
if d.HasChange("tags") {
err := dmsSetTags(d.Get("endpoint_arn").(string), d, meta)
if err != nil {
return err
}
}
if hasChanges {
log.Println("[DEBUG] DMS update endpoint:", request)
_, err := conn.ModifyEndpoint(request)
if err != nil {
return err
}
return resourceAwsDmsEndpointRead(d, meta)
}
return nil
}
func resourceAwsDmsEndpointDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn
request := &dms.DeleteEndpointInput{
EndpointArn: aws.String(d.Get("endpoint_arn").(string)),
}
log.Printf("[DEBUG] DMS delete endpoint: %#v", request)
_, err := conn.DeleteEndpoint(request)
if err != nil {
return err
}
waitErr := waitForEndpointDelete(conn, d.Get("endpoint_id").(string), 30, 20)
if waitErr != nil {
return waitErr
}
return nil
}
func resourceAwsDmsEndpointSetState(d *schema.ResourceData, endpoint *dms.Endpoint) error {
d.SetId(*endpoint.EndpointIdentifier)
d.Set("certificate_arn", endpoint.CertificateArn)
d.Set("database_name", endpoint.DatabaseName)
d.Set("endpoint_arn", endpoint.EndpointArn)
d.Set("endpoint_id", endpoint.EndpointIdentifier)
// For some reason the AWS API only accepts lowercase type but returns it as uppercase
d.Set("endpoint_type", strings.ToLower(*endpoint.EndpointType))
d.Set("engine_name", endpoint.EngineName)
d.Set("extra_connection_attributes", endpoint.ExtraConnectionAttributes)
d.Set("kms_key_arn", endpoint.KmsKeyId)
d.Set("port", endpoint.Port)
d.Set("server_name", endpoint.ServerName)
d.Set("ssl_mode", endpoint.SslMode)
d.Set("username", endpoint.Username)
return nil
}
func waitForEndpointDelete(client *dms.DatabaseMigrationService, endpointId string, delay int, maxAttempts int) error {
input := &dms.DescribeEndpointsInput{
Filters: []*dms.Filter{
{
Name: aws.String("endpoint-id"),
Values: []*string{aws.String(endpointId)},
},
},
}
config := waiter.Config{
Operation: "DescribeEndpoints",
Delay: delay,
MaxAttempts: maxAttempts,
Acceptors: []waiter.WaitAcceptor{
{
State: "success",
Matcher: "path",
Argument: "length(Endpoints[]) > `0`",
Expected: false,
},
},
}
w := waiter.Waiter{
Client: client,
Input: input,
Config: config,
}
return w.Wait()
}