Skip to content

Commit

Permalink
Direct Connect virtual interfaces: Tag-on-create and validate type du…
Browse files Browse the repository at this point in the history
…ring import (#9572)

* r/aws_dx_private_virtual_interface: Add support for tag-on-create and verify virtual interface type during import.

* r/aws_dx_hosted_private_virtual_interface, r/aws_dx_hosted_private_virtual_interface_accepter: Add support for tag-on-create and verify virtual interface type during import.

* r/aws_dx_public_virtual_interface: Add support for tag-on-create and verify virtual interface type during import.

* r/aws_dx_hosted_public_virtual_interface, r/aws_dx_hosted_public_virtual_interface_accepter: Add support for tag-on-create and verify virtual interface type during import.

* Address review comments: Common acceptance test 'Exists' and 'Destroy' check methods.

* Update aws/resource_aws_dx_hosted_private_virtual_interface.go

Co-Authored-By: Brian Flad <[email protected]>
  • Loading branch information
ewbankkit and bflad committed Nov 25, 2019
1 parent 5bdaac0 commit 8225a62
Show file tree
Hide file tree
Showing 10 changed files with 988 additions and 624 deletions.
140 changes: 74 additions & 66 deletions aws/resource_aws_dx_hosted_private_virtual_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,28 @@ func resourceAwsDxHostedPrivateVirtualInterface() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"connection_id": {
"address_family": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
directconnect.AddressFamilyIpv4,
directconnect.AddressFamilyIpv6,
}, false),
},
"name": {
"amazon_address": {
Type: schema.TypeString,
Required: true,
Optional: true,
Computed: true,
ForceNew: true,
},
"vlan": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 4094),
"arn": {
Type: schema.TypeString,
Computed: true,
},
"aws_device": {
Type: schema.TypeString,
Computed: true,
},
"bgp_asn": {
Type: schema.TypeInt,
Expand All @@ -53,22 +56,31 @@ func resourceAwsDxHostedPrivateVirtualInterface() *schema.Resource {
Computed: true,
ForceNew: true,
},
"address_family": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{directconnect.AddressFamilyIpv4, directconnect.AddressFamilyIpv6}, false),
"connection_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"customer_address": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"amazon_address": {
Type: schema.TypeString,
Optional: true,
"jumbo_frame_capable": {
Type: schema.TypeBool,
Computed: true,
},
"mtu": {
Type: schema.TypeInt,
Default: 1500,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntInSlice([]int{1500, 9001}),
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"owner_account_id": {
Expand All @@ -77,20 +89,11 @@ func resourceAwsDxHostedPrivateVirtualInterface() *schema.Resource {
ForceNew: true,
ValidateFunc: validateAwsAccountId,
},
"mtu": {
"vlan": {
Type: schema.TypeInt,
Default: 1500,
Optional: true,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntInSlice([]int{1500, 9001}),
},
"jumbo_frame_capable": {
Type: schema.TypeBool,
Computed: true,
},
"aws_device": {
Type: schema.TypeString,
Computed: true,
ValidateFunc: validation.IntBetween(1, 4094),
},
},

Expand All @@ -107,43 +110,35 @@ func resourceAwsDxHostedPrivateVirtualInterfaceCreate(d *schema.ResourceData, me

req := &directconnect.AllocatePrivateVirtualInterfaceInput{
ConnectionId: aws.String(d.Get("connection_id").(string)),
OwnerAccount: aws.String(d.Get("owner_account_id").(string)),
NewPrivateVirtualInterfaceAllocation: &directconnect.NewPrivateVirtualInterfaceAllocation{
VirtualInterfaceName: aws.String(d.Get("name").(string)),
Vlan: aws.Int64(int64(d.Get("vlan").(int))),
Asn: aws.Int64(int64(d.Get("bgp_asn").(int))),
AddressFamily: aws.String(d.Get("address_family").(string)),
Asn: aws.Int64(int64(d.Get("bgp_asn").(int))),
Mtu: aws.Int64(int64(d.Get("mtu").(int))),
VirtualInterfaceName: aws.String(d.Get("name").(string)),
Vlan: aws.Int64(int64(d.Get("vlan").(int))),
},
OwnerAccount: aws.String(d.Get("owner_account_id").(string)),
}
if v, ok := d.GetOk("amazon_address"); ok && v.(string) != "" {
req.NewPrivateVirtualInterfaceAllocation.AmazonAddress = aws.String(v.(string))
}
if v, ok := d.GetOk("bgp_auth_key"); ok && v.(string) != "" {
req.NewPrivateVirtualInterfaceAllocation.AuthKey = aws.String(v.(string))
}
if v, ok := d.GetOk("customer_address"); ok && v.(string) != "" {
req.NewPrivateVirtualInterfaceAllocation.CustomerAddress = aws.String(v.(string))
}
if v, ok := d.GetOk("amazon_address"); ok && v.(string) != "" {
req.NewPrivateVirtualInterfaceAllocation.AmazonAddress = aws.String(v.(string))
}
if v, ok := d.GetOk("mtu"); ok && v.(int) != 0 {
req.NewPrivateVirtualInterfaceAllocation.Mtu = aws.Int64(int64(v.(int)))
}

log.Printf("[DEBUG] Creating Direct Connect hosted private virtual interface: %#v", req)
log.Printf("[DEBUG] Creating Direct Connect hosted private virtual interface: %s", req)
resp, err := conn.AllocatePrivateVirtualInterface(req)
if err != nil {
return fmt.Errorf("Error creating Direct Connect hosted private virtual interface: %s", err.Error())
return fmt.Errorf("error creating Direct Connect hosted private virtual interface: %s", err)
}

d.SetId(aws.StringValue(resp.VirtualInterfaceId))
arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "directconnect",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("dxvif/%s", d.Id()),
}.String()
d.Set("arn", arn)

if err := dxHostedPrivateVirtualInterfaceWaitUntilAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
return err
Expand All @@ -160,23 +155,31 @@ func resourceAwsDxHostedPrivateVirtualInterfaceRead(d *schema.ResourceData, meta
return err
}
if vif == nil {
log.Printf("[WARN] Direct Connect virtual interface (%s) not found, removing from state", d.Id())
log.Printf("[WARN] Direct Connect hosted private virtual interface (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

d.Set("connection_id", vif.ConnectionId)
d.Set("name", vif.VirtualInterfaceName)
d.Set("vlan", vif.Vlan)
d.Set("address_family", vif.AddressFamily)
arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "directconnect",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("dxvif/%s", d.Id()),
}.String()
d.Set("amazon_address", vif.AmazonAddress)
d.Set("arn", arn)
d.Set("aws_device", vif.AwsDeviceV2)
d.Set("bgp_asn", vif.Asn)
d.Set("bgp_auth_key", vif.AuthKey)
d.Set("address_family", vif.AddressFamily)
d.Set("connection_id", vif.ConnectionId)
d.Set("customer_address", vif.CustomerAddress)
d.Set("amazon_address", vif.AmazonAddress)
d.Set("owner_account_id", vif.OwnerAccount)
d.Set("mtu", vif.Mtu)
d.Set("jumbo_frame_capable", vif.JumboFrameCapable)
d.Set("aws_device", vif.AwsDeviceV2)
d.Set("mtu", vif.Mtu)
d.Set("name", vif.VirtualInterfaceName)
d.Set("owner_account_id", vif.OwnerAccount)
d.Set("vlan", vif.Vlan)

return nil
}
Expand All @@ -186,14 +189,19 @@ func resourceAwsDxHostedPrivateVirtualInterfaceDelete(d *schema.ResourceData, me
}

func resourceAwsDxHostedPrivateVirtualInterfaceImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "directconnect",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("dxvif/%s", d.Id()),
}.String()
d.Set("arn", arn)
conn := meta.(*AWSClient).dxconn

vif, err := dxVirtualInterfaceRead(d.Id(), conn)
if err != nil {
return nil, err
}
if vif == nil {
return nil, fmt.Errorf("virtual interface (%s) not found", d.Id())
}

if vifType := aws.StringValue(vif.VirtualInterfaceType); vifType != "private" {
return nil, fmt.Errorf("virtual interface (%s) has incorrect type: %s", d.Id(), vifType)
}

return []*schema.ResourceData{d}, nil
}
Expand Down
51 changes: 34 additions & 17 deletions aws/resource_aws_dx_hosted_private_virtual_interface_accepter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ func resourceAwsDxHostedPrivateVirtualInterfaceAccepter() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"dx_gateway_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"vpn_gateway_id"},
},
"tags": tagsSchema(),
"virtual_interface_id": {
Type: schema.TypeString,
Required: true,
Expand All @@ -37,13 +44,6 @@ func resourceAwsDxHostedPrivateVirtualInterfaceAccepter() *schema.Resource {
ForceNew: true,
ConflictsWith: []string{"dx_gateway_id"},
},
"dx_gateway_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"vpn_gateway_id"},
},
"tags": tagsSchema(),
},

Timeouts: &schema.ResourceTimeout{
Expand All @@ -67,17 +67,17 @@ func resourceAwsDxHostedPrivateVirtualInterfaceAccepterCreate(d *schema.Resource
req := &directconnect.ConfirmPrivateVirtualInterfaceInput{
VirtualInterfaceId: aws.String(vifId),
}
if vgwOk && vgwIdRaw.(string) != "" {
req.VirtualGatewayId = aws.String(vgwIdRaw.(string))
}
if dxgwOk && dxgwIdRaw.(string) != "" {
req.DirectConnectGatewayId = aws.String(dxgwIdRaw.(string))
}
if vgwOk && vgwIdRaw.(string) != "" {
req.VirtualGatewayId = aws.String(vgwIdRaw.(string))
}

log.Printf("[DEBUG] Accepting Direct Connect hosted private virtual interface: %#v", req)
log.Printf("[DEBUG] Accepting Direct Connect hosted private virtual interface: %s", req)
_, err := conn.ConfirmPrivateVirtualInterface(req)
if err != nil {
return fmt.Errorf("Error accepting Direct Connect hosted private virtual interface: %s", err.Error())
return fmt.Errorf("error accepting Direct Connect hosted private virtual interface: %s", err)
}

d.SetId(vifId)
Expand Down Expand Up @@ -105,23 +105,26 @@ func resourceAwsDxHostedPrivateVirtualInterfaceAccepterRead(d *schema.ResourceDa
return err
}
if vif == nil {
log.Printf("[WARN] Direct Connect virtual interface (%s) not found, removing from state", d.Id())
log.Printf("[WARN] Direct Connect hosted private virtual interface (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
vifState := aws.StringValue(vif.VirtualInterfaceState)
if vifState != directconnect.VirtualInterfaceStateAvailable &&
vifState != directconnect.VirtualInterfaceStateDown {
log.Printf("[WARN] Direct Connect virtual interface (%s) is '%s', removing from state", vifState, d.Id())
log.Printf("[WARN] Direct Connect hosted private virtual interface (%s) is '%s', removing from state", vifState, d.Id())
d.SetId("")
return nil
}

d.Set("dx_gateway_id", vif.DirectConnectGatewayId)
d.Set("virtual_interface_id", vif.VirtualInterfaceId)
d.Set("vpn_gateway_id", vif.VirtualGatewayId)
d.Set("dx_gateway_id", vif.DirectConnectGatewayId)
err1 := getTagsDX(conn, d, d.Get("arn").(string))
return err1
if err := getTagsDX(conn, d, d.Get("arn").(string)); err != nil {
return fmt.Errorf("error getting Direct Connect hosted private virtual interface (%s) tags: %s", d.Id(), err)
}

return nil
}

func resourceAwsDxHostedPrivateVirtualInterfaceAccepterUpdate(d *schema.ResourceData, meta interface{}) error {
Expand All @@ -138,6 +141,20 @@ func resourceAwsDxHostedPrivateVirtualInterfaceAccepterDelete(d *schema.Resource
}

func resourceAwsDxHostedPrivateVirtualInterfaceAccepterImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
conn := meta.(*AWSClient).dxconn

vif, err := dxVirtualInterfaceRead(d.Id(), conn)
if err != nil {
return nil, err
}
if vif == nil {
return nil, fmt.Errorf("virtual interface (%s) not found", d.Id())
}

if vifType := aws.StringValue(vif.VirtualInterfaceType); vifType != "private" {
return nil, fmt.Errorf("virtual interface (%s) has incorrect type: %s", d.Id(), vifType)
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Expand Down
Loading

0 comments on commit 8225a62

Please sign in to comment.