github.com/rafflecopter/deis@v1.12.2/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  }