github.com/naphatkrit/deis@v1.12.3/client/cmd/keys.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "path" 7 "regexp" 8 "strconv" 9 "strings" 10 11 "github.com/deis/deis/client/controller/api" 12 "github.com/deis/deis/client/controller/client" 13 "github.com/deis/deis/client/controller/models/keys" 14 ) 15 16 // KeysList lists a user's keys. 17 func KeysList(results int) error { 18 c, err := client.New() 19 20 if err != nil { 21 return err 22 } 23 24 if results == defaultLimit { 25 results = c.ResponseLimit 26 } 27 28 keys, count, err := keys.List(c, results) 29 30 if err != nil { 31 return err 32 } 33 34 fmt.Printf("=== %s Keys%s", c.Username, limitCount(len(keys), count)) 35 36 for _, key := range keys { 37 fmt.Printf("%s %s...%s\n", key.ID, key.Public[:16], key.Public[len(key.Public)-10:]) 38 } 39 return nil 40 } 41 42 // KeyRemove removes keys. 43 func KeyRemove(keyID string) error { 44 c, err := client.New() 45 46 if err != nil { 47 return err 48 } 49 50 fmt.Printf("Removing %s SSH Key...", keyID) 51 52 if err = keys.Delete(c, keyID); err != nil { 53 fmt.Println() 54 return err 55 } 56 57 fmt.Println(" done") 58 return nil 59 } 60 61 // KeyAdd adds keys. 62 func KeyAdd(keyLocation string) error { 63 c, err := client.New() 64 65 if err != nil { 66 return err 67 } 68 69 var key api.KeyCreateRequest 70 71 if keyLocation == "" { 72 key, err = chooseKey() 73 } else { 74 key, err = getKey(keyLocation) 75 } 76 77 if err != nil { 78 return err 79 } 80 81 fmt.Printf("Uploading %s to deis...", path.Base(key.Name)) 82 83 if _, err = keys.New(c, key.ID, key.Public); err != nil { 84 fmt.Println() 85 return err 86 } 87 88 fmt.Println(" done") 89 return nil 90 } 91 92 func chooseKey() (api.KeyCreateRequest, error) { 93 keys, err := listKeys() 94 95 if err != nil { 96 return api.KeyCreateRequest{}, err 97 } 98 99 fmt.Println("Found the following SSH public keys:") 100 101 for i, key := range keys { 102 fmt.Printf("%d) %s %s\n", i+1, path.Base(key.Name), key.ID) 103 } 104 105 fmt.Println("0) Enter path to pubfile (or use keys:add <key_path>)") 106 107 var selected string 108 109 fmt.Print("Which would you like to use with Deis? ") 110 fmt.Scanln(&selected) 111 112 numSelected, err := strconv.Atoi(selected) 113 114 if err != nil { 115 return api.KeyCreateRequest{}, err 116 } 117 118 if numSelected > len(keys)+1 { 119 return api.KeyCreateRequest{}, fmt.Errorf("%d is not a valid option", numSelected) 120 } 121 122 if numSelected == 0 { 123 var filename string 124 125 fmt.Print("Enter the path to the pubkey file: ") 126 fmt.Scanln(&filename) 127 128 return getKey(filename) 129 } 130 131 return keys[numSelected-1], nil 132 } 133 134 func listKeys() ([]api.KeyCreateRequest, error) { 135 folder := path.Join(client.FindHome(), ".ssh") 136 files, err := ioutil.ReadDir(folder) 137 138 if err != nil { 139 return nil, err 140 } 141 142 var keys []api.KeyCreateRequest 143 144 for _, file := range files { 145 if path.Ext(file.Name()) == ".pub" { 146 key, err := getKey(path.Join(folder, file.Name())) 147 148 if err == nil { 149 keys = append(keys, key) 150 } else { 151 fmt.Println(err) 152 } 153 } 154 } 155 156 return keys, nil 157 } 158 159 func getKey(filename string) (api.KeyCreateRequest, error) { 160 regex := regexp.MustCompile("^(ssh-...|ecdsa-[^ ]+) ([^ ]+) ?(.*)") 161 contents, err := ioutil.ReadFile(filename) 162 163 if err != nil { 164 return api.KeyCreateRequest{}, err 165 } 166 167 if regex.Match(contents) { 168 capture := regex.FindStringSubmatch(string(contents)) 169 if capture[3] != "" { 170 return api.KeyCreateRequest{ID: capture[3], Public: string(contents), Name: filename}, nil 171 } 172 173 id := strings.Split(path.Base(filename), ".")[0] 174 return api.KeyCreateRequest{ID: id, Public: string(contents), Name: filename}, nil 175 } 176 177 return api.KeyCreateRequest{}, fmt.Errorf("%s is not a valid ssh key", filename) 178 }