Skip to content

Commit

Permalink
Merge pull request #19083 from shedimon/f-aws_vpc_endpoint_connection…
Browse files Browse the repository at this point in the history
…_accepter

New resource/aws_vpc_endpoint_connection_accepter
  • Loading branch information
ewbankkit committed Dec 21, 2021
2 parents c07fe59 + 99a7fe6 commit 82b69c0
Show file tree
Hide file tree
Showing 8 changed files with 557 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/19083.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_vpc_endpoint_connection_accepter
```
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,7 @@ func Provider() *schema.Provider {
"aws_vpc_dhcp_options": ec2.ResourceVPCDHCPOptions(),
"aws_vpc_dhcp_options_association": ec2.ResourceVPCDHCPOptionsAssociation(),
"aws_vpc_endpoint": ec2.ResourceVPCEndpoint(),
"aws_vpc_endpoint_connection_accepter": ec2.ResourceVPCEndpointConnectionAccepter(),
"aws_vpc_endpoint_connection_notification": ec2.ResourceVPCEndpointConnectionNotification(),
"aws_vpc_endpoint_route_table_association": ec2.ResourceVPCEndpointRouteTableAssociation(),
"aws_vpc_endpoint_service": ec2.ResourceVPCEndpointService(),
Expand Down
45 changes: 45 additions & 0 deletions internal/service/ec2/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -1349,3 +1349,48 @@ func FindPlacementGroupByName(conn *ec2.EC2, name string) (*ec2.PlacementGroup,

return placementGroup, nil
}

func FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn *ec2.EC2, serviceID, vpcEndpointID string) (*ec2.VpcEndpointConnection, error) {
input := &ec2.DescribeVpcEndpointConnectionsInput{
Filters: BuildAttributeFilterList(map[string]string{
"service-id": serviceID,
// "InvalidFilter: The filter vpc-endpoint-id is invalid"
// "vpc-endpoint-id ": vpcEndpointID,
}),
}

var output *ec2.VpcEndpointConnection

err := conn.DescribeVpcEndpointConnectionsPages(input, func(page *ec2.DescribeVpcEndpointConnectionsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, v := range page.VpcEndpointConnections {
if aws.StringValue(v.VpcEndpointId) == vpcEndpointID {
output = v

return false
}
}

return !lastPage
})

if err != nil {
return nil, err
}

if output == nil {
return nil, tfresource.NewEmptyResultError(input)
}

if vpcEndpointState := aws.StringValue(output.VpcEndpointState); vpcEndpointState == VPCEndpointStateDeleted {
return nil, &resource.NotFoundError{
Message: vpcEndpointState,
LastRequest: input,
}
}

return output, nil
}
16 changes: 16 additions & 0 deletions internal/service/ec2/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,3 +641,19 @@ func StatusEBSSnapshotImport(conn *ec2.EC2, importTaskId string) resource.StateR
}
}
}

func statusVPCEndpointConnectionVPCEndpointState(conn *ec2.EC2, serviceID, vpcEndpointID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn, serviceID, vpcEndpointID)

if tfresource.NotFound(err) {
return nil, "", nil
}

if err != nil {
return nil, "", err
}

return output, aws.StringValue(output.VpcEndpointState), nil
}
}
146 changes: 146 additions & 0 deletions internal/service/ec2/vpc_endpoint_connection_accepter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package ec2

import (
"fmt"
"log"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func ResourceVPCEndpointConnectionAccepter() *schema.Resource {
return &schema.Resource{
Create: resourceVPCEndpointConnectionAccepterCreate,
Read: resourceVPCEndpointConnectionAccepterRead,
Delete: resourceVPCEndpointConnectionAccepterDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"vpc_endpoint_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"vpc_endpoint_service_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"vpc_endpoint_state": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).EC2Conn

serviceID := d.Get("vpc_endpoint_service_id").(string)
vpcEndpointID := d.Get("vpc_endpoint_id").(string)
id := VPCEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID)
input := &ec2.AcceptVpcEndpointConnectionsInput{
ServiceId: aws.String(serviceID),
VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}),
}

log.Printf("[DEBUG] Accepting VPC Endpoint Connection: %s", input)
_, err := conn.AcceptVpcEndpointConnections(input)

if err != nil {
return fmt.Errorf("error accepting VPC Endpoint Connection (%s): %w", id, err)
}

d.SetId(id)

_, err = waitVPCEndpointConnectionAccepted(conn, serviceID, vpcEndpointID, d.Timeout(schema.TimeoutCreate))

if err != nil {
return fmt.Errorf("error waiting for VPC Endpoint Connection (%s) to be accepted: %w", d.Id(), err)
}

return resourceVPCEndpointConnectionAccepterRead(d, meta)
}

func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).EC2Conn

serviceID, vpcEndpointID, err := VPCEndpointConnectionAccepterParseResourceID(d.Id())

if err != nil {
return err
}

vpcEndpointConnection, err := FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn, serviceID, vpcEndpointID)

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] VPC Endpoint Connection %s not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading VPC Endpoint Connection (%s): %w", d.Id(), err)
}

d.Set("vpc_endpoint_id", vpcEndpointConnection.VpcEndpointId)
d.Set("vpc_endpoint_service_id", vpcEndpointConnection.ServiceId)
d.Set("vpc_endpoint_state", vpcEndpointConnection.VpcEndpointState)

return nil
}

func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).EC2Conn

serviceID, vpcEndpointID, err := VPCEndpointConnectionAccepterParseResourceID(d.Id())

if err != nil {
return err
}

input := &ec2.RejectVpcEndpointConnectionsInput{
ServiceId: aws.String(serviceID),
VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}),
}

_, err = conn.RejectVpcEndpointConnections(input)

if tfawserr.ErrCodeEquals(err, ErrCodeInvalidVPCEndpointServiceIdNotFound) {
return nil
}

if err != nil {
return fmt.Errorf("error rejecting VPC Endpoint Connection (%s): %w", d.Id(), err)
}

return nil
}

const vpcEndpointConnectionAccepterResourceIDSeparator = "_"

func VPCEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID string) string {
parts := []string{serviceID, vpcEndpointID}
id := strings.Join(parts, vpcEndpointConnectionAccepterResourceIDSeparator)

return id
}

func VPCEndpointConnectionAccepterParseResourceID(id string) (string, string, error) {
parts := strings.Split(id, vpcEndpointConnectionAccepterResourceIDSeparator)

if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
return parts[0], parts[1], nil
}

return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected VPCEndpointServiceID%[2]sVPCEndpointID", id, vpcEndpointConnectionAccepterResourceIDSeparator)
}
Loading

0 comments on commit 82b69c0

Please sign in to comment.