github.com/deis/deis@v1.13.5-0.20170519182049-1d9e59fbdbfc/client/cmd/keys.go (about)

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