blob: 0d33849655e1b29459d002306c1160b9cfbad86e [file] [log] [blame]
Tim Windelschmidt6d33a432025-02-04 14:34:25 +01001// Copyright The Monogon Project Authors.
2// SPDX-License-Identifier: Apache-2.0
3
Tim Windelschmidt9f21f532024-05-07 15:14:20 +02004package launch
Serge Bazanski1f8cad72023-03-20 16:58:10 +01005
6import (
Serge Bazanski7eeef0f2024-02-05 14:40:15 +01007 "context"
8 "crypto/x509"
Serge Bazanski1f8cad72023-03-20 16:58:10 +01009 "fmt"
10 "net"
11 "os"
12 "path"
13 "sort"
14
15 "github.com/kballard/go-shellquote"
16
17 metroctl "source.monogon.dev/metropolis/cli/metroctl/core"
Serge Bazanski1f8cad72023-03-20 16:58:10 +010018)
19
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010020type acceptall struct{}
21
22func (a *acceptall) Ask(ctx context.Context, _ *metroctl.ConnectOptions, _ *x509.Certificate) (bool, error) {
23 return true, nil
24}
25
Serge Bazanski1f8cad72023-03-20 16:58:10 +010026// ConnectOptions returns metroctl.ConnectOptions that describe connectivity to
27// the launched cluster.
28func (c *Cluster) ConnectOptions() *metroctl.ConnectOptions {
29 // Use all metropolis nodes as endpoints. That's fine, metroctl's resolver will
30 // figure out what to actually use.
31 var endpoints []string
32 for _, n := range c.Nodes {
33 endpoints = append(endpoints, n.ManagementAddress)
34 }
35 sort.Strings(endpoints)
36 return &metroctl.ConnectOptions{
37 ConfigPath: c.metroctlDir,
38 ProxyServer: net.JoinHostPort("127.0.0.1", fmt.Sprintf("%d", c.Ports[SOCKSPort])),
39 Endpoints: endpoints,
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010040 TOFU: &acceptall{},
Serge Bazanski1f8cad72023-03-20 16:58:10 +010041 }
42}
43
44// MetroctlFlags return stringified flags to pass to a metroctl binary to connect
45// to the launched cluster.
46func (c *Cluster) MetroctlFlags() string {
47 return shellquote.Join(c.ConnectOptions().ToFlags()...)
48}
49
50// MakeMetroctlWrapper builds and returns the path to a shell script which calls
51// metroctl (from //metropolis/cli/metroctl, which must be included as a data
52// dependency of the built target) with all the required flags to connect to the
53// launched cluster.
54func (c *Cluster) MakeMetroctlWrapper() (string, error) {
Serge Bazanski1f8cad72023-03-20 16:58:10 +010055 wpath := path.Join(c.metroctlDir, "metroctl.sh")
56
57 // Don't create wrapper if it already exists.
58 if _, err := os.Stat(wpath); err == nil {
59 return wpath, nil
60 }
61
Tim Windelschmidt82e6af72024-07-23 00:05:42 +000062 wrapper := fmt.Sprintf("#!/usr/bin/env bash\nexec %s %s \"$@\"", xMetroctlPath, c.MetroctlFlags())
Serge Bazanski1f8cad72023-03-20 16:58:10 +010063 if err := os.WriteFile(wpath, []byte(wrapper), 0555); err != nil {
64 return "", fmt.Errorf("could not write wrapper: %w", err)
65 }
66 return wpath, nil
67}