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

fix route table for Amazon FSx for NetApp ONTAP routes and tag #21265

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0026f9e
ignore cross account ENIs and FSx Tag
awsaxeman Oct 11, 2021
b0c1e67
Merge remote-tracking branch 'upstream/main' into f-route_table_for_f…
awsaxeman Oct 12, 2021
34460ea
Merge branch 'hashicorp:main' into f-route_table_for_fsx_ontap_routes
awsaxeman Oct 12, 2021
50c946d
ignore cross account ENIs and FSx Tag
awsaxeman Oct 12, 2021
e57cb05
added change log
awsaxeman Oct 13, 2021
5869f47
Merge branch 'hashicorp:main' into f-route_table_for_fsx_ontap_routes
awsaxeman Oct 13, 2021
5a837fe
Merge branch 'f-route_table_for_fsx_ontap_routes' of https://github.c…
awsaxeman Oct 13, 2021
970b3f2
added changelog
awsaxeman Oct 13, 2021
1abdf63
added test for FSx route update
awsaxeman Oct 16, 2021
39389cf
resolve conflict
awsaxeman Oct 16, 2021
3c8c3d3
ignore cross account ENIs and FSx Tag updated to new schema
awsaxeman Oct 17, 2021
9a1af6a
Merge branch 'hashicorp:main' into f-route_table_for_fsx_ontap_routes
awsaxeman Oct 22, 2021
441d254
update FSx tag using Ignore
awsaxeman Oct 22, 2021
1735ce5
Return NotFoundErrors from FindNetworkInterfaceByID/FindNetworkInterf…
ewbankkit Oct 26, 2021
627c4b9
Use 'FindNetworkInterfaceByID' when skipping cross-account ENIs for A…
ewbankkit Oct 26, 2021
133ff03
Remove FSx ONTAP route tests from aws_route_table. Rely on aws_fsx_on…
ewbankkit Oct 26, 2021
1d36b91
r/aws_fsx_ontap_file_system: Test aws_route_table cross-account ENI l…
ewbankkit Oct 26, 2021
c81688d
r/aws_network_interface: Alphabetize attributes.
ewbankkit Oct 26, 2021
82bfdfb
Tweak CHANGELOG entry.
ewbankkit Oct 26, 2021
54b24fe
r/aws_network_interface: Add 'arn' and 'owner_id` attributes.
ewbankkit Oct 26, 2021
cb30abe
r/aws_network_interface: Move wait functionality.
ewbankkit Oct 27, 2021
4cdfe3e
r/aws_network_interface: Retry Read for new resource.
ewbankkit Oct 27, 2021
5124341
r/aws_network_interface: Start to consolidate attach/detach code.
ewbankkit Oct 27, 2021
47f7938
r/aws_network_interface_attachment: Use consolidated attach/detach code.
ewbankkit Nov 2, 2021
8f8b316
Add constants for network interface attach/detach timeouts.
ewbankkit Nov 2, 2021
a1735a9
r/aws_network_interface_sg_attachment: Simplify.
ewbankkit Nov 2, 2021
5ab1e7e
d/aws_network_interface: Use 'FindNetworkInterface'."
ewbankkit Nov 2, 2021
acc3281
d/aws_network_interfaces: Use pagination.
ewbankkit Nov 2, 2021
daa7b8e
r/aws_network_interface: Better error messages.
ewbankkit Nov 2, 2021
3e2f231
r/aws_network_interface: Add 'ipv4_prefix', 'ipv4_prefix_count', 'ipv…
ewbankkit Nov 2, 2021
52e7b77
r/aws_network_interface: 'ipv4_prefix' -> 'ipv4_prefixes' (and the sa…
ewbankkit Nov 2, 2021
aca0e4f
r/aws_network_interface: If IPv4 or IPv6 prefixes are specified, tag …
ewbankkit Nov 2, 2021
7401346
r/aws_network_interface: Tidy up some flex.
ewbankkit Nov 2, 2021
2d84e21
Merge branch 'main' into HEAD
ewbankkit Nov 2, 2021
787bf3a
Fix terrafmt errors.
ewbankkit Nov 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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