Skip to content

Commit

Permalink
Use PrivateDnsName as Node name in nodeadm
Browse files Browse the repository at this point in the history
  • Loading branch information
cartermckinnon committed Mar 12, 2024
1 parent 7d215b2 commit 5395fb9
Show file tree
Hide file tree
Showing 83 changed files with 299 additions and 28,222 deletions.
67 changes: 11 additions & 56 deletions nodeadm/cmd/nodeadm/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package init

import (
"context"
"encoding/base64"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go/service/eks"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/integrii/flaggy"
"go.uber.org/zap"
"k8s.io/utils/strings/slices"
Expand Down Expand Up @@ -145,7 +145,14 @@ func (c *initCmd) Run(log *zap.Logger, opts *cli.GlobalOptions) error {
// perform in-place updates when allowed by the user
func enrichConfig(log *zap.Logger, cfg *api.NodeConfig) error {
log.Info("Fetching instance details..")
instanceDetails, err := api.GetIMDSInstanceDetails(context.TODO(), imds.New(imds.Options{}))
imdsClient := imds.New(imds.Options{})
awsConfig, err := config.LoadDefaultConfig(context.TODO(), config.WithClientLogMode(aws.LogRetries), config.WithEC2IMDSRegion(func(o *config.UseEC2IMDSRegion) {
o.Client = imdsClient
}))
if err != nil {
return err
}
instanceDetails, err := api.GetInstanceDetails(context.TODO(), imdsClient, ec2.NewFromConfig(awsConfig))
if err != nil {
return err
}
Expand All @@ -162,55 +169,3 @@ func enrichConfig(log *zap.Logger, cfg *api.NodeConfig) error {
log.Info("Default options populated", zap.Reflect("defaults", cfg.Status.Defaults))
return nil
}

// Discovers all cluster details using a describe call to the eks endpoint and
// updates the value of the config's `ClusterDetails` in-place
func populateClusterDetails(eksClient *eks.EKS, clusterName string, cfg *api.NodeConfig) error {
if err := eksClient.WaitUntilClusterActive(&eks.DescribeClusterInput{Name: &clusterName}); err != nil {
return err
}
describeResponse, err := eksClient.DescribeCluster(&eks.DescribeClusterInput{Name: &clusterName})
if err != nil {
return err
}

ipFamily := *describeResponse.Cluster.KubernetesNetworkConfig.IpFamily

var cidr string
if ipFamily == eks.IpFamilyIpv4 {
cidr = *describeResponse.Cluster.KubernetesNetworkConfig.ServiceIpv4Cidr
} else if ipFamily == eks.IpFamilyIpv6 {
cidr = *describeResponse.Cluster.KubernetesNetworkConfig.ServiceIpv6Cidr
} else {
return fmt.Errorf("bad ipFamily: %s", ipFamily)
}

isOutpost := false
clusterId := cfg.Spec.Cluster.ID
// detect whether the cluster is an aws outpost cluster depending on whether
// the response contains the outpost ID
if outpostId := describeResponse.Cluster.Id; outpostId != nil {
clusterId = *outpostId
isOutpost = true
}

enableOutpost := isOutpost
// respect the user override for enabling the outpost
if enabled := cfg.Spec.Cluster.EnableOutpost; enabled != nil {
enableOutpost = *enabled
}

caCert, err := base64.StdEncoding.DecodeString(*describeResponse.Cluster.CertificateAuthority.Data)
if err != nil {
return err
}

cfg.Spec.Cluster.Name = *describeResponse.Cluster.Name
cfg.Spec.Cluster.APIServerEndpoint = *describeResponse.Cluster.Endpoint
cfg.Spec.Cluster.CertificateAuthority = caCert
cfg.Spec.Cluster.CIDR = cidr
cfg.Spec.Cluster.EnableOutpost = &enableOutpost
cfg.Spec.Cluster.ID = clusterId

return nil
}
4 changes: 2 additions & 2 deletions nodeadm/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require (
require dario.cat/mergo v1.0.0 // direct

require (
github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.24.1
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
Expand All @@ -54,7 +54,7 @@ require (
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmespath/go-jmespath v0.4.0
github.com/json-iterator/go v1.1.12 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand Down
32 changes: 0 additions & 32 deletions nodeadm/internal/api/net.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,11 @@
package api

import (
"context"
"fmt"
"io"
"net"
"strings"

"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
)

// Fetch information about the ec2 instance using IMDS data.
// This information is stored into the internal config to avoid redundant calls
// to IMDS when looking for instance metadata
func GetIMDSInstanceDetails(ctx context.Context, imdsClient *imds.Client) (*InstanceDetails, error) {
instanceIdenitityDocument, err := imdsClient.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
if err != nil {
return nil, err
}

macResponse, err := imdsClient.GetMetadata(ctx, &imds.GetMetadataInput{Path: "mac"})
if err != nil {
return nil, err
}
mac, err := io.ReadAll(macResponse.Content)
if err != nil {
return nil, err
}

instanceDetails := InstanceDetails{
ID: instanceIdenitityDocument.InstanceID,
Region: instanceIdenitityDocument.Region,
Type: instanceIdenitityDocument.InstanceType,
AvailabilityZone: instanceIdenitityDocument.AvailabilityZone,
MAC: string(mac),
}
return &instanceDetails, nil
}

// Derive the default ClusterIP of the kube-dns service from EKS built-in CoreDNS addon
func (details *ClusterDetails) GetClusterDns() (string, error) {
ipFamily, err := GetCIDRIpFamily(details.CIDR)
Expand Down
68 changes: 68 additions & 0 deletions nodeadm/internal/api/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package api

import (
"context"
"fmt"
"io"
"time"

"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go/aws"
ec2extra "github.com/awslabs/amazon-eks-ami/nodeadm/internal/aws/ec2"
)

// Fetch information about the ec2 instance using IMDS data.
// This information is stored into the internal config to avoid redundant calls
// to IMDS when looking for instance metadata
func GetInstanceDetails(ctx context.Context, imdsClient *imds.Client, ec2Client *ec2.Client) (*InstanceDetails, error) {
instanceIdenitityDocument, err := imdsClient.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
if err != nil {
return nil, err
}

macResponse, err := imdsClient.GetMetadata(ctx, &imds.GetMetadataInput{Path: "mac"})
if err != nil {
return nil, err
}
mac, err := io.ReadAll(macResponse.Content)
if err != nil {
return nil, err
}

privateDNSName, err := getPrivateDNSName(ec2Client, instanceIdenitityDocument.InstanceID)
if err != nil {
return nil, err
}

return &InstanceDetails{
ID: instanceIdenitityDocument.InstanceID,
Region: instanceIdenitityDocument.Region,
Type: instanceIdenitityDocument.InstanceType,
AvailabilityZone: instanceIdenitityDocument.AvailabilityZone,
MAC: string(mac),
PrivateDNSName: privateDNSName,
}, nil
}

const privateDNSNameAvailableTimeout = 3 * time.Minute

// GetPrivateDNSName returns this instance's private DNS name as reported by the EC2 API, waiting until it's available if necessary.
func getPrivateDNSName(ec2Client *ec2.Client, instanceID string) (string, error) {
w := ec2extra.NewInstanceConditionWaiter(ec2Client, privateDNSNameAvailable, func(opts *ec2extra.InstanceConditionWaiterOptions) {
opts.LogWaitAttempts = true
})
out, err := w.WaitForOutput(context.TODO(), &ec2.DescribeInstancesInput{InstanceIds: []string{instanceID}}, privateDNSNameAvailableTimeout)
if err != nil {
return "", err
}
privateDNSName := aws.StringValue(out.Reservations[0].Instances[0].PrivateDnsName)
return privateDNSName, nil
}

func privateDNSNameAvailable(out *ec2.DescribeInstancesOutput) (bool, error) {
if out == nil || len(out.Reservations) != 1 || len(out.Reservations[0].Instances) != 1 {
return false, fmt.Errorf("reservation or instance not found")
}
return aws.StringValue(out.Reservations[0].Instances[0].PrivateDnsName) != "", nil
}
1 change: 1 addition & 0 deletions nodeadm/internal/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type InstanceDetails struct {
Type string `json:"type,omitempty"`
AvailabilityZone string `json:"availabilityZone,omitempty"`
MAC string `json:"mac,omitempty"`
PrivateDNSName string `json:"privateDnsName,omitempty"`
}

type DefaultOptions struct {
Expand Down
Loading

0 comments on commit 5395fb9

Please sign in to comment.