Skip to content

Commit

Permalink
New Datasource: aws_network_interface (hashicorp#2316)
Browse files Browse the repository at this point in the history
* New Datasource: aws_network_interface

* Reflect reviews
  • Loading branch information
atsushi-ishibashi authored and mdlavin committed Dec 9, 2017
1 parent 774b76f commit 493f059
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 0 deletions.
174 changes: 174 additions & 0 deletions aws/data_source_aws_network_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package aws

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceAwsNetworkInterface() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsNetworkInterfaceRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Required: true,
},
"association": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"allocation_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"association_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"ip_owner_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"public_dns_name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"public_ip": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
},
},
"attachment": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"attachment_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"device_index": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
},
"instance_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"instance_owner_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
},
},
"availability_zone": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"security_groups": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"interface_type": {
Type: schema.TypeString,
Computed: true,
},
"ipv6_addresses": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"mac_address": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"owner_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"private_dns_name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"private_ip": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"private_ips": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"requester_id": {
Type: schema.TypeString,
Computed: true,
},
"subnet_id": {
Type: schema.TypeString,
Computed: true,
},
"vpc_id": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsSchemaComputed(),
},
}
}

func dataSourceAwsNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

input := &ec2.DescribeNetworkInterfacesInput{
NetworkInterfaceIds: []*string{aws.String(d.Get("id").(string))},
}

resp, err := conn.DescribeNetworkInterfaces(input)
if err != nil {
return err
}
if resp == nil || len(resp.NetworkInterfaces) == 0 {
return fmt.Errorf("no matching network interface found")
}
if len(resp.NetworkInterfaces) > 1 {
return fmt.Errorf("multiple network interfaces matched %s", d.Id())
}

eni := resp.NetworkInterfaces[0]

d.SetId(*eni.NetworkInterfaceId)
if eni.Association != nil {
d.Set("association", flattenEc2NetworkInterfaceAssociation(eni.Association))
}
if eni.Attachment != nil {
attachment := []interface{}{flattenAttachment(eni.Attachment)}
d.Set("attachment", attachment)
}
d.Set("availability_zone", eni.AvailabilityZone)
d.Set("description", eni.Description)
d.Set("security_groups", flattenGroupIdentifiers(eni.Groups))
d.Set("interface_type", eni.InterfaceType)
d.Set("ipv6_addresses", flattenEc2NetworkInterfaceIpv6Address(eni.Ipv6Addresses))
d.Set("mac_address", eni.MacAddress)
d.Set("owner_id", eni.OwnerId)
d.Set("private_dns_name", eni.PrivateDnsName)
d.Set("private_id", eni.PrivateIpAddress)
d.Set("private_ips", flattenNetworkInterfacesPrivateIPAddresses(eni.PrivateIpAddresses))
d.Set("requester_id", eni.RequesterId)
d.Set("subnet_id", eni.SubnetId)
d.Set("vpc_id", eni.VpcId)
d.Set("tags", tagsToMap(eni.TagSet))
return nil
}
57 changes: 57 additions & 0 deletions aws/data_source_aws_network_interface_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAwsNetworkInterface_basic(t *testing.T) {
rName := acctest.RandString(5)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAwsNetworkInterface_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.aws_network_interface.test", "private_ips.#", "1"),
resource.TestCheckResourceAttr("data.aws_network_interface.test", "security_groups.#", "1"),
),
},
},
})
}

func testAccDataSourceAwsNetworkInterface_basic(rName string) string {
return fmt.Sprintf(`
data "aws_availability_zones" "available" {}
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "test" {
cidr_block = "10.0.0.0/24"
availability_zone = "${data.aws_availability_zones.available.names[0]}"
vpc_id = "${aws_vpc.test.id}"
}
resource "aws_security_group" "test" {
name = "tf-sg-%s"
vpc_id = "${aws_vpc.test.id}"
}
resource "aws_network_interface" "test" {
subnet_id = "${aws_subnet.test.id}"
private_ips = ["10.0.0.50"]
security_groups = ["${aws_security_group.test.id}"]
}
data "aws_network_interface" "test" {
id = "${aws_network_interface.test.id}"
}
`, rName)
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func Provider() terraform.ResourceProvider {
"aws_kms_ciphertext": dataSourceAwsKmsCiphertext(),
"aws_kms_secret": dataSourceAwsKmsSecret(),
"aws_nat_gateway": dataSourceAwsNatGateway(),
"aws_network_interface": dataSourceAwsNetworkInterface(),
"aws_partition": dataSourceAwsPartition(),
"aws_prefix_list": dataSourceAwsPrefixList(),
"aws_rds_cluster": dataSourceAwsRdsCluster(),
Expand Down
28 changes: 28 additions & 0 deletions aws/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,34 @@ func flattenAttachment(a *ec2.NetworkInterfaceAttachment) map[string]interface{}
return att
}

func flattenEc2NetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) []interface{} {
att := make(map[string]interface{})
if a.AllocationId != nil {
att["allocation_id"] = *a.AllocationId
}
if a.AssociationId != nil {
att["association_id"] = *a.AssociationId
}
if a.IpOwnerId != nil {
att["ip_owner_id"] = *a.IpOwnerId
}
if a.PublicDnsName != nil {
att["public_dns_name"] = *a.PublicDnsName
}
if a.PublicIp != nil {
att["public_ip"] = *a.PublicIp
}
return []interface{}{att}
}

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

func flattenElastiCacheSecurityGroupNames(securityGroups []*elasticache.CacheSecurityGroupMembership) []string {
result := make([]string, 0, len(securityGroups))
for _, sg := range securityGroups {
Expand Down
4 changes: 4 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@
</li>
<li<%= sidebar_current("docs-aws-datasource-nat-gateway") %>>
<a href="/docs/providers/aws/d/nat_gateway.html">aws_nat_gateway</a>
</li>
<li<%= sidebar_current("docs-aws-datasource-network-interface") %>>
<a href="/docs/providers/aws/d/network_interface.html">aws_network_interface</a>
</li>
<li<%= sidebar_current("docs-aws-datasource-lb-x") %>>
<a href="/docs/providers/aws/d/lb.html">aws_lb</a>
</li>
Expand Down
47 changes: 47 additions & 0 deletions website/docs/d/network_interface.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
layout: "aws"
page_title: "AWS: aws_network_interface"
sidebar_current: "docs-aws-datasource-network-interface"
description: |-
Get information on a Network Interface resource.
---

# aws_network_interface

Use this data source to get information about a Network Interface.

## Example Usage

```hcl
data "aws_network_interface" "bar" {
id = "eni-01234567"
}
```

## Argument Reference

The following arguments are supported:

* `id` – (Required) The identifier for the network interface.

## Attributes Reference

See the [Network Interface](/docs/providers/aws/r/network_interface.html) for details on the returned attributes.

Additionally, the following attributes are exported:

* `association` - The association information for an Elastic IP address (IPv4) associated with the network interface. See supported fields below.
* `availability_zone` - The Availability Zone.
* `interface_type` - The type of interface.
* `ipv6_addresses` - List of IPv6 addresses to assign to the ENI.
* `mac_address` - The MAC address.
* `owner_id` - The AWS account ID of the owner of the network interface.
* `requester_id` - The ID of the entity that launched the instance on your behalf.

### `association`

* `allocation_id` - The allocation ID.
* `association_id` - The association ID.
* `ip_owner_id` - The ID of the Elastic IP address owner.
* `public_dns_name` - The public DNS name.
* `public_ip` - The address of the Elastic IP address bound to the network interface.

0 comments on commit 493f059

Please sign in to comment.