blob: 9d685a161930653c64b1a9e7003c24ce0aa9d647 [file] [log] [blame]
Mateusz Zalegac437dc42022-07-07 13:01:43 +02001package main
2
3import (
4 "context"
5 "fmt"
Mateusz Zalegac437dc42022-07-07 13:01:43 +02006 "log"
7
8 "github.com/spf13/cobra"
9
Mateusz Zalega18a67b02022-08-02 13:37:50 +020010 "source.monogon.dev/metropolis/cli/metroctl/core"
Mateusz Zalegac437dc42022-07-07 13:01:43 +020011 clicontext "source.monogon.dev/metropolis/cli/pkg/context"
12 "source.monogon.dev/metropolis/node/core/identity"
13 "source.monogon.dev/metropolis/proto/api"
14)
15
16var approveCmd = &cobra.Command{
17 Short: "Approves a candidate node, if specified; lists nodes pending approval otherwise.",
18 Use: "approve [node-id]",
19 Args: cobra.MaximumNArgs(1), // One positional argument: node ID
20 Run: doApprove,
21}
22
23func init() {
24 rootCmd.AddCommand(approveCmd)
25}
26
Mateusz Zalegac437dc42022-07-07 13:01:43 +020027// nodeById returns the node matching id, if it exists within nodes.
28func nodeById(nodes []*api.Node, id string) *api.Node {
29 for _, n := range nodes {
30 if identity.NodeID(n.Pubkey) == id {
31 return n
32 }
33 }
34 return nil
35}
36
37func doApprove(cmd *cobra.Command, args []string) {
Mateusz Zalegadb75e212022-08-04 17:31:34 +020038 ctx := clicontext.WithInterrupt(context.Background())
39 cc := dialAuthenticated(ctx)
Mateusz Zalegac437dc42022-07-07 13:01:43 +020040 mgmt := api.NewManagementClient(cc)
41
42 // Get a list of all nodes pending approval by calling Management.GetNodes.
43 // We need this list regardless of whether we're actually approving nodes, or
44 // just listing them.
Mateusz Zalega18a67b02022-08-02 13:37:50 +020045 nodes, err := core.GetNodes(ctx, mgmt, "node.state == NODE_STATE_NEW")
Mateusz Zalegac437dc42022-07-07 13:01:43 +020046 if err != nil {
47 log.Fatalf("While fetching a list of nodes pending approval: %v", err)
48 }
49
50 if len(args) == 0 {
51 // If no id was given, just list the nodes pending approval.
52 if len(nodes) != 0 {
53 for _, n := range nodes {
54 fmt.Print(identity.NodeID(n.Pubkey))
55 }
56 } else {
57 log.Print("There are no nodes pending approval at this time.")
58 }
59 } else {
Mateusz Zalega4c078782022-08-12 19:03:53 +020060 // Otherwise, try to approve the nodes matching the supplied ids.
61 for _, tgtNodeId := range args {
62 n := nodeById(nodes, tgtNodeId)
63 if n == nil {
64 log.Fatalf("Couldn't find a new node matching id %s", tgtNodeId)
65 }
66 _, err := mgmt.ApproveNode(ctx, &api.ApproveNodeRequest{
67 Pubkey: n.Pubkey,
68 })
69 if err != nil {
70 log.Fatalf("While approving node %s: %v", tgtNodeId, err)
71 }
72 log.Printf("Approved node %s.", tgtNodeId)
Mateusz Zalegac437dc42022-07-07 13:01:43 +020073 }
Mateusz Zalegac437dc42022-07-07 13:01:43 +020074 }
75}