Skip to content

Commit

Permalink
Merge pull request #21265 from awsaxeman/f-route_table_for_fsx_ontap_…
Browse files Browse the repository at this point in the history
…routes

fix route table for Amazon FSx for NetApp ONTAP routes and tag
  • Loading branch information
ewbankkit authored Nov 2, 2021
2 parents 031ca40 + 787bf3a commit aa38005
Show file tree
Hide file tree
Showing 24 changed files with 1,825 additions and 1,146 deletions.
15 changes: 15 additions & 0 deletions .changelog/21265.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```release-note:bug-fix
resource/aws_route_table: Remove cross-account ENIs managed by AWS services like FSX for ONTAP from Terraform-managed routes to avoid diffs
```

```release-note:enhancement
resource/aws_network_interface: Add `arn` and `owner_id` attributes
```

```release-note:enhancement
resource/aws_network_interface: Add `ipv4_prefix`, `ipv4_prefix_count`, `ipv6_prefix` and `ipv6_prefix_count` arguments
```

```release-note:enhancement
data-source/aws_network_interface: Add `arn` attribute
```
5 changes: 5 additions & 0 deletions internal/service/ec2/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ const (
EBSSnapshotImportStateConverting = "converting"
EBSSnapshotImportStateCompleted = "completed"
)

// See https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html#API_CreateNetworkInterface_Example_2_Response
const (
NetworkInterfaceStatusPending = "pending"
)
1 change: 1 addition & 0 deletions internal/service/ec2/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
const (
ErrCodeGatewayNotAttached = "Gateway.NotAttached"
ErrCodeInvalidAssociationIDNotFound = "InvalidAssociationID.NotFound"
ErrCodeInvalidAttachmentIDNotFound = "InvalidAttachmentID.NotFound"
ErrCodeInvalidParameter = "InvalidParameter"
ErrCodeInvalidParameterException = "InvalidParameterException"
ErrCodeInvalidParameterValue = "InvalidParameterValue"
Expand Down
79 changes: 56 additions & 23 deletions internal/service/ec2/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,59 +236,92 @@ func FindNetworkACLEntry(conn *ec2.EC2, networkAclID string, egress bool, ruleNu
return nil, nil
}

// FindNetworkInterfaceByID looks up a NetworkInterface by ID. When not found, returns nil and potentially an API error.
func FindNetworkInterface(conn *ec2.EC2, input *ec2.DescribeNetworkInterfacesInput) (*ec2.NetworkInterface, error) {
output, err := conn.DescribeNetworkInterfaces(input)

if tfawserr.ErrCodeEquals(err, ErrCodeInvalidNetworkInterfaceIDNotFound) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil {
return nil, nil
}

if output == nil || len(output.NetworkInterfaces) == 0 || output.NetworkInterfaces[0] == nil {
return nil, tfresource.NewEmptyResultError(input)
}

if count := len(output.NetworkInterfaces); count > 1 {
return nil, tfresource.NewTooManyResultsError(count, input)
}

return output.NetworkInterfaces[0], nil
}

func FindNetworkInterfaceByID(conn *ec2.EC2, id string) (*ec2.NetworkInterface, error) {
input := &ec2.DescribeNetworkInterfacesInput{
NetworkInterfaceIds: aws.StringSlice([]string{id}),
}

output, err := conn.DescribeNetworkInterfaces(input)
networkInterface, err := FindNetworkInterface(conn, input)

if err != nil {
return nil, err
}

if output == nil {
return nil, nil
// Eventual consistency check.
if aws.StringValue(networkInterface.NetworkInterfaceId) != id {
return nil, &resource.NotFoundError{
LastRequest: input,
}
}

for _, networkInterface := range output.NetworkInterfaces {
if networkInterface == nil {
continue
}
return networkInterface, nil
}

if aws.StringValue(networkInterface.NetworkInterfaceId) != id {
continue
}
func FindNetworkInterfaceAttachmentByID(conn *ec2.EC2, id string) (*ec2.NetworkInterfaceAttachment, error) {
input := &ec2.DescribeNetworkInterfacesInput{
Filters: BuildAttributeFilterList(map[string]string{
"attachment.attachment-id": id,
}),
}

networkInterface, err := FindNetworkInterface(conn, input)

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

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

return networkInterface.Attachment, nil
}

// FindNetworkInterfaceSecurityGroup returns the associated GroupIdentifier if found
func FindNetworkInterfaceSecurityGroup(conn *ec2.EC2, networkInterfaceID string, securityGroupID string) (*ec2.GroupIdentifier, error) {
var result *ec2.GroupIdentifier

networkInterface, err := FindNetworkInterfaceByID(conn, networkInterfaceID)

if err != nil {
return nil, err
}

if networkInterface == nil {
return nil, nil
}

for _, groupIdentifier := range networkInterface.Groups {
if aws.StringValue(groupIdentifier.GroupId) == securityGroupID {
result = groupIdentifier
break
return groupIdentifier, nil
}
}

return result, err
return nil, &resource.NotFoundError{
LastError: fmt.Errorf("Network Interface (%s) Security Group (%s) not found", networkInterfaceID, securityGroupID),
}
}

// FindMainRouteTableAssociationByID returns the main route table association corresponding to the specified identifier.
Expand Down
88 changes: 0 additions & 88 deletions internal/service/ec2/flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

//Flattens network interface attachment into a map[string]interface
func FlattenAttachment(a *ec2.NetworkInterfaceAttachment) map[string]interface{} {
att := make(map[string]interface{})
if a.InstanceId != nil {
att["instance"] = *a.InstanceId
}
if a.DeviceIndex != nil {
att["device_index"] = *a.DeviceIndex
}
if a.AttachmentId != nil {
att["attachment_id"] = *a.AttachmentId
}
return att
}

func flattenAttributeValues(l []*ec2.AttributeValue) []string {
values := make([]string, 0, len(l))
for _, v := range l {
Expand Down Expand Up @@ -53,18 +38,6 @@ type GroupIdentifier struct {
Description *string
}

func expandIP6Addresses(ips []interface{}) []*ec2.InstanceIpv6Address {
dtos := make([]*ec2.InstanceIpv6Address, 0, len(ips))
for _, v := range ips {
ipv6Address := &ec2.InstanceIpv6Address{
Ipv6Address: aws.String(v.(string)),
}

dtos = append(dtos, ipv6Address)
}
return dtos
}

// Takes the result of flatmap.Expand for an array of ingress/egress security
// group rules and returns EC2 API compatible objects. This function will error
// if it finds invalid permissions input, namely a protocol of "-1" with either
Expand Down Expand Up @@ -175,67 +148,6 @@ func ExpandIPPerms(
return perms, nil
}

func flattenNetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) []interface{} {
tfMap := map[string]interface{}{}

if a.AllocationId != nil {
tfMap["allocation_id"] = aws.StringValue(a.AllocationId)
}
if a.AssociationId != nil {
tfMap["association_id"] = aws.StringValue(a.AssociationId)
}
if a.CarrierIp != nil {
tfMap["carrier_ip"] = aws.StringValue(a.CarrierIp)
}
if a.CustomerOwnedIp != nil {
tfMap["customer_owned_ip"] = aws.StringValue(a.CustomerOwnedIp)
}
if a.IpOwnerId != nil {
tfMap["ip_owner_id"] = aws.StringValue(a.IpOwnerId)
}
if a.PublicDnsName != nil {
tfMap["public_dns_name"] = aws.StringValue(a.PublicDnsName)
}
if a.PublicIp != nil {
tfMap["public_ip"] = aws.StringValue(a.PublicIp)
}

return []interface{}{tfMap}
}

func flattenNetworkInterfaceIPv6Address(niia []*ec2.NetworkInterfaceIpv6Address) []string {
ips := make([]string, 0, len(niia))
for _, v := range niia {
ips = append(ips, *v.Ipv6Address)
}
return ips
}

//Flattens an array of private ip addresses into a []string, where the elements returned are the IP strings e.g. "192.168.0.0"
func FlattenNetworkInterfacesPrivateIPAddresses(dtos []*ec2.NetworkInterfacePrivateIpAddress) []string {
ips := make([]string, 0, len(dtos))
for _, v := range dtos {
ip := *v.PrivateIpAddress
ips = append(ips, ip)
}
return ips
}

//Expands an array of IPs into a ec2 Private IP Address Spec
func ExpandPrivateIPAddresses(ips []interface{}) []*ec2.PrivateIpAddressSpecification {
dtos := make([]*ec2.PrivateIpAddressSpecification, 0, len(ips))
for i, v := range ips {
new_private_ip := &ec2.PrivateIpAddressSpecification{
PrivateIpAddress: aws.String(v.(string)),
}

new_private_ip.Primary = aws.Bool(i == 0)

dtos = append(dtos, new_private_ip)
}
return dtos
}

// Flattens an array of UserSecurityGroups into a []*GroupIdentifier
func FlattenSecurityGroups(list []*ec2.UserIdGroupPair, ownerId *string) []*GroupIdentifier {
result := make([]*GroupIdentifier, 0, len(list))
Expand Down
92 changes: 0 additions & 92 deletions internal/service/ec2/flex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func TestFlattenAttachment(t *testing.T) {
expanded := &ec2.NetworkInterfaceAttachment{
InstanceId: aws.String("i-00001"),
DeviceIndex: aws.Int64(1),
AttachmentId: aws.String("at-002"),
}

result := FlattenAttachment(expanded)

if result == nil {
t.Fatal("expected result to have value, but got nil")
}

if result["instance"] != "i-00001" {
t.Fatalf("expected instance to be i-00001, but got %s", result["instance"])
}

if result["device_index"] != int64(1) {
t.Fatalf("expected device_index to be 1, but got %d", result["device_index"])
}

if result["attachment_id"] != "at-002" {
t.Fatalf("expected attachment_id to be at-002, but got %s", result["attachment_id"])
}
}

func TestFlattenAttachmentWhenNoInstanceId(t *testing.T) {
expanded := &ec2.NetworkInterfaceAttachment{
DeviceIndex: aws.Int64(1),
AttachmentId: aws.String("at-002"),
}

result := FlattenAttachment(expanded)

if result == nil {
t.Fatal("expected result to have value, but got nil")
}

if result["instance"] != nil {
t.Fatalf("expected instance to be nil, but got %s", result["instance"])
}
}

func TestFlattenGroupIdentifiers(t *testing.T) {
expanded := []*ec2.GroupIdentifier{
{GroupId: aws.String("sg-001")},
Expand Down Expand Up @@ -378,55 +335,6 @@ func TestExpandIPPerms_nonVPC(t *testing.T) {
}
}

func TestFlattenNetworkInterfacesPrivateIPAddresses(t *testing.T) {
expanded := []*ec2.NetworkInterfacePrivateIpAddress{
{PrivateIpAddress: aws.String("192.168.0.1")},
{PrivateIpAddress: aws.String("192.168.0.2")},
}

result := FlattenNetworkInterfacesPrivateIPAddresses(expanded)

if result == nil {
t.Fatal("result was nil")
}

if len(result) != 2 {
t.Fatalf("expected result had %d elements, but got %d", 2, len(result))
}

if result[0] != "192.168.0.1" {
t.Fatalf("expected ip to be 192.168.0.1, but was %s", result[0])
}

if result[1] != "192.168.0.2" {
t.Fatalf("expected ip to be 192.168.0.2, but was %s", result[1])
}
}

func TestExpandPrivateIPAddresses(t *testing.T) {

ip1 := "192.168.0.1"
ip2 := "192.168.0.2"
flattened := []interface{}{
ip1,
ip2,
}

result := ExpandPrivateIPAddresses(flattened)

if len(result) != 2 {
t.Fatalf("expected result had %d elements, but got %d", 2, len(result))
}

if aws.StringValue(result[0].PrivateIpAddress) != "192.168.0.1" || !aws.BoolValue(result[0].Primary) {
t.Fatalf("expected ip to be 192.168.0.1 and Primary, but got %v, %t", aws.StringValue(result[0].PrivateIpAddress), aws.BoolValue(result[0].Primary))
}

if aws.StringValue(result[1].PrivateIpAddress) != "192.168.0.2" || aws.BoolValue(result[1].Primary) {
t.Fatalf("expected ip to be 192.168.0.2 and not Primary, but got %v, %t", aws.StringValue(result[1].PrivateIpAddress), aws.BoolValue(result[1].Primary))
}
}

func TestFlattenSecurityGroups(t *testing.T) {
cases := []struct {
ownerId *string
Expand Down
Loading

0 comments on commit aa38005

Please sign in to comment.