344 lines
8.3 KiB
Go
344 lines
8.3 KiB
Go
|
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()
|
||
|
}
|