Skip to content

Commit fe9f2f6

Browse files
authored
Merge pull request #17261 from justinsb/ssh_metal_test_oddity
Better dumping via private IP when bastion is not set
2 parents cfe8e62 + 3ea73f4 commit fe9f2f6

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

cmd/kops/toolbox_dump.go

+3
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ func RunToolboxDump(ctx context.Context, f commandutils.Factory, out io.Writer,
209209
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
210210
}
211211

212+
klog.Infof("will SSH using username %q", sshConfig.User)
213+
klog.Infof("ssh auth methods %v", sshConfig.Auth)
214+
212215
keyRing := agent.NewKeyring()
213216
defer func(keyRing agent.Agent) {
214217
_ = keyRing.RemoveAll()

pkg/dump/dumper.go

+25-5
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,12 @@ func (d *logDumper) dumpRegistered(ctx context.Context, node *corev1.Node) error
199199
if publicIP != "" {
200200
return d.dumpNode(ctx, node.Name, publicIP, false)
201201
} else {
202-
return d.dumpNode(ctx, node.Name, privateIP, true)
202+
useBastion := true
203+
if !d.sshClientFactory.HasBastion() {
204+
klog.Warningf("no bastion address set, will attempt to connect to node %s directly via private IP %v", node.Name, privateIP)
205+
useBastion = false
206+
}
207+
return d.dumpNode(ctx, node.Name, privateIP, useBastion)
203208
}
204209
}
205210

@@ -274,7 +279,12 @@ type sshClient interface {
274279

275280
// sshClientFactory is an interface abstracting to a node over SSH
276281
type sshClientFactory interface {
282+
// Dial creates a new sshClient
277283
Dial(ctx context.Context, host string, useBastion bool) (sshClient, error)
284+
285+
// HasBastion returns true if the sshClientFactory has a bastion configured.
286+
// Calling Dial with useBastion=true will return an error if there is no bastion.
287+
HasBastion() bool
278288
}
279289

280290
// logDumperNode holds state for a particular node we are dumping
@@ -540,21 +550,31 @@ type sshClientFactoryImplementation struct {
540550

541551
var _ sshClientFactory = &sshClientFactoryImplementation{}
542552

553+
// HasBastion implements sshClientFactory::HasBastion
554+
func (f *sshClientFactoryImplementation) HasBastion() bool {
555+
return f.bastion != ""
556+
}
557+
543558
// Dial implements sshClientFactory::Dial
544559
func (f *sshClientFactoryImplementation) Dial(ctx context.Context, host string, useBastion bool) (sshClient, error) {
545-
var addr string
560+
addr := host
546561
if useBastion {
562+
if f.bastion == "" {
563+
return nil, fmt.Errorf("bastion is not set, but useBastion is true")
564+
}
547565
addr = f.bastion
548-
} else {
549-
addr = host
566+
}
567+
568+
if addr == "" {
569+
return nil, fmt.Errorf("host is empty")
550570
}
551571
addr = net.JoinHostPort(addr, "22")
552572
d := net.Dialer{
553573
Timeout: 5 * time.Second,
554574
}
555575
conn, err := d.DialContext(ctx, "tcp", addr)
556576
if err != nil {
557-
return nil, err
577+
return nil, fmt.Errorf("error dialing tcp %s: %w", addr, err)
558578
}
559579

560580
// We have a TCP connection; we will force-close it to support context cancellation

0 commit comments

Comments
 (0)