github.com/chasestarr/deis@v1.13.5-0.20170519182049-1d9e59fbdbfc/deisctl/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/base64"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"regexp"
    10  
    11  	"github.com/deis/deis/deisctl/utils"
    12  )
    13  
    14  // fileKeys define config keys to be read from local files
    15  var fileKeys = []string{
    16  	"/deis/platform/sshPrivateKey",
    17  	"/deis/router/sslCert",
    18  	"/deis/router/sslKey",
    19  	"/deis/router/sslDhparam"}
    20  
    21  // b64Keys define config keys to be base64 encoded before stored
    22  var b64Keys = []string{"/deis/platform/sshPrivateKey"}
    23  
    24  // Config runs the config subcommand
    25  func Config(target string, action string, key []string, cb Backend) error {
    26  	return doConfig(target, action, key, cb, os.Stdout)
    27  }
    28  
    29  // CheckConfig looks for a value at a keyspace path
    30  // and returns an error if a value is not found
    31  func CheckConfig(root string, k string, cb Backend) error {
    32  
    33  	_, err := doConfigGet(cb, root, []string{k})
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  func doConfig(target string, action string, key []string, cb Backend, w io.Writer) error {
    42  	rootPath := "/deis/" + target + "/"
    43  
    44  	var vals []string
    45  	var err error
    46  
    47  	switch action {
    48  	case "rm":
    49  		vals, err = doConfigRm(cb, rootPath, key)
    50  	case "set":
    51  		vals, err = doConfigSet(cb, rootPath, key)
    52  	default:
    53  		vals, err = doConfigGet(cb, rootPath, key)
    54  	}
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	// print results
    60  	for _, v := range vals {
    61  		fmt.Fprintf(w, "%v\n", v)
    62  	}
    63  	return nil
    64  }
    65  
    66  func doConfigSet(cb Backend, root string, kvs []string) ([]string, error) {
    67  	var result []string
    68  	regex := regexp.MustCompile(`^(.+)=([\s\S]+)$`)
    69  
    70  	for _, kv := range kvs {
    71  
    72  		if !regex.MatchString(kv) {
    73  			return []string{}, fmt.Errorf("'%s' does not match the pattern 'key=var', ex: foo=bar\n", kv)
    74  		}
    75  
    76  		// split k/v from args
    77  		captures := regex.FindStringSubmatch(kv)
    78  		k, v := captures[1], captures[2]
    79  
    80  		// prepare path and value
    81  		path := root + k
    82  		val, err := valueForPath(path, v)
    83  		if err != nil {
    84  			return result, err
    85  		}
    86  
    87  		// set key/value in config backend
    88  		ret, err := cb.Set(path, val)
    89  		if err != nil {
    90  			return result, err
    91  		}
    92  		result = append(result, ret)
    93  
    94  	}
    95  	return result, nil
    96  }
    97  
    98  func doConfigGet(cb Backend, root string, keys []string) ([]string, error) {
    99  	var result []string
   100  	for _, k := range keys {
   101  		val, err := cb.Get(root + k)
   102  		if err != nil {
   103  			return result, err
   104  		}
   105  		result = append(result, val)
   106  	}
   107  	return result, nil
   108  }
   109  
   110  func doConfigRm(cb Backend, root string, keys []string) ([]string, error) {
   111  	var result []string
   112  	for _, k := range keys {
   113  		err := cb.Delete(root + k)
   114  		if err != nil {
   115  			return result, err
   116  		}
   117  		result = append(result, k)
   118  	}
   119  	return result, nil
   120  }
   121  
   122  // valueForPath returns the canonical value for a user-defined path and value
   123  func valueForPath(path string, v string) (string, error) {
   124  
   125  	// check if path is part of fileKeys
   126  	for _, p := range fileKeys {
   127  
   128  		if path == p {
   129  
   130  			// read value from filesystem
   131  			bytes, err := ioutil.ReadFile(utils.ResolvePath(v))
   132  			if err != nil {
   133  				return "", err
   134  			}
   135  
   136  			// see if we should return base64 encoded value
   137  			for _, pp := range b64Keys {
   138  				if path == pp {
   139  					return base64.StdEncoding.EncodeToString(bytes), nil
   140  				}
   141  			}
   142  
   143  			return string(bytes), nil
   144  		}
   145  	}
   146  
   147  	return v, nil
   148  
   149  }