blob: bdba8a96672c72142c73dff1de8c60bcd540482d [file] [log] [blame]
Mateusz Zalegae15fee12022-08-12 18:48:40 +02001package main
2
3import (
4 "context"
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +02005 "fmt"
Mateusz Zalegae15fee12022-08-12 18:48:40 +02006 "log"
Tim Windelschmidtb765f242024-05-08 01:40:02 +02007 "os"
8 "os/signal"
Mateusz Zalegae15fee12022-08-12 18:48:40 +02009 "strings"
10
11 "github.com/spf13/cobra"
12
Mateusz Zalegae15fee12022-08-12 18:48:40 +020013 "source.monogon.dev/metropolis/proto/api"
14)
15
16var addCmd = &cobra.Command{
17 Short: "Updates node configuration.",
18 Use: "add",
19}
20
21var removeCmd = &cobra.Command{
22 Short: "Updates node configuration.",
23 Use: "remove",
24}
25
26var addRoleCmd = &cobra.Command{
27 Short: "Updates node roles.",
Serge Bazanski15f7f632023-03-14 17:17:20 +010028 Use: "role <KubernetesController|KubernetesWorker|ConsensusMember> [NodeID, ...]",
Mateusz Zalegae15fee12022-08-12 18:48:40 +020029 Example: "metroctl node add role KubernetesWorker metropolis-25fa5f5e9349381d4a5e9e59de0215e3",
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020030 Args: PrintUsageOnWrongArgs(cobra.MinimumNArgs(2)),
31 RunE: func(cmd *cobra.Command, args []string) error {
32 ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
33 cc, err := dialAuthenticated(ctx)
34 if err != nil {
35 return fmt.Errorf("while dialing node: %w", err)
36 }
37 mgmt := api.NewManagementClient(cc)
38
39 role := strings.ToLower(args[0])
40 nodes := args[1:]
41
42 opt := func(v bool) *bool { return &v }
43 for _, node := range nodes {
44 req := &api.UpdateNodeRolesRequest{
45 Node: &api.UpdateNodeRolesRequest_Id{
46 Id: node,
47 },
48 }
49 switch role {
50 case "kubernetescontroller", "kc":
51 req.KubernetesController = opt(true)
52 case "kubernetesworker", "kw":
53 req.KubernetesWorker = opt(true)
54 case "consensusmember", "cm":
55 req.ConsensusMember = opt(true)
56 default:
57 return fmt.Errorf("unknown role: %s", role)
58 }
59
60 _, err := mgmt.UpdateNodeRoles(ctx, req)
61 if err != nil {
62 log.Printf("Couldn't update node \"%s\": %v", node, err)
63 } else {
64 log.Printf("Updated node %s.", node)
65 }
66 }
67 return nil
68 },
Mateusz Zalegae15fee12022-08-12 18:48:40 +020069}
70
71var removeRoleCmd = &cobra.Command{
72 Short: "Updates node roles.",
Serge Bazanski15f7f632023-03-14 17:17:20 +010073 Use: "role <KubernetesController|KubernetesWorker|ConsensusMember> [NodeID, ...]",
Mateusz Zalegae15fee12022-08-12 18:48:40 +020074 Example: "metroctl node remove role KubernetesWorker metropolis-25fa5f5e9349381d4a5e9e59de0215e3",
Tim Windelschmidtfc6e1cf2024-09-18 17:34:07 +020075 Args: PrintUsageOnWrongArgs(cobra.ArbitraryArgs),
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020076 RunE: func(cmd *cobra.Command, args []string) error {
77 ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
78 cc, err := dialAuthenticated(ctx)
79 if err != nil {
80 return fmt.Errorf("while dialing node: %w", err)
81 }
82 mgmt := api.NewManagementClient(cc)
83
84 role := strings.ToLower(args[0])
85 nodes := args[1:]
86
87 opt := func(v bool) *bool { return &v }
88 for _, node := range nodes {
89 req := &api.UpdateNodeRolesRequest{
90 Node: &api.UpdateNodeRolesRequest_Id{
91 Id: node,
92 },
93 }
94
95 switch role {
96 case "kubernetescontroller", "kc":
97 req.KubernetesController = opt(false)
98 case "kubernetesworker", "kw":
99 req.KubernetesWorker = opt(false)
100 case "consensusmember", "cm":
101 req.ConsensusMember = opt(false)
102 default:
103 return fmt.Errorf("unknown role: %s. Must be one of: KubernetesController, KubernetesWorker, ConsensusMember", role)
104 }
105
106 _, err := mgmt.UpdateNodeRoles(ctx, req)
107 if err != nil {
108 log.Printf("Couldn't update node \"%s\": %v", node, err)
109 } else {
110 log.Printf("Updated node %s.", node)
111 }
112 }
113 return nil
114 },
Mateusz Zalegae15fee12022-08-12 18:48:40 +0200115}
116
117func init() {
118 addCmd.AddCommand(addRoleCmd)
119 nodeCmd.AddCommand(addCmd)
120
121 removeCmd.AddCommand(removeRoleCmd)
122 nodeCmd.AddCommand(removeCmd)
123}