Add ssh user to kops toolbox dump

Where we can identify the SSH user to use, we can include it in kops
toolbox dump.  This is a precursor to trying to better understand
what's in an image (warnings about NVME or network drivers, or showing
the correct SSH username)
This commit is contained in:
Justin Santa Barbara 2018-07-24 17:17:21 -04:00
parent b36c67f81c
commit 5933aed899
3 changed files with 78 additions and 3 deletions

View File

@ -21,6 +21,7 @@ import (
"bytes"
"fmt"
"strings"
"sync"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling"
@ -417,6 +418,69 @@ func ListInstances(cloud fi.Cloud, clusterName string) ([]*resources.Resource, e
return resourceTrackers, nil
}
// getDumpState gets the dumpState from the dump context, or creates one if not yet initialized
func getDumpState(dumpContext *resources.DumpOperation) *dumpState {
if dumpContext.CloudState == nil {
dumpContext.CloudState = &dumpState{
cloud: dumpContext.Cloud.(awsup.AWSCloud),
}
}
return dumpContext.CloudState.(*dumpState)
}
type imageInfo struct {
SSHUser string
}
type dumpState struct {
cloud awsup.AWSCloud
mutex sync.Mutex
images map[string]*imageInfo
}
func (s *dumpState) getImageInfo(imageID string) (*imageInfo, error) {
s.mutex.Lock()
defer s.mutex.Unlock()
if s.images == nil {
s.images = make(map[string]*imageInfo)
}
info := s.images[imageID]
if info == nil {
image, err := s.cloud.ResolveImage(imageID)
if err != nil {
return nil, err
}
info = &imageInfo{}
if image != nil {
sshUser := guessSSHUser(image)
if sshUser == "" {
glog.Warningf("unable to guess SSH user for image: %+v", image)
}
info.SSHUser = sshUser
}
s.images[imageID] = info
}
return info, nil
}
func guessSSHUser(image *ec2.Image) string {
owner := aws.StringValue(image.OwnerId)
switch owner {
case awsup.WellKnownAccountAmazonSystemLinux2:
return "ec2-user"
case awsup.WellKnownAccountCoreOS:
return "core"
case awsup.WellKnownAccountKopeio:
return "admin"
}
return ""
}
func DumpInstance(op *resources.DumpOperation, r *resources.Resource) error {
data := make(map[string]interface{})
data["id"] = r.ID
@ -444,6 +508,15 @@ func DumpInstance(op *resources.DumpOperation, r *resources.Resource) error {
role := strings.TrimPrefix(key, awsup.TagNameRolePrefix)
i.Roles = append(i.Roles, role)
}
imageID := aws.StringValue(ec2Instance.ImageId)
imageInfo, err := getDumpState(op).getImageInfo(imageID)
if err != nil {
glog.Warningf("unable to fetch image %q: %v", imageID, err)
} else if imageInfo != nil {
i.SSHUser = imageInfo.SSHUser
}
op.Dump.Instances = append(op.Dump.Instances, i)
return nil

View File

@ -21,6 +21,7 @@ type Instance struct {
Name string `json:"name,omitempty"`
PublicAddresses []string `json:"publicAddresses,omitempty"`
Roles []string `json:"roles,omitempty"`
SSHUser string `json:"sshUser,omitempty"`
}
// Subnet is the type for an subnetwork in a dump

View File

@ -84,6 +84,7 @@ const (
WellKnownAccountKopeio = "383156758163"
WellKnownAccountRedhat = "309956199498"
WellKnownAccountCoreOS = "595879546273"
WellKnownAccountAmazonSystemLinux2 = "137112412989"
)
type AWSCloud interface {