From 13469e3594615128d27f2203806d843e50fe87d8 Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Fri, 3 Dec 2021 13:24:48 -0800 Subject: [PATCH 1/2] plugin: add DNS names This adds DNS names to the output for host queries. Hosts are discovered in private, then public order, first at the top-level, and then through attached network interfaces. This mirrors the discovery order of IP addresses. --- plugin/plugin.go | 36 ++++++++++++++++++++++++++---------- plugin/plugin_test.go | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/plugin/plugin.go b/plugin/plugin.go index 1c897e8..04d76be 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -543,16 +543,22 @@ func awsInstanceToHost(instance *ec2.Instance) (*pb.ListHostsResponseHost, error // External ID is the instance ID. result.ExternalId = aws.StringValue(instance.InstanceId) - // First IP address is always the private IP address field if it's - // populated + // First IP address/dns name are always the private fields if they + // are populated if aws.StringValue(instance.PrivateIpAddress) != "" { result.IpAddresses = append(result.IpAddresses, aws.StringValue(instance.PrivateIpAddress)) } + if aws.StringValue(instance.PrivateDnsName) != "" { + result.DnsNames = append(result.DnsNames, aws.StringValue(instance.PrivateDnsName)) + } - // Public IP address is next. + // Public IP address/dns names are next if aws.StringValue(instance.PublicIpAddress) != "" { result.IpAddresses = append(result.IpAddresses, aws.StringValue(instance.PublicIpAddress)) } + if aws.StringValue(instance.PublicDnsName) != "" { + result.DnsNames = append(result.DnsNames, aws.StringValue(instance.PublicDnsName)) + } // Now go through all of the interfaces and log the IP address of // every interface. @@ -569,22 +575,32 @@ func awsInstanceToHost(instance *ec2.Instance) (*pb.ListHostsResponseHost, error return nil, errors.New("response integrity error: interface address entry is nil") } - // Check to see if the PrivateIpAddress matches the one - // reported at the top-level of the instance (let's call it the - // "default address"). If it doesn't, add it. + // Check to see if the PrivateIpAddress/PrivateDnsName fields + // match the ones reported at the top-level of the instance. + // If they don't, add them. if aws.StringValue(addr.PrivateIpAddress) != "" { if aws.StringValue(instance.PrivateIpAddress) != aws.StringValue(addr.PrivateIpAddress) { result.IpAddresses = append(result.IpAddresses, aws.StringValue(addr.PrivateIpAddress)) } } + if aws.StringValue(addr.PrivateDnsName) != "" { + if aws.StringValue(instance.PrivateDnsName) != aws.StringValue(addr.PrivateDnsName) { + result.DnsNames = append(result.DnsNames, aws.StringValue(addr.PrivateDnsName)) + } + } - // Do the same for the default public IP address and the - // public association on the interface. - if addr.Association != nil && addr.Association.PublicIp != nil && aws.StringValue(addr.Association.PublicIp) != "" { - if instance.PublicIpAddress != nil && aws.StringValue(instance.PublicIpAddress) != aws.StringValue(addr.Association.PublicIp) { + // Do the same for the top-level public IP address/DNS name and + // the public association on the interface. + if addr.Association != nil && aws.StringValue(addr.Association.PublicIp) != "" { + if aws.StringValue(instance.PublicIpAddress) != aws.StringValue(addr.Association.PublicIp) { result.IpAddresses = append(result.IpAddresses, aws.StringValue(addr.Association.PublicIp)) } } + if addr.Association != nil && aws.StringValue(addr.Association.PublicDnsName) != "" { + if aws.StringValue(instance.PublicDnsName) != aws.StringValue(addr.Association.PublicDnsName) { + result.DnsNames = append(result.DnsNames, aws.StringValue(addr.Association.PublicDnsName)) + } + } } // Add the IPv6 addresses. diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index 961aa8d..b0201a6 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -1380,15 +1380,19 @@ func TestAwsInstanceToHost(t *testing.T) { instance: &ec2.Instance{ InstanceId: aws.String("foobar"), PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PublicIpAddress: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ - PublicIp: aws.String("1.1.1.1"), + PublicIp: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), }, PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), }, }, }, @@ -1397,6 +1401,7 @@ func TestAwsInstanceToHost(t *testing.T) { expected: &pb.ListHostsResponseHost{ ExternalId: "foobar", IpAddresses: []string{"10.0.0.1", "1.1.1.1"}, + DnsNames: []string{"test.example.internal", "test.example.com"}, }, }, { @@ -1404,11 +1409,13 @@ func TestAwsInstanceToHost(t *testing.T) { instance: &ec2.Instance{ InstanceId: aws.String("foobar"), PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), }, }, }, @@ -1417,6 +1424,7 @@ func TestAwsInstanceToHost(t *testing.T) { expected: &pb.ListHostsResponseHost{ ExternalId: "foobar", IpAddresses: []string{"10.0.0.1"}, + DnsNames: []string{"test.example.internal"}, }, }, { @@ -1424,12 +1432,15 @@ func TestAwsInstanceToHost(t *testing.T) { instance: &ec2.Instance{ InstanceId: aws.String("foobar"), PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PublicIpAddress: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ PrivateIpAddress: aws.String("10.0.0.2"), + PrivateDnsName: aws.String("test2.example.internal"), }, }, }, @@ -1437,9 +1448,11 @@ func TestAwsInstanceToHost(t *testing.T) { PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ - PublicIp: aws.String("1.1.1.1"), + PublicIp: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), }, PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), }, }, }, @@ -1448,6 +1461,7 @@ func TestAwsInstanceToHost(t *testing.T) { expected: &pb.ListHostsResponseHost{ ExternalId: "foobar", IpAddresses: []string{"10.0.0.1", "1.1.1.1", "10.0.0.2"}, + DnsNames: []string{"test.example.internal", "test.example.com", "test2.example.internal"}, }, }, { @@ -1455,15 +1469,19 @@ func TestAwsInstanceToHost(t *testing.T) { instance: &ec2.Instance{ InstanceId: aws.String("foobar"), PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PublicIpAddress: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ - PublicIp: aws.String("1.1.1.2"), + PublicIp: aws.String("1.1.1.2"), + PublicDnsName: aws.String("test2.example.com"), }, PrivateIpAddress: aws.String("10.0.0.2"), + PrivateDnsName: aws.String("test2.example.internal"), }, }, }, @@ -1471,9 +1489,11 @@ func TestAwsInstanceToHost(t *testing.T) { PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ - PublicIp: aws.String("1.1.1.1"), + PublicIp: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), }, PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), }, }, }, @@ -1482,6 +1502,7 @@ func TestAwsInstanceToHost(t *testing.T) { expected: &pb.ListHostsResponseHost{ ExternalId: "foobar", IpAddresses: []string{"10.0.0.1", "1.1.1.1", "10.0.0.2", "1.1.1.2"}, + DnsNames: []string{"test.example.internal", "test.example.com", "test2.example.internal", "test2.example.com"}, }, }, { @@ -1489,18 +1510,23 @@ func TestAwsInstanceToHost(t *testing.T) { instance: &ec2.Instance{ InstanceId: aws.String("foobar"), PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PublicIpAddress: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ - PublicIp: aws.String("1.1.1.1"), + PublicIp: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), }, PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), }, &ec2.InstancePrivateIpAddress{ PrivateIpAddress: aws.String("10.0.0.2"), + PrivateDnsName: aws.String("test2.example.internal"), }, }, }, @@ -1509,6 +1535,7 @@ func TestAwsInstanceToHost(t *testing.T) { expected: &pb.ListHostsResponseHost{ ExternalId: "foobar", IpAddresses: []string{"10.0.0.1", "1.1.1.1", "10.0.0.2"}, + DnsNames: []string{"test.example.internal", "test.example.com", "test2.example.internal"}, }, }, { @@ -1516,7 +1543,9 @@ func TestAwsInstanceToHost(t *testing.T) { instance: &ec2.Instance{ InstanceId: aws.String("foobar"), PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PublicIpAddress: aws.String("1.1.1.1"), + PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ @@ -1537,6 +1566,7 @@ func TestAwsInstanceToHost(t *testing.T) { expected: &pb.ListHostsResponseHost{ ExternalId: "foobar", IpAddresses: []string{"10.0.0.1", "1.1.1.1", "some::fake::address"}, + DnsNames: []string{"test.example.internal", "test.example.com"}, }, }, } From 7a07ac42c073ef9efaf6dd7f5e8c674453990409 Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Mon, 6 Dec 2021 11:40:44 -0800 Subject: [PATCH 2/2] add default address/DNS check/add for interface, not just whole instance --- plugin/plugin.go | 50 +++++++++++++++++++++++++------------------ plugin/plugin_test.go | 15 +++++++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/plugin/plugin.go b/plugin/plugin.go index 04d76be..f484c8e 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -568,6 +568,15 @@ func awsInstanceToHost(instance *ec2.Instance) (*pb.ListHostsResponseHost, error return nil, errors.New("response integrity error: interface entry is nil") } + // Populate default IP addresses/DNS name similar to how we do + // for the entire instance. + if aws.StringValue(iface.PrivateIpAddress) != "" && !stringInSlice(result.IpAddresses, aws.StringValue(iface.PrivateIpAddress)) { + result.IpAddresses = append(result.IpAddresses, aws.StringValue(iface.PrivateIpAddress)) + } + if aws.StringValue(iface.PrivateDnsName) != "" && !stringInSlice(result.DnsNames, aws.StringValue(iface.PrivateDnsName)) { + result.DnsNames = append(result.DnsNames, aws.StringValue(iface.PrivateDnsName)) + } + // Iterate through the private IP addresses and log the // information. for _, addr := range iface.PrivateIpAddresses { @@ -575,31 +584,20 @@ func awsInstanceToHost(instance *ec2.Instance) (*pb.ListHostsResponseHost, error return nil, errors.New("response integrity error: interface address entry is nil") } - // Check to see if the PrivateIpAddress/PrivateDnsName fields - // match the ones reported at the top-level of the instance. - // If they don't, add them. - if aws.StringValue(addr.PrivateIpAddress) != "" { - if aws.StringValue(instance.PrivateIpAddress) != aws.StringValue(addr.PrivateIpAddress) { - result.IpAddresses = append(result.IpAddresses, aws.StringValue(addr.PrivateIpAddress)) - } + // Add private address/dns name if they have not been added yet + if aws.StringValue(addr.PrivateIpAddress) != "" && !stringInSlice(result.IpAddresses, aws.StringValue(addr.PrivateIpAddress)) { + result.IpAddresses = append(result.IpAddresses, aws.StringValue(addr.PrivateIpAddress)) } - if aws.StringValue(addr.PrivateDnsName) != "" { - if aws.StringValue(instance.PrivateDnsName) != aws.StringValue(addr.PrivateDnsName) { - result.DnsNames = append(result.DnsNames, aws.StringValue(addr.PrivateDnsName)) - } + if aws.StringValue(addr.PrivateDnsName) != "" && !stringInSlice(result.DnsNames, aws.StringValue(addr.PrivateDnsName)) { + result.DnsNames = append(result.DnsNames, aws.StringValue(addr.PrivateDnsName)) } - // Do the same for the top-level public IP address/DNS name and - // the public association on the interface. - if addr.Association != nil && aws.StringValue(addr.Association.PublicIp) != "" { - if aws.StringValue(instance.PublicIpAddress) != aws.StringValue(addr.Association.PublicIp) { - result.IpAddresses = append(result.IpAddresses, aws.StringValue(addr.Association.PublicIp)) - } + // Add public address/dns name if they have not been added yet + if addr.Association != nil && aws.StringValue(addr.Association.PublicIp) != "" && !stringInSlice(result.IpAddresses, aws.StringValue(addr.Association.PublicIp)) { + result.IpAddresses = append(result.IpAddresses, aws.StringValue(addr.Association.PublicIp)) } - if addr.Association != nil && aws.StringValue(addr.Association.PublicDnsName) != "" { - if aws.StringValue(instance.PublicDnsName) != aws.StringValue(addr.Association.PublicDnsName) { - result.DnsNames = append(result.DnsNames, aws.StringValue(addr.Association.PublicDnsName)) - } + if addr.Association != nil && aws.StringValue(addr.Association.PublicDnsName) != "" && !stringInSlice(result.DnsNames, aws.StringValue(addr.Association.PublicDnsName)) { + result.DnsNames = append(result.DnsNames, aws.StringValue(addr.Association.PublicDnsName)) } } @@ -618,3 +616,13 @@ func awsInstanceToHost(instance *ec2.Instance) (*pb.ListHostsResponseHost, error // Done return result, nil } + +func stringInSlice(s []string, x string) bool { + for _, y := range s { + if x == y { + return true + } + } + + return false +} diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index b0201a6..8fee701 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -1385,6 +1385,8 @@ func TestAwsInstanceToHost(t *testing.T) { PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ @@ -1412,6 +1414,8 @@ func TestAwsInstanceToHost(t *testing.T) { PrivateDnsName: aws.String("test.example.internal"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ PrivateIpAddress: aws.String("10.0.0.1"), @@ -1437,6 +1441,8 @@ func TestAwsInstanceToHost(t *testing.T) { PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.2"), + PrivateDnsName: aws.String("test2.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ PrivateIpAddress: aws.String("10.0.0.2"), @@ -1445,6 +1451,8 @@ func TestAwsInstanceToHost(t *testing.T) { }, }, &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ @@ -1474,6 +1482,8 @@ func TestAwsInstanceToHost(t *testing.T) { PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.2"), + PrivateDnsName: aws.String("test2.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ @@ -1486,6 +1496,8 @@ func TestAwsInstanceToHost(t *testing.T) { }, }, &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ @@ -1515,6 +1527,8 @@ func TestAwsInstanceToHost(t *testing.T) { PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.1"), + PrivateDnsName: aws.String("test.example.internal"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{ @@ -1548,6 +1562,7 @@ func TestAwsInstanceToHost(t *testing.T) { PublicDnsName: aws.String("test.example.com"), NetworkInterfaces: []*ec2.InstanceNetworkInterface{ &ec2.InstanceNetworkInterface{ + PrivateIpAddress: aws.String("10.0.0.1"), PrivateIpAddresses: []*ec2.InstancePrivateIpAddress{ &ec2.InstancePrivateIpAddress{ Association: &ec2.InstanceNetworkInterfaceAssociation{