blob: 110c54d50a641b5bf3c5c5ca0d2dee09f53f0773 [file] [log] [blame]
Serge Bazanski9f0e1e82023-03-31 22:36:54 +00001package main
2
3import (
4 "fmt"
5 "log"
6 "os"
7 "os/user"
8 "path/filepath"
9
10 "github.com/spf13/cobra"
11 "k8s.io/client-go/tools/clientcmd"
12 clientapi "k8s.io/client-go/tools/clientcmd/api"
13
14 "code.hackerspace.pl/hscloud/cluster/clustercfg/certs"
15 "code.hackerspace.pl/hscloud/go/workspace"
16)
17
18var admincredsCmd = &cobra.Command{
19 Use: "admincreds",
20 Short: "Acquire emergency Kubernetes credentials",
21 Long: `
22Use secretstore secrets to generate a Kubernetes system:masters keypair and
23certificate. Only for use in emergencies.
24
25Your local username and hostname will make part of the cert and can be used
26for auditing of accesses to apiservers.
27`,
28 Run: func(cmd *cobra.Command, args []string) {
29 ws, err := workspace.Get()
30 if err != nil {
31 log.Fatalf("Could not figure out workspace: %v", err)
32 }
33
34 uname := "UNKNOWN"
35 if u, err := user.Current(); err == nil {
36 uname = u.Username
37 }
38 hostname := "UNKNOWN"
39 if h, err := os.Hostname(); err == nil {
40 hostname = h
41 }
42 breadcrumb := fmt.Sprintf("%s@%s", uname, hostname)
43
44 root := filepath.Join(ws, "cluster")
45 path := filepath.Join(ws, ".kubectl", "admincreds")
46 c := certs.Prepare(root, nil)
47 creds := c.MakeKubeEmergencyCreds(path, breadcrumb)
48 _ = creds
49
50 log.Printf("")
51 log.Printf("WARNING WARNING WARNING WARNING WARNING WARNING")
52 log.Printf("===============================================")
53 log.Printf("")
54 log.Printf("You are requesting ADMIN credentials.")
55 log.Printf("")
56 log.Printf("You likely shouldn't be doing this, and")
57 log.Printf("instead should be using `prodaccess`.")
58 log.Printf("")
59 log.Printf("===============================================")
60 log.Printf("WARNING WARNING WARNING WARNING WARNING WARNING")
61 log.Printf("")
62
63 log.Printf("Issuing certs...")
64 if err := creds.Ensure(); err != nil {
65 log.Fatalf("Failed: %v", err)
66 }
67
68 log.Printf("Configuring kubectl...")
69 caPath, certPath, keyPath := creds.Paths()
70 if err := installKubeletConfig(caPath, certPath, keyPath, "emergency.k0"); err != nil {
71 log.Fatalf("Failed: %v", err)
72 }
73
74 log.Fatalf("Done. Use kubectl --context=emergency.k0")
75 },
76}
77
78func installKubeletConfig(caPath, certPath, keyPath, configName string) error {
79 ca := clientcmd.NewDefaultPathOptions()
80 config, err := ca.GetStartingConfig()
81 if err != nil {
82 return fmt.Errorf("getting initial config failed: %w", err)
83 }
84
85 config.AuthInfos[configName] = &clientapi.AuthInfo{
86 ClientCertificate: certPath,
87 ClientKey: keyPath,
88 }
89
90 config.Clusters[configName] = &clientapi.Cluster{
91 CertificateAuthority: caPath,
92 Server: "https://k0.hswaw.net:4001",
93 }
94
95 config.Contexts[configName] = &clientapi.Context{
96 AuthInfo: configName,
97 Cluster: configName,
98 Namespace: "default",
99 }
100
101 if err := clientcmd.ModifyConfig(ca, *config, true); err != nil {
102 return fmt.Errorf("modifying config failed: %w", err)
103 }
104 return nil
105}
106
107func init() {
108 rootCmd.AddCommand(admincredsCmd)
109}