Skip to content

Commit

Permalink
fix(cloud): Several small usability fixes (#1809)
Browse files Browse the repository at this point in the history
Reviewed-by: Alexander Jung <[email protected]>
Approved-by: Alexander Jung <[email protected]>
  • Loading branch information
nderjung authored Jul 26, 2024
2 parents 845710d + f560ad6 commit 4cd5494
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 32 deletions.
36 changes: 26 additions & 10 deletions internal/cli/kraft/cloud/tunnel/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import (

// Relay relays connections from a local listener to a remote host over TLS.
type Relay struct {
lAddr string
rAddr string
ctype string
auth string
name string
lAddr string
rAddr string
ctype string
auth string
name string
nameAddr string
}

const Heartbeat = "\xf0\x9f\x91\x8b\xf0\x9f\x90\x92\x00"
Expand All @@ -39,7 +40,13 @@ func (r *Relay) Up(ctx context.Context) error {
defer func() { l.Close() }()
go func() { <-ctx.Done(); l.Close() }()

log.G(ctx).Info("tunnelling ", l.Addr(), " to ", r.rAddr)
log.G(ctx).
WithField("from", l.Addr()).
WithField("to", r.nameAddr).
Info("tunnelling")
log.G(ctx).
WithField("via", r.rAddr).
Debug("tunnelling")

for {
conn, err := l.Accept()
Expand All @@ -51,7 +58,7 @@ func (r *Relay) Up(ctx context.Context) error {
}

c := r.newConnection(conn)
go c.handle(ctx, []byte(r.auth), r.name)
go c.handle(ctx, []byte(r.auth), r.name, r.nameAddr)
}
}

Expand Down Expand Up @@ -108,10 +115,12 @@ type connection struct {

// handle handles the client connection by relaying reads and writes from/to
// the remote host.
func (c *connection) handle(ctx context.Context, auth []byte, instance string) {
func (c *connection) handle(ctx context.Context, auth []byte, instance, instanceRaw string) {
defer func() {
c.conn.Close()
log.G(ctx).Info("closed client connection ", c.conn.RemoteAddr())
log.G(ctx).
WithField("for", instanceRaw).
Info("closed connection")
}()

rc, err := c.relay.dialRemote(ctx)
Expand All @@ -121,7 +130,14 @@ func (c *connection) handle(ctx context.Context, auth []byte, instance string) {
}
defer rc.Close()

log.G(ctx).Info("accepted client connection ", c.conn.RemoteAddr(), " to ", rc.LocalAddr(), "->", rc.RemoteAddr())
log.G(ctx).
WithField("for", c.conn.RemoteAddr()).
WithField("from", rc.LocalAddr()).
WithField("to", rc.RemoteAddr()).
Debug("opened connection")
log.G(ctx).
WithField("to", instanceRaw).
Info("accepted connection")

// NOTE(antoineco): these calls are critical as they allow reads/writes to be
// later cancelled, because the deadline applies to all future and pending
Expand Down
35 changes: 22 additions & 13 deletions internal/cli/kraft/cloud/tunnel/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ func (opts *TunnelOptions) Run(ctx context.Context, args []string) error {
kraftcloud.WithToken(config.GetKraftCloudTokenAuthConfig(*auth)),
).WithMetro(opts.Metro)

rawInstances := opts.instances
opts.instances, err = populatePrivateIPs(ctx, cliInstance, opts.instances)
if err != nil {
return fmt.Errorf("could not populate private IPs: %w", err)
Expand Down Expand Up @@ -220,9 +221,10 @@ func (opts *TunnelOptions) Run(ctx context.Context, args []string) error {
// NOTE(craciunoiuc): Only TCP is supported at the moment. This refers to the
// local listener, as the remote listener is always assumed to be TCP because
// of TLS.
ctype: opts.ctypes[0],
auth: authStr,
name: instID,
ctype: opts.ctypes[0],
auth: authStr,
name: instID,
nameAddr: fmt.Sprintf("%s:%d", rawInstances[0], opts.instanceProxyPorts[0]),
}

for i := range opts.localPorts {
Expand All @@ -231,11 +233,12 @@ func (opts *TunnelOptions) Run(ctx context.Context, args []string) error {
}

pr := Relay{
lAddr: net.JoinHostPort("127.0.0.1", strconv.FormatUint(uint64(opts.localPorts[i]), 10)),
rAddr: net.JoinHostPort(sgFQDN, strconv.FormatUint(uint64(opts.exposedProxyPorts[i]), 10)),
ctype: opts.ctypes[i],
auth: authStr,
name: instID,
lAddr: net.JoinHostPort("127.0.0.1", strconv.FormatUint(uint64(opts.localPorts[i]), 10)),
rAddr: net.JoinHostPort(sgFQDN, strconv.FormatUint(uint64(opts.exposedProxyPorts[i]), 10)),
ctype: opts.ctypes[i],
auth: authStr,
name: instID,
nameAddr: fmt.Sprintf("%s:%d", rawInstances[i], opts.instanceProxyPorts[i]),
}

go func() {
Expand Down Expand Up @@ -401,14 +404,15 @@ func (opts *TunnelOptions) formatProxyArgs(authStr string) []string {
}

// populatePrivateIPs fetches the private IPs of the instances and replaces the instance names/uuids with the Private IPs.
func populatePrivateIPs(ctx context.Context, cli kcinstances.InstancesService, ips []string) ([]string, error) {
func populatePrivateIPs(ctx context.Context, cli kcinstances.InstancesService, targets []string) (ips []string, err error) {
var instancesToGet []string
var indexesToGet []int
for i := range ips {
for i := range targets {
ips = append(ips, targets[i])
// If instance is not an IP (PrivateIP) or PrivateFQDN
// assume it is a name/UUID and fetch the IP
if net.ParseIP(ips[i]) == nil && !strings.HasSuffix(ips[i], ".internal") {
instancesToGet = append(instancesToGet, ips[i])
if net.ParseIP(targets[i]) == nil && !strings.HasSuffix(targets[i], ".internal") {
instancesToGet = append(instancesToGet, targets[i])
indexesToGet = append(indexesToGet, i)
}
}
Expand All @@ -418,7 +422,12 @@ func populatePrivateIPs(ctx context.Context, cli kcinstances.InstancesService, i
return nil, fmt.Errorf("getting instances: %w", err)
}

for i, inst := range instGetResp.Data.Entries {
instances, err := instGetResp.AllOrErr()
if err != nil {
return nil, fmt.Errorf("getting instances: %w", err)
}

for i, inst := range instances {
if inst.PrivateIP == "" {
return nil, fmt.Errorf("instance '%s' not found", instancesToGet[i])
}
Expand Down
30 changes: 21 additions & 9 deletions internal/cli/kraft/cloud/utils/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,17 @@ func PrintInstances(ctx context.Context, format string, resp kcclient.ServiceRes

table.AddField(instance.Name, nil)

var fqdn string
if instance.ServiceGroup != nil && len(instance.ServiceGroup.Domains) > 0 {
fqdn = instance.ServiceGroup.Domains[0].FQDN
if instance.ServiceGroup != nil {
var fqdns []string
for _, domain := range instance.ServiceGroup.Domains {
if domain.FQDN != "" {
fqdns = append(fqdns, domain.FQDN)
}
}
table.AddField(strings.Join(fqdns, ","), nil)
} else {
table.AddField("", nil)
}
table.AddField(fqdn, nil)

if format != "table" {
table.AddField(instance.PrivateFQDN, nil)
Expand Down Expand Up @@ -320,7 +326,11 @@ func PrintInstances(ctx context.Context, format string, resp kcclient.ServiceRes
}
table.AddField(strings.Join(vols, ", "), nil)
if instance.ServiceGroup != nil {
table.AddField(instance.ServiceGroup.UUID, nil)
if instance.ServiceGroup.Name != "" {
table.AddField(instance.ServiceGroup.Name, nil)
} else {
table.AddField(instance.ServiceGroup.UUID, nil)
}
} else {
table.AddField("", nil)
}
Expand Down Expand Up @@ -605,11 +615,13 @@ func PrintServices(ctx context.Context, format string, resp kcclient.ServiceResp

table.AddField(sg.Name, nil)

var fqdn string
if len(sg.Domains) > 0 {
fqdn = sg.Domains[0].FQDN
var fqdns []string
for _, domain := range sg.Domains {
if domain.FQDN != "" {
fqdns = append(fqdns, domain.FQDN)
}
}
table.AddField(fqdn, nil)
table.AddField(strings.Join(fqdns, ","), nil)

var services []string
for _, service := range sg.Services {
Expand Down

0 comments on commit 4cd5494

Please sign in to comment.