package keys import ( "context" "encoding/json" "fmt" "os" "strings" "github.com/urfave/cli/v3" "tangled.org/core/knot2/config" "tangled.org/core/knot2/db" "tangled.org/core/log" ) func Command() *cli.Command { return &cli.Command{ Name: "keys", Usage: "fetch public keys from the knot server", Action: Run, Flags: []cli.Flag{ &cli.StringFlag{ Name: "config", Aliases: []string{"c"}, Usage: "config path", Required: true, }, &cli.StringFlag{ Name: "output", Aliases: []string{"o"}, Usage: "output format (table, json, authorized-keys)", Value: "table", }, }, } } func Run(ctx context.Context, cmd *cli.Command) error { l := log.FromContext(ctx) l = log.SubLogger(l, cmd.Name) ctx = log.IntoContext(ctx, l) var ( output = cmd.String("output") configPath = cmd.String("config") ) cfg, err := config.Load(ctx, configPath) if err != nil { return fmt.Errorf("failed to load config: %w", err) } d, err := db.New(cfg.DbPath()) if err != nil { return fmt.Errorf("failed to load db: %w", err) } pubkeyDidListMap, err := db.GetPubkeyDidListMap(d) if err != nil { return err } switch output { case "json": prettyJSON, err := json.MarshalIndent(pubkeyDidListMap, "", " ") if err != nil { return err } if _, err := os.Stdout.Write(prettyJSON); err != nil { return err } case "table": fmt.Printf("%-40s %-40s\n", "KEY", "DID") fmt.Println(strings.Repeat("-", 80)) for key, didList := range pubkeyDidListMap { fmt.Printf("%-40s %-40s\n", key, strings.Join(didList, ",")) } case "authorized-keys": for key, didList := range pubkeyDidListMap { executablePath, err := os.Executable() if err != nil { l.Error("error getting path of executable", "error", err) return err } command := fmt.Sprintf("%s guard", executablePath) for _, did := range didList { command += fmt.Sprintf(" -user %s", did) } fmt.Printf( `command="%s",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s`+"\n", command, key, ) } if err != nil { l.Error("error writing to stdout", "error", err) return err } } return nil }