blob: e3ae92b7daf3541e8db1de25e670ac8e08244997 [file] [log] [blame]
Lorenz Brun6adf8842021-10-05 13:39:11 +02001package main
2
3import (
Serge Bazanski7eeef0f2024-02-05 14:40:15 +01004 "context"
5 "crypto/x509"
Mateusz Zalega18a67b02022-08-02 13:37:50 +02006 "log"
Mateusz Zalega8234c162022-07-08 17:05:50 +02007 "path/filepath"
8
9 "github.com/adrg/xdg"
Lorenz Brun6adf8842021-10-05 13:39:11 +020010 "github.com/spf13/cobra"
Serge Bazanski1f8cad72023-03-20 16:58:10 +010011
12 "source.monogon.dev/metropolis/cli/metroctl/core"
Lorenz Brun6adf8842021-10-05 13:39:11 +020013)
14
15// rootCmd represents the base command when called without any subcommands
16var rootCmd = &cobra.Command{
17 Use: "metroctl",
18 Short: "metroctl controls Metropolis nodes and clusters.",
19}
20
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020021type metroctlFlags struct {
22 // clusterEndpoints is a list of the targeted cluster's endpoints, used by
23 // commands that perform RPC on it.
24 clusterEndpoints []string
Mateusz Zalegaf7774962022-07-08 12:26:55 +020025 // proxyAddr is a SOCKS5 proxy address the cluster will be accessed through.
26 proxyAddr string
Mateusz Zalega8234c162022-07-08 17:05:50 +020027 // configPath overrides the default XDG config path
28 configPath string
Mateusz Zalegab2cac082022-07-14 14:55:43 +020029 // verbose, if set, will make this utility log additional runtime
30 // information.
31 verbose bool
Mateusz Zalegadb75e212022-08-04 17:31:34 +020032 // format refers to how the output data, except logs, is formatted.
33 format string
34 // filter specifies a CEL filter used to narrow down the set of output
35 // objects.
36 filter string
37 // output is an optional output file path the resulting data will be saved
38 // at. If unspecified, the data will be written to stdout.
39 output string
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010040 // acceptAnyCA will persist the first encountered (while connecting) CA
41 // certificate of the cluster as the trusted CA certificate for this cluster.
42 // This is unsafe and should only be used for testing.
43 acceptAnyCA bool
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020044}
45
46var flags metroctlFlags
47
48func init() {
Serge Bazanskicf33f682023-03-17 00:16:16 +010049 rootCmd.PersistentFlags().StringSliceVar(&flags.clusterEndpoints, "endpoints", nil, "A list of the target cluster's endpoints.")
Mateusz Zalegaf7774962022-07-08 12:26:55 +020050 rootCmd.PersistentFlags().StringVar(&flags.proxyAddr, "proxy", "", "SOCKS5 proxy address")
Mateusz Zalega8234c162022-07-08 17:05:50 +020051 rootCmd.PersistentFlags().StringVar(&flags.configPath, "config", filepath.Join(xdg.ConfigHome, "metroctl"), "An alternative cluster config path")
Mateusz Zalegab2cac082022-07-14 14:55:43 +020052 rootCmd.PersistentFlags().BoolVar(&flags.verbose, "verbose", false, "Log additional runtime information")
Serge Bazanskie012b722023-03-29 17:49:04 +020053 rootCmd.PersistentFlags().StringVar(&flags.format, "format", "plaintext", "Data output format")
Mateusz Zalegadb75e212022-08-04 17:31:34 +020054 rootCmd.PersistentFlags().StringVar(&flags.filter, "filter", "", "The object filter applied to the output data")
55 rootCmd.PersistentFlags().StringVarP(&flags.output, "output", "o", "", "Redirects output to the specified file")
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010056 rootCmd.PersistentFlags().BoolVar(&flags.acceptAnyCA, "insecure-accept-and-persist-first-encountered-ca", false, "Accept the first encountered CA while connecting as the trusted CA for future metroctl connections with this config path. This is very insecure and should only be used for testing.")
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020057}
58
Mateusz Zalega18a67b02022-08-02 13:37:50 +020059// rpcLogger passes through the cluster resolver logs, if "--verbose" flag was
60// used.
61func rpcLogger(f string, args ...interface{}) {
62 if flags.verbose {
Serge Bazanski4c50f992022-09-05 18:43:01 +020063 log.Printf("resolver: "+f, args...)
Mateusz Zalega18a67b02022-08-02 13:37:50 +020064 }
65}
66
Lorenz Brun6adf8842021-10-05 13:39:11 +020067func main() {
68 cobra.CheckErr(rootCmd.Execute())
69}
Serge Bazanski1f8cad72023-03-20 16:58:10 +010070
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010071type acceptall struct{}
72
73func (a *acceptall) Ask(ctx context.Context, _ *core.ConnectOptions, _ *x509.Certificate) (bool, error) {
74 return true, nil
75}
76
Serge Bazanski1f8cad72023-03-20 16:58:10 +010077// connectOptions returns core.ConnectOptions as defined by the metroctl flags
78// currently set.
79func connectOptions() *core.ConnectOptions {
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010080 var tofu core.CertificateTOFU
81 if flags.acceptAnyCA {
82 tofu = &acceptall{}
83 }
Serge Bazanski1f8cad72023-03-20 16:58:10 +010084 return &core.ConnectOptions{
Serge Bazanski925ec3d2024-02-05 14:38:20 +010085 ConfigPath: flags.configPath,
86 ProxyServer: flags.proxyAddr,
87 Endpoints: flags.clusterEndpoints,
88 ResolverLogger: rpcLogger,
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010089 TOFU: tofu,
Serge Bazanski1f8cad72023-03-20 16:58:10 +010090 }
91}