forked from tangled.org/core
this repo has no description
at master 2.9 kB view raw
1package keyfetch 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "os" 10 "strings" 11 12 "github.com/urfave/cli/v3" 13 "tangled.sh/tangled.sh/core/log" 14) 15 16func Command() *cli.Command { 17 return &cli.Command{ 18 Name: "keys", 19 Usage: "fetch public keys from the knot server", 20 Action: Run, 21 Flags: []cli.Flag{ 22 &cli.StringFlag{ 23 Name: "output", 24 Aliases: []string{"o"}, 25 Usage: "output format (table, json, authorized-keys)", 26 Value: "table", 27 }, 28 &cli.StringFlag{ 29 Name: "internal-api", 30 Usage: "internal API endpoint", 31 Value: "http://localhost:5444", 32 }, 33 &cli.StringFlag{ 34 Name: "git-dir", 35 Usage: "base directory for git repos", 36 Value: "/home/git", 37 }, 38 &cli.StringFlag{ 39 Name: "log-path", 40 Usage: "path to log file", 41 Value: "/home/git/log", 42 }, 43 }, 44 } 45} 46 47func Run(ctx context.Context, cmd *cli.Command) error { 48 l := log.FromContext(ctx) 49 50 internalApi := cmd.String("internal-api") 51 gitDir := cmd.String("git-dir") 52 logPath := cmd.String("log-path") 53 output := cmd.String("output") 54 55 executablePath, err := os.Executable() 56 if err != nil { 57 l.Error("error getting path of executable", "error", err) 58 return err 59 } 60 61 resp, err := http.Get(internalApi + "/keys") 62 if err != nil { 63 l.Error("error reaching internal API endpoint; is the knot server running?", "error", err) 64 return err 65 } 66 defer resp.Body.Close() 67 68 body, err := io.ReadAll(resp.Body) 69 if err != nil { 70 l.Error("error reading response body", "error", err) 71 return err 72 } 73 74 var data []map[string]any 75 err = json.Unmarshal(body, &data) 76 if err != nil { 77 l.Error("error unmarshalling response body", "error", err) 78 return err 79 } 80 81 switch output { 82 case "json": 83 prettyJSON, err := json.MarshalIndent(data, "", " ") 84 if err != nil { 85 l.Error("error pretty printing JSON", "error", err) 86 return err 87 } 88 89 if _, err := os.Stdout.Write(prettyJSON); err != nil { 90 l.Error("error writing to stdout", "error", err) 91 return err 92 } 93 case "authorized-keys": 94 formatted := formatKeyData(executablePath, gitDir, logPath, internalApi, data) 95 _, err := os.Stdout.Write([]byte(formatted)) 96 if err != nil { 97 l.Error("error writing to stdout", "error", err) 98 return err 99 } 100 case "table": 101 fmt.Printf("%-40s %-40s\n", "DID", "KEY") 102 fmt.Println(strings.Repeat("-", 80)) 103 104 for _, entry := range data { 105 did, _ := entry["did"].(string) 106 key, _ := entry["key"].(string) 107 fmt.Printf("%-40s %-40s\n", did, key) 108 } 109 } 110 return nil 111} 112 113func formatKeyData(executablePath, gitDir, logPath, endpoint string, data []map[string]any) string { 114 var result string 115 for _, entry := range data { 116 result += fmt.Sprintf( 117 `command="%s guard -git-dir %s -user %s -log-path %s -internal-api %s",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s`+"\n", 118 executablePath, gitDir, entry["did"], logPath, endpoint, entry["key"]) 119 } 120 return result 121}