1package cmd
2
3import (
4	"bytes"
5	"context"
6	"fmt"
7	"io/ioutil"
8	"os"
9
10	"github.com/gridscale/gsclient-go/v3"
11	"github.com/gridscale/gscloud/render"
12	"github.com/spf13/cobra"
13)
14
15type sshKeyCmdFlags struct {
16	name       string
17	pubKeyFile string
18}
19
20var (
21	sshKeyFlags sshKeyCmdFlags
22)
23
24var sshKeyCmd = &cobra.Command{
25	Use:   "ssh-key",
26	Short: "Operations on SSH keys",
27	Long:  `List, create, or remove SSH keys.`,
28}
29
30var sshKeyLsCmd = &cobra.Command{
31	Use:     "ls [flags]",
32	Aliases: []string{"list"},
33	Short:   "List SSH keys",
34	Long:    `List SSH key objects.`,
35	RunE: func(cmd *cobra.Command, args []string) error {
36		ctx := context.Background()
37		out := new(bytes.Buffer)
38		op := rt.SSHKeyOperator()
39		sshkeys, err := op.GetSshkeyList(ctx)
40		if err != nil {
41			return NewError(cmd, "Could not get SSH key list", err)
42		}
43		var rows [][]string
44		if !rootFlags.json {
45			heading := []string{"id", "name", "key", "user", "created"}
46			for _, key := range sshkeys {
47				fill := [][]string{
48					{
49						key.Properties.ObjectUUID,
50						key.Properties.Name,
51						key.Properties.Sshkey[:10] + "..." + key.Properties.Sshkey[len(key.Properties.Sshkey)-30:],
52						key.Properties.UserUUID[:8],
53						key.Properties.CreateTime.String()[:19],
54					},
55				}
56				rows = append(rows, fill...)
57			}
58
59			if rootFlags.quiet {
60				for _, info := range rows {
61					fmt.Println(info[0])
62				}
63				return nil
64			}
65			render.AsTable(out, heading, rows, renderOpts)
66		} else {
67			render.AsJSON(out, sshkeys)
68		}
69		fmt.Print(out)
70		return nil
71	},
72}
73
74var sshKeyAddCmd = &cobra.Command{
75	Use:   "add [flags]",
76	Short: "Add a new SSH key",
77	Long:  `Create a new SSH key.`,
78	RunE: func(cmd *cobra.Command, args []string) error {
79		publicKey, err := ioutil.ReadFile(sshKeyFlags.pubKeyFile)
80		if err != nil {
81			return NewError(cmd, "Error reading file", err)
82		}
83		ctx := context.Background()
84		op := rt.SSHKeyOperator()
85		_, err = op.CreateSshkey(ctx, gsclient.SshkeyCreateRequest{
86			Name:   sshKeyFlags.name,
87			Sshkey: string(publicKey),
88		})
89		if err != nil {
90			return NewError(cmd, "Creating SSH key failed", err)
91		}
92		return nil
93	},
94}
95
96var sshKeyRmCmd = &cobra.Command{
97	Use:     "rm [flags] [ID]",
98	Aliases: []string{"remove"},
99	Short:   "Remove SSH key",
100	Long:    `Remove an existing SSH key.`,
101	Args:    cobra.ExactArgs(1),
102	RunE: func(cmd *cobra.Command, args []string) error {
103		ctx := context.Background()
104		op := rt.SSHKeyOperator()
105		err := op.DeleteSshkey(ctx, args[0])
106		if err != nil {
107			return NewError(cmd, "Removing SSH key failed", err)
108		}
109		fmt.Fprintf(os.Stderr, "Removed %s\n", args[0])
110		return nil
111	},
112}
113
114func init() {
115	sshKeyAddCmd.PersistentFlags().StringVarP(&sshKeyFlags.name, "name", "n", "", "Name of the new key")
116	sshKeyAddCmd.MarkFlagRequired("name")
117	sshKeyAddCmd.PersistentFlags().StringVarP(&sshKeyFlags.pubKeyFile, "file", "f", "", "Path to public key file")
118	sshKeyAddCmd.MarkFlagRequired("file")
119
120	sshKeyCmd.AddCommand(sshKeyLsCmd, sshKeyAddCmd, sshKeyRmCmd)
121	rootCmd.AddCommand(sshKeyCmd)
122}
123