Skip to content

Commit b04bed6

Browse files
Use PrivateDnsName as Node name in nodeadm (#1715)
1 parent 8dab7ec commit b04bed6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+299
-28222
lines changed

nodeadm/cmd/nodeadm/init/init.go

+11-56
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package init
22

33
import (
44
"context"
5-
"encoding/base64"
6-
"fmt"
75

6+
"github.com/aws/aws-sdk-go-v2/aws"
7+
"github.com/aws/aws-sdk-go-v2/config"
88
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
9-
"github.com/aws/aws-sdk-go/service/eks"
9+
"github.com/aws/aws-sdk-go-v2/service/ec2"
1010
"github.com/integrii/flaggy"
1111
"go.uber.org/zap"
1212
"k8s.io/utils/strings/slices"
@@ -145,7 +145,14 @@ func (c *initCmd) Run(log *zap.Logger, opts *cli.GlobalOptions) error {
145145
// perform in-place updates when allowed by the user
146146
func enrichConfig(log *zap.Logger, cfg *api.NodeConfig) error {
147147
log.Info("Fetching instance details..")
148-
instanceDetails, err := api.GetIMDSInstanceDetails(context.TODO(), imds.New(imds.Options{}))
148+
imdsClient := imds.New(imds.Options{})
149+
awsConfig, err := config.LoadDefaultConfig(context.TODO(), config.WithClientLogMode(aws.LogRetries), config.WithEC2IMDSRegion(func(o *config.UseEC2IMDSRegion) {
150+
o.Client = imdsClient
151+
}))
152+
if err != nil {
153+
return err
154+
}
155+
instanceDetails, err := api.GetInstanceDetails(context.TODO(), imdsClient, ec2.NewFromConfig(awsConfig))
149156
if err != nil {
150157
return err
151158
}
@@ -162,55 +169,3 @@ func enrichConfig(log *zap.Logger, cfg *api.NodeConfig) error {
162169
log.Info("Default options populated", zap.Reflect("defaults", cfg.Status.Defaults))
163170
return nil
164171
}
165-
166-
// Discovers all cluster details using a describe call to the eks endpoint and
167-
// updates the value of the config's `ClusterDetails` in-place
168-
func populateClusterDetails(eksClient *eks.EKS, clusterName string, cfg *api.NodeConfig) error {
169-
if err := eksClient.WaitUntilClusterActive(&eks.DescribeClusterInput{Name: &clusterName}); err != nil {
170-
return err
171-
}
172-
describeResponse, err := eksClient.DescribeCluster(&eks.DescribeClusterInput{Name: &clusterName})
173-
if err != nil {
174-
return err
175-
}
176-
177-
ipFamily := *describeResponse.Cluster.KubernetesNetworkConfig.IpFamily
178-
179-
var cidr string
180-
if ipFamily == eks.IpFamilyIpv4 {
181-
cidr = *describeResponse.Cluster.KubernetesNetworkConfig.ServiceIpv4Cidr
182-
} else if ipFamily == eks.IpFamilyIpv6 {
183-
cidr = *describeResponse.Cluster.KubernetesNetworkConfig.ServiceIpv6Cidr
184-
} else {
185-
return fmt.Errorf("bad ipFamily: %s", ipFamily)
186-
}
187-
188-
isOutpost := false
189-
clusterId := cfg.Spec.Cluster.ID
190-
// detect whether the cluster is an aws outpost cluster depending on whether
191-
// the response contains the outpost ID
192-
if outpostId := describeResponse.Cluster.Id; outpostId != nil {
193-
clusterId = *outpostId
194-
isOutpost = true
195-
}
196-
197-
enableOutpost := isOutpost
198-
// respect the user override for enabling the outpost
199-
if enabled := cfg.Spec.Cluster.EnableOutpost; enabled != nil {
200-
enableOutpost = *enabled
201-
}
202-
203-
caCert, err := base64.StdEncoding.DecodeString(*describeResponse.Cluster.CertificateAuthority.Data)
204-
if err != nil {
205-
return err
206-
}
207-
208-
cfg.Spec.Cluster.Name = *describeResponse.Cluster.Name
209-
cfg.Spec.Cluster.APIServerEndpoint = *describeResponse.Cluster.Endpoint
210-
cfg.Spec.Cluster.CertificateAuthority = caCert
211-
cfg.Spec.Cluster.CIDR = cidr
212-
cfg.Spec.Cluster.EnableOutpost = &enableOutpost
213-
cfg.Spec.Cluster.ID = clusterId
214-
215-
return nil
216-
}

nodeadm/go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ require (
3434
require dario.cat/mergo v1.0.0 // direct
3535

3636
require (
37-
github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
37+
github.com/aws/aws-sdk-go-v2 v1.24.1
3838
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect
3939
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
4040
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
@@ -54,7 +54,7 @@ require (
5454
github.com/google/go-cmp v0.6.0 // indirect
5555
github.com/google/gofuzz v1.2.0 // indirect
5656
github.com/inconshreveable/mousetrap v1.1.0 // indirect
57-
github.com/jmespath/go-jmespath v0.4.0 // indirect
57+
github.com/jmespath/go-jmespath v0.4.0
5858
github.com/json-iterator/go v1.1.12 // indirect
5959
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
6060
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect

nodeadm/internal/api/net.go

-32
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,11 @@
11
package api
22

33
import (
4-
"context"
54
"fmt"
6-
"io"
75
"net"
86
"strings"
9-
10-
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
117
)
128

13-
// Fetch information about the ec2 instance using IMDS data.
14-
// This information is stored into the internal config to avoid redundant calls
15-
// to IMDS when looking for instance metadata
16-
func GetIMDSInstanceDetails(ctx context.Context, imdsClient *imds.Client) (*InstanceDetails, error) {
17-
instanceIdenitityDocument, err := imdsClient.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
18-
if err != nil {
19-
return nil, err
20-
}
21-
22-
macResponse, err := imdsClient.GetMetadata(ctx, &imds.GetMetadataInput{Path: "mac"})
23-
if err != nil {
24-
return nil, err
25-
}
26-
mac, err := io.ReadAll(macResponse.Content)
27-
if err != nil {
28-
return nil, err
29-
}
30-
31-
instanceDetails := InstanceDetails{
32-
ID: instanceIdenitityDocument.InstanceID,
33-
Region: instanceIdenitityDocument.Region,
34-
Type: instanceIdenitityDocument.InstanceType,
35-
AvailabilityZone: instanceIdenitityDocument.AvailabilityZone,
36-
MAC: string(mac),
37-
}
38-
return &instanceDetails, nil
39-
}
40-
419
// Derive the default ClusterIP of the kube-dns service from EKS built-in CoreDNS addon
4210
func (details *ClusterDetails) GetClusterDns() (string, error) {
4311
ipFamily, err := GetCIDRIpFamily(details.CIDR)

nodeadm/internal/api/status.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package api
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
"time"
8+
9+
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
10+
"github.com/aws/aws-sdk-go-v2/service/ec2"
11+
"github.com/aws/aws-sdk-go/aws"
12+
ec2extra "github.com/awslabs/amazon-eks-ami/nodeadm/internal/aws/ec2"
13+
)
14+
15+
// Fetch information about the ec2 instance using IMDS data.
16+
// This information is stored into the internal config to avoid redundant calls
17+
// to IMDS when looking for instance metadata
18+
func GetInstanceDetails(ctx context.Context, imdsClient *imds.Client, ec2Client *ec2.Client) (*InstanceDetails, error) {
19+
instanceIdenitityDocument, err := imdsClient.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
macResponse, err := imdsClient.GetMetadata(ctx, &imds.GetMetadataInput{Path: "mac"})
25+
if err != nil {
26+
return nil, err
27+
}
28+
mac, err := io.ReadAll(macResponse.Content)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
privateDNSName, err := getPrivateDNSName(ec2Client, instanceIdenitityDocument.InstanceID)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
return &InstanceDetails{
39+
ID: instanceIdenitityDocument.InstanceID,
40+
Region: instanceIdenitityDocument.Region,
41+
Type: instanceIdenitityDocument.InstanceType,
42+
AvailabilityZone: instanceIdenitityDocument.AvailabilityZone,
43+
MAC: string(mac),
44+
PrivateDNSName: privateDNSName,
45+
}, nil
46+
}
47+
48+
const privateDNSNameAvailableTimeout = 3 * time.Minute
49+
50+
// GetPrivateDNSName returns this instance's private DNS name as reported by the EC2 API, waiting until it's available if necessary.
51+
func getPrivateDNSName(ec2Client *ec2.Client, instanceID string) (string, error) {
52+
w := ec2extra.NewInstanceConditionWaiter(ec2Client, privateDNSNameAvailable, func(opts *ec2extra.InstanceConditionWaiterOptions) {
53+
opts.LogWaitAttempts = true
54+
})
55+
out, err := w.WaitForOutput(context.TODO(), &ec2.DescribeInstancesInput{InstanceIds: []string{instanceID}}, privateDNSNameAvailableTimeout)
56+
if err != nil {
57+
return "", err
58+
}
59+
privateDNSName := aws.StringValue(out.Reservations[0].Instances[0].PrivateDnsName)
60+
return privateDNSName, nil
61+
}
62+
63+
func privateDNSNameAvailable(out *ec2.DescribeInstancesOutput) (bool, error) {
64+
if out == nil || len(out.Reservations) != 1 || len(out.Reservations[0].Instances) != 1 {
65+
return false, fmt.Errorf("reservation or instance not found")
66+
}
67+
return aws.StringValue(out.Reservations[0].Instances[0].PrivateDnsName) != "", nil
68+
}

nodeadm/internal/api/types.go

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type InstanceDetails struct {
4545
Type string `json:"type,omitempty"`
4646
AvailabilityZone string `json:"availabilityZone,omitempty"`
4747
MAC string `json:"mac,omitempty"`
48+
PrivateDNSName string `json:"privateDnsName,omitempty"`
4849
}
4950

5051
type DefaultOptions struct {

0 commit comments

Comments
 (0)