Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct Connect virtual interfaces: Tag-on-create and validate type during import #9572

Merged
merged 6 commits into from
Nov 25, 2019
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