blob: 5ce4032b9201b9bc4b924349af807cb7e72dc85f [file] [log] [blame]
Serge Bazanski7d1a0de2023-07-05 01:17:15 +02001package main
2
3import (
Serge Bazanski568c38c2024-02-05 14:40:39 +01004 "context"
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +02005 "fmt"
Serge Bazanski7d1a0de2023-07-05 01:17:15 +02006 "log"
7 "os"
8 "os/exec"
Tim Windelschmidtb765f242024-05-08 01:40:02 +02009 "os/signal"
Serge Bazanski7d1a0de2023-07-05 01:17:15 +020010
11 "github.com/spf13/cobra"
12
13 "source.monogon.dev/metropolis/cli/metroctl/core"
14)
15
16var k8sCommand = &cobra.Command{
17 Short: "Manages kubernetes-specific functionality in Metropolis.",
18 Use: "k8s",
19}
20
21var k8sConfigureCommand = &cobra.Command{
22 Use: "configure",
23 Short: "Configures local `kubectl` for use with a Metropolis cluster.",
24 Long: `Configures a local kubectl instance (or any other Kubernetes application)
25to connect to a Metropolis cluster. A cluster endpoint must be provided with the
26--endpoints parameter.`,
Tim Windelschmidtfc6e1cf2024-09-18 17:34:07 +020027 Args: PrintUsageOnWrongArgs(cobra.ExactArgs(0)),
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020028 RunE: func(cmd *cobra.Command, _ []string) error {
29 ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
30 if len(flags.clusterEndpoints) < 1 {
31 return fmt.Errorf("k8s configure requires at least one cluster endpoint to be provided with the --endpoints parameter")
Serge Bazanski7d1a0de2023-07-05 01:17:15 +020032 }
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020033
34 contextName, err := cmd.Flags().GetString("context")
35 if err != nil || contextName == "" {
36 return fmt.Errorf("k8s configure requires a valid context name to be provided with the --context parameter")
37 }
38
39 // If the user has metroctl in their path, use the metroctl from path as
40 // a credential plugin. Otherwise use the path to the currently-running
41 // metroctl.
42 metroctlPath := "metroctl"
43 if _, err := exec.LookPath("metroctl"); err != nil {
44 metroctlPath, err = os.Executable()
45 if err != nil {
46 return fmt.Errorf("failed to create kubectl entry as metroctl is neither in PATH nor can its absolute path be determined: %w", err)
47 }
48 }
49 // TODO(q3k, issues/144): this only works as long as all nodes are kubernetes controller
50 // nodes. This won't be the case for too long. Figure this out.
51 if err := core.InstallKubeletConfig(ctx, metroctlPath, connectOptions(), contextName, flags.clusterEndpoints[0]); err != nil {
52 return fmt.Errorf("failed to install metroctl/k8s integration: %w", err)
53 }
54 log.Printf("Success! kubeconfig is set up. You can now run kubectl --context=%s ... to access the Kubernetes cluster.", contextName)
55 return nil
56 },
Serge Bazanski7d1a0de2023-07-05 01:17:15 +020057}
58
59func init() {
Tim Windelschmidt2f842372024-05-07 00:07:11 +020060 k8sConfigureCommand.Flags().String("context", "metroctl", "The name for the kubernetes context to configure")
Serge Bazanski7d1a0de2023-07-05 01:17:15 +020061 k8sCommand.AddCommand(k8sConfigureCommand)
Serge Bazanski7d1a0de2023-07-05 01:17:15 +020062 rootCmd.AddCommand(k8sCommand)
63}