| Tim Windelschmidt | 6d33a43 | 2025-02-04 14:34:25 +0100 | [diff] [blame] | 1 | // Copyright The Monogon Project Authors. |
| 2 | // SPDX-License-Identifier: Apache-2.0 |
| 3 | |
| Tim Windelschmidt | 9f21f53 | 2024-05-07 15:14:20 +0200 | [diff] [blame] | 4 | package launch |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 5 | |
| 6 | import ( |
| Serge Bazanski | 7eeef0f | 2024-02-05 14:40:15 +0100 | [diff] [blame] | 7 | "context" |
| 8 | "crypto/x509" |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 9 | "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 Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 18 | ) |
| 19 | |
| Serge Bazanski | 7eeef0f | 2024-02-05 14:40:15 +0100 | [diff] [blame] | 20 | type acceptall struct{} |
| 21 | |
| 22 | func (a *acceptall) Ask(ctx context.Context, _ *metroctl.ConnectOptions, _ *x509.Certificate) (bool, error) { |
| 23 | return true, nil |
| 24 | } |
| 25 | |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 26 | // ConnectOptions returns metroctl.ConnectOptions that describe connectivity to |
| 27 | // the launched cluster. |
| 28 | func (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 Bazanski | 7eeef0f | 2024-02-05 14:40:15 +0100 | [diff] [blame] | 40 | TOFU: &acceptall{}, |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 41 | } |
| 42 | } |
| 43 | |
| 44 | // MetroctlFlags return stringified flags to pass to a metroctl binary to connect |
| 45 | // to the launched cluster. |
| 46 | func (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. |
| 54 | func (c *Cluster) MakeMetroctlWrapper() (string, error) { |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 55 | 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 Windelschmidt | 82e6af7 | 2024-07-23 00:05:42 +0000 | [diff] [blame] | 62 | wrapper := fmt.Sprintf("#!/usr/bin/env bash\nexec %s %s \"$@\"", xMetroctlPath, c.MetroctlFlags()) |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 63 | 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 | } |