mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 17:23:22 +00:00
Merge pull request #43 from gravitational/alexander/update
re-vendor configure and update code
This commit is contained in:
commit
8df6d4e0f9
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
|
@ -67,7 +67,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/gravitational/configure",
|
||||
"Rev": "725b3af8847feced5316be064a297d7c8a1052b3"
|
||||
"Rev": "af81ee7530fe68dbac8824c44f9fd0b0546c3efb"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gravitational/form",
|
||||
|
|
55
Godeps/_workspace/src/github.com/gravitational/configure/README.md
generated
vendored
55
Godeps/_workspace/src/github.com/gravitational/configure/README.md
generated
vendored
|
@ -1,24 +1,43 @@
|
|||
# Configure
|
||||
|
||||
Package configure generates configuration tools based on a struct
|
||||
definition with tags. It can read a configuration for a struct
|
||||
from YAML, environment variables and command line.
|
||||
`configure` is a golang library that populates a struct from environment variables, command line arugments and YAML files.
|
||||
It works by reading a struct definition with special tags.
|
||||
|
||||
```go
|
||||
// Given the struct definition:
|
||||
type Config struct {
|
||||
StringVar string `env:"TEST_STRING_VAR" cli:"string" yaml:"string"`
|
||||
BoolVar bool `env:"TEST_BOOL_VAR" cli:"bool" yaml:"bool"`
|
||||
IntVar int `env:"TEST_INT_VAR" cli:"int" yaml:"int"`
|
||||
HexVar hexType `env:"TEST_HEX_VAR" cli:"hex" yaml:"hex"`
|
||||
MapVar map[string]string `env:"TEST_MAP_VAR" cli:"map" yaml:"map,flow"`
|
||||
SliceMapVar []map[string]string `env:"TEST_SLICE_MAP_VAR" cli:"slice" yaml:"slice,flow"`
|
||||
}
|
||||
### Usage
|
||||
|
||||
The latest can be seen if you run
|
||||
```
|
||||
|
||||
You can start initializing the struct from YAML, command line or environment.
|
||||
|
||||
```shell
|
||||
# use godoc for more details
|
||||
godoc github.com/gravitational/configure
|
||||
```
|
||||
|
||||
But here's a quickstart: Define a sample structure, for examlpe:
|
||||
```go
|
||||
|
||||
type Config struct {
|
||||
StringVar string `env:"STRING_VAR" cli:"string-var" yaml:"string_var"`
|
||||
BoolVar bool `env:"BOOL_VAR" cli:"bool_var" yaml:"bool_var"`
|
||||
IntVar int `env:"INT_VAR" cli:"int_var" yaml:"int_var"`
|
||||
HexVar hexType `env:"HEX_VAR" cli:"hex_var" yaml:"hex_var"`
|
||||
MapVar map[string]string `env:"MAP_VAR" cli:"map_var" yaml:"map_var,flow"`
|
||||
SliceMapVar []map[string]string `env:"SLICE_MAP_VAR" cli:"slice_var" yaml:"slice_var,flow"`
|
||||
}
|
||||
```
|
||||
|
||||
Then you can query the environment and populate that structure from environment variables, YAML files or command line arguments.
|
||||
|
||||
```go
|
||||
import (
|
||||
"os"
|
||||
"github.com/gravitational/configure"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var cfg Config
|
||||
// parse environment variables
|
||||
err := configure.ParseEnv(&cfg)
|
||||
// parse YAML
|
||||
err = configure.ParseYAML(&cfg)
|
||||
// parse command line arguments
|
||||
err = configure.ParseCommandLine(&cfg, os.Ars[1:])
|
||||
}
|
||||
```
|
||||
|
|
3
Godeps/_workspace/src/github.com/gravitational/configure/cli.go
generated
vendored
3
Godeps/_workspace/src/github.com/gravitational/configure/cli.go
generated
vendored
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure/cstrings"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
@ -139,7 +140,7 @@ func setMap(kv *map[string]string, val string) error {
|
|||
if len(*kv) == 0 {
|
||||
*kv = make(map[string]string)
|
||||
}
|
||||
for _, i := range SplitComma(val) {
|
||||
for _, i := range cstrings.SplitComma(val) {
|
||||
vals := strings.SplitN(i, ":", 2)
|
||||
if len(vals) != 2 {
|
||||
return trace.Errorf("extra options should be defined like KEY:VAL")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package configure
|
||||
package cstrings
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
@ -29,6 +29,21 @@ func Split(delim, escape rune, v string) []string {
|
|||
return out
|
||||
}
|
||||
|
||||
// SplitAt splits array of strings at a given separator
|
||||
func SplitAt(args []string, sep string) ([]string, []string) {
|
||||
index := -1
|
||||
for i, a := range args {
|
||||
if a == sep {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if index == -1 {
|
||||
return args, []string{}
|
||||
}
|
||||
return args[:index], args[index+1:]
|
||||
}
|
||||
|
||||
type splitter struct {
|
||||
delim rune
|
||||
escape rune
|
|
@ -1,9 +1,13 @@
|
|||
package configure
|
||||
package cstrings
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func TestStrings(t *testing.T) { TestingT(t) }
|
||||
|
||||
type USuite struct {
|
||||
}
|
||||
|
12
Godeps/_workspace/src/github.com/gravitational/configure/kv.go
generated
vendored
12
Godeps/_workspace/src/github.com/gravitational/configure/kv.go
generated
vendored
|
@ -6,7 +6,9 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure/cstrings"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
// KeyVal is map that can parse itself from string, represented as a
|
||||
|
@ -18,7 +20,7 @@ func (kv *KeyVal) Set(v string) error {
|
|||
if len(*kv) == 0 {
|
||||
*kv = make(map[string]string)
|
||||
}
|
||||
for _, i := range SplitComma(v) {
|
||||
for _, i := range cstrings.SplitComma(v) {
|
||||
vals := strings.SplitN(i, ":", 2)
|
||||
if len(vals) != 2 {
|
||||
return trace.Errorf("extra options should be defined like KEY:VAL")
|
||||
|
@ -47,6 +49,14 @@ func (kv *KeyVal) String() string {
|
|||
return b.String()
|
||||
}
|
||||
|
||||
// KeyValParam accepts a kingpin setting parameter and returns
|
||||
// kingpin-compatible value
|
||||
func KeyValParam(s kingpin.Settings) *KeyVal {
|
||||
kv := make(KeyVal)
|
||||
s.SetValue(&kv)
|
||||
return &kv
|
||||
}
|
||||
|
||||
// KeyValSlice is a list of key value strings
|
||||
type KeyValSlice []map[string]string
|
||||
|
||||
|
|
96
Godeps/_workspace/src/github.com/gravitational/configure/schema/decoding.go
generated
vendored
Normal file
96
Godeps/_workspace/src/github.com/gravitational/configure/schema/decoding.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type configV1 struct {
|
||||
Params []paramSpec `json:"params"`
|
||||
}
|
||||
|
||||
type paramSpec struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Type string `json:"type"`
|
||||
Check string `json:"check"`
|
||||
Default string `json:"default"`
|
||||
CLI cliSpec `json:"cli"` // cli-specific settings
|
||||
Env string `json:"env"` // environment variable name
|
||||
Required bool `json:"required"`
|
||||
S json.RawMessage `json:"spec"`
|
||||
}
|
||||
|
||||
func (p *paramSpec) common() paramCommon {
|
||||
return paramCommon{
|
||||
name: p.Name,
|
||||
descr: p.Description,
|
||||
check: p.Check,
|
||||
def: p.Default,
|
||||
cli: p.CLI,
|
||||
req: p.Required,
|
||||
env: p.Env,
|
||||
}
|
||||
}
|
||||
|
||||
type paramCommon struct {
|
||||
name string
|
||||
descr string
|
||||
check string
|
||||
req bool
|
||||
cli cliSpec
|
||||
def string
|
||||
env string
|
||||
}
|
||||
|
||||
func (p *paramCommon) EnvName() string {
|
||||
if p.env != "" {
|
||||
return p.env
|
||||
}
|
||||
return strings.ToUpper(p.name)
|
||||
}
|
||||
|
||||
func (p *paramCommon) CLIName() string {
|
||||
if p.cli.Name != "" {
|
||||
return p.cli.Name
|
||||
}
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *paramCommon) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *paramCommon) Description() string {
|
||||
return p.descr
|
||||
}
|
||||
|
||||
func (p *paramCommon) Check() string {
|
||||
return p.check
|
||||
}
|
||||
|
||||
func (p *paramCommon) Required() bool {
|
||||
return p.req
|
||||
}
|
||||
|
||||
func (p *paramCommon) Default() string {
|
||||
return p.def
|
||||
}
|
||||
|
||||
type cliSpec struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"` // type is either 'flag' or 'arg', 'flag is the default'
|
||||
}
|
||||
|
||||
func (s *paramSpec) Spec() paramSpec {
|
||||
return *s
|
||||
}
|
||||
|
||||
type kvSpec struct {
|
||||
Separator string `json:"separator"`
|
||||
Keys []paramSpec `json:"keys"`
|
||||
}
|
||||
|
||||
type enumSpec struct {
|
||||
Values []string `json:"values"`
|
||||
}
|
669
Godeps/_workspace/src/github.com/gravitational/configure/schema/schema.go
generated
vendored
Normal file
669
Godeps/_workspace/src/github.com/gravitational/configure/schema/schema.go
generated
vendored
Normal file
|
@ -0,0 +1,669 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure/cstrings"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
func ParseJSON(r io.Reader) (*Config, error) {
|
||||
var c *configV1
|
||||
|
||||
if err := json.NewDecoder(r).Decode(&c); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return newParser().parse(*c)
|
||||
}
|
||||
|
||||
func ParseVariablesJSON(r io.Reader) (*Config, error) {
|
||||
var variables []paramSpec
|
||||
|
||||
if err := json.NewDecoder(r).Decode(&variables); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return newParser().parse(configV1{Params: variables})
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Params []Param
|
||||
}
|
||||
|
||||
func (c *Config) Vars() map[string]string {
|
||||
vars := make(map[string]string, len(c.Params))
|
||||
for _, p := range c.Params {
|
||||
k, v := p.Vars()
|
||||
vars[k] = v
|
||||
}
|
||||
return vars
|
||||
}
|
||||
|
||||
func (c *Config) EnvVars() map[string]string {
|
||||
vars := make(map[string]string, len(c.Params))
|
||||
for _, p := range c.Params {
|
||||
k, v := p.EnvVars()
|
||||
vars[k] = v
|
||||
}
|
||||
return vars
|
||||
}
|
||||
|
||||
func (c *Config) Args() []string {
|
||||
args := []string{}
|
||||
for _, p := range c.Params {
|
||||
args = append(args, p.Args()...)
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
func (c *Config) ParseArgs(args []string) error {
|
||||
app := cliApp(c, false)
|
||||
_, err := app.Parse(args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Config) ParseEnv() error {
|
||||
app := cliApp(c, true)
|
||||
_, err := app.Parse([]string{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Config) ParseVars(vars map[string]string) error {
|
||||
for _, p := range c.Params {
|
||||
val, ok := vars[p.Name()]
|
||||
if !ok {
|
||||
if p.Required() {
|
||||
return trace.Errorf("missing value for required variable: %v", p.Name())
|
||||
} else {
|
||||
val = p.Default()
|
||||
}
|
||||
}
|
||||
if err := p.Set(val); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cliApp(c *Config, useEnv bool) *kingpin.Application {
|
||||
app := kingpin.New("app", "Orbit package configuration tool")
|
||||
|
||||
for _, p := range c.Params {
|
||||
cliFlag(app, p, useEnv)
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
func cliFlag(app *kingpin.Application, p Param, useEnv bool) {
|
||||
name := p.CLIName()
|
||||
f := app.Flag(name, p.Description())
|
||||
if p.Required() {
|
||||
f = f.Required()
|
||||
}
|
||||
if p.Default() != "" {
|
||||
f = f.Default(p.Default())
|
||||
}
|
||||
if useEnv {
|
||||
f.OverrideDefaultFromEnvar(p.EnvName())
|
||||
}
|
||||
SetParam(p, f)
|
||||
}
|
||||
|
||||
func SetParam(p Param, s kingpin.Settings) {
|
||||
s.SetValue(p)
|
||||
}
|
||||
|
||||
type Param interface {
|
||||
Name() string
|
||||
CLIName() string
|
||||
Description() string
|
||||
Check() string
|
||||
Required() bool
|
||||
Default() string
|
||||
|
||||
// New returns a new instance of the param identical to this
|
||||
New() Param
|
||||
|
||||
// Set is required to set parameters from command line string
|
||||
Set(string) error
|
||||
// String is required to output value to command line string
|
||||
String() string
|
||||
|
||||
// Args returns argument strings in cli format
|
||||
Args() []string
|
||||
|
||||
// Values returns a tuple with environment variable name and value
|
||||
EnvVars() (string, string)
|
||||
|
||||
// Vars returns a tuple with the variable name and value
|
||||
Vars() (string, string)
|
||||
|
||||
EnvName() string
|
||||
}
|
||||
|
||||
func newParser() *cparser {
|
||||
return &cparser{
|
||||
params: []Param{},
|
||||
}
|
||||
}
|
||||
|
||||
type cparser struct {
|
||||
params []Param
|
||||
}
|
||||
|
||||
func (p *cparser) parse(c configV1) (*Config, error) {
|
||||
cfg := &Config{
|
||||
Params: make([]Param, len(c.Params)),
|
||||
}
|
||||
// parse types
|
||||
if len(c.Params) != 0 {
|
||||
for i, ts := range c.Params {
|
||||
pr, err := p.parseParam(ts, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.Params[i] = pr
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (p *cparser) parseParam(s paramSpec, scalar bool) (Param, error) {
|
||||
if s.Name == "" {
|
||||
return nil, trace.Errorf("set a type name")
|
||||
}
|
||||
if err := p.checkName(s.Name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.Type == "" {
|
||||
return nil, trace.Errorf("set a type for '%v'", s.Name)
|
||||
}
|
||||
switch s.Type {
|
||||
case "String":
|
||||
pr := &StringParam{}
|
||||
pr.paramCommon = s.common()
|
||||
return pr, nil
|
||||
case "Path":
|
||||
pr := &PathParam{}
|
||||
pr.paramCommon = s.common()
|
||||
return pr, nil
|
||||
case "Int":
|
||||
pr := &IntParam{}
|
||||
pr.paramCommon = s.common()
|
||||
return pr, nil
|
||||
case "Bool":
|
||||
pr := &BoolParam{}
|
||||
pr.paramCommon = s.common()
|
||||
return pr, nil
|
||||
case "KeyVal":
|
||||
return p.parseKeyVal(s)
|
||||
case "Enum":
|
||||
return p.parseEnum(s)
|
||||
case "List":
|
||||
if scalar {
|
||||
return nil, trace.Errorf(
|
||||
"scalar values are not allowed here: '%v'", s.Type)
|
||||
}
|
||||
return p.parseList(s)
|
||||
}
|
||||
return nil, trace.Errorf("unrecognized type: '%v'", s.Type)
|
||||
}
|
||||
|
||||
func (p *cparser) parseList(s paramSpec) (Param, error) {
|
||||
var ps *paramSpec
|
||||
if err := json.Unmarshal(s.S, &ps); err != nil {
|
||||
return nil, trace.Wrap(err, "failed to parse: '%v'", string(s.S))
|
||||
}
|
||||
el, err := p.parseParam(*ps, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := &ListParam{el: el}
|
||||
l.paramCommon = s.common()
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (p *cparser) parseEnum(s paramSpec) (Param, error) {
|
||||
var e *enumSpec
|
||||
if err := json.Unmarshal(s.S, &e); err != nil {
|
||||
return nil, trace.Wrap(
|
||||
err, fmt.Sprintf("failed to parse: '%v'", string(s.S)))
|
||||
}
|
||||
if len(e.Values) == 0 {
|
||||
return nil, trace.Errorf("provide at least one value for '%v'", s.Name)
|
||||
}
|
||||
|
||||
values := make([]string, len(e.Values))
|
||||
seen := make(map[string]bool, len(e.Values))
|
||||
|
||||
for i, v := range e.Values {
|
||||
if v == "" {
|
||||
return nil, trace.Errorf("value can not be an empty string")
|
||||
}
|
||||
if seen[v] {
|
||||
return nil, trace.Errorf("duplicate value: '%v'", v)
|
||||
}
|
||||
values[i] = v
|
||||
}
|
||||
|
||||
ep := &EnumParam{values: values}
|
||||
ep.paramCommon = s.common()
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
func (p *cparser) parseKeyVal(s paramSpec) (Param, error) {
|
||||
var k *kvSpec
|
||||
if err := json.Unmarshal(s.S, &k); err != nil {
|
||||
return nil, trace.Wrap(
|
||||
err, fmt.Sprintf("failed to parse: '%v'", string(s.S)))
|
||||
}
|
||||
if len(k.Keys) == 0 {
|
||||
return nil, trace.Errorf("provide at least one key for '%v'", s.Name)
|
||||
}
|
||||
|
||||
keys := make([]Param, len(k.Keys))
|
||||
|
||||
for i, ks := range k.Keys {
|
||||
k, err := p.parseParam(ks, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys[i] = k
|
||||
}
|
||||
|
||||
if err := checkSameNames(keys); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kv := &KVParam{keys: keys, separator: k.Separator}
|
||||
kv.paramCommon = s.common()
|
||||
return kv, nil
|
||||
}
|
||||
|
||||
func (p *cparser) checkName(n string) error {
|
||||
for _, pr := range p.params {
|
||||
if pr.Name() == n {
|
||||
return trace.Errorf("parameter '%v' is already defined", n)
|
||||
}
|
||||
}
|
||||
e, err := parser.ParseExpr(n)
|
||||
if err != nil {
|
||||
return trace.Wrap(
|
||||
err, fmt.Sprintf("failed to parse name: '%v'", n))
|
||||
}
|
||||
if _, ok := e.(*ast.Ident); !ok {
|
||||
return trace.Wrap(
|
||||
err, fmt.Sprintf("name should be a valid identifier: '%v'", n))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkSameNames(ps []Param) error {
|
||||
n := map[string]bool{}
|
||||
for _, p := range ps {
|
||||
if n[p.Name()] {
|
||||
return trace.Errorf("parameter '%v' is already defined", n)
|
||||
}
|
||||
n[p.Name()] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PathParam struct {
|
||||
paramCommon
|
||||
val *string
|
||||
}
|
||||
|
||||
func (p *PathParam) New() Param {
|
||||
return &PathParam{p.paramCommon, nil}
|
||||
}
|
||||
|
||||
func (p *PathParam) Args() []string {
|
||||
return []string{fmt.Sprintf("--%v", p.CLIName()), p.String()}
|
||||
}
|
||||
|
||||
func (p *PathParam) EnvVars() (string, string) {
|
||||
return p.EnvName(), p.String()
|
||||
}
|
||||
|
||||
func (p *PathParam) Vars() (string, string) {
|
||||
return p.Name(), p.String()
|
||||
}
|
||||
|
||||
func (p *PathParam) Set(s string) error {
|
||||
p.val = &s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PathParam) String() string {
|
||||
if p.val == nil {
|
||||
return p.Default()
|
||||
}
|
||||
return *p.val
|
||||
}
|
||||
|
||||
type StringParam struct {
|
||||
paramCommon
|
||||
val *string
|
||||
}
|
||||
|
||||
func (p *StringParam) New() Param {
|
||||
return &StringParam{p.paramCommon, nil}
|
||||
}
|
||||
|
||||
func (p *StringParam) Set(s string) error {
|
||||
p.val = &s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *StringParam) String() string {
|
||||
if p.val == nil {
|
||||
return p.Default()
|
||||
}
|
||||
return *p.val
|
||||
}
|
||||
|
||||
func (p *StringParam) Args() []string {
|
||||
return []string{fmt.Sprintf("--%v", p.CLIName()), p.String()}
|
||||
}
|
||||
|
||||
func (p *StringParam) EnvVars() (string, string) {
|
||||
return p.EnvName(), p.String()
|
||||
}
|
||||
|
||||
func (p *StringParam) Vars() (string, string) {
|
||||
return p.Name(), p.String()
|
||||
}
|
||||
|
||||
type BoolParam struct {
|
||||
paramCommon
|
||||
val *bool
|
||||
}
|
||||
|
||||
func (p *BoolParam) New() Param {
|
||||
return &BoolParam{p.paramCommon, nil}
|
||||
}
|
||||
|
||||
func (p *BoolParam) Vars() (string, string) {
|
||||
return p.Name(), p.String()
|
||||
}
|
||||
|
||||
func (p *BoolParam) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.val = &v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *BoolParam) String() string {
|
||||
if p.val == nil {
|
||||
return "false"
|
||||
}
|
||||
return fmt.Sprintf("%v", *p.val)
|
||||
}
|
||||
|
||||
func (p *BoolParam) Args() []string {
|
||||
return []string{fmt.Sprintf("--%v", p.CLIName()), p.String()}
|
||||
}
|
||||
|
||||
func (p *BoolParam) EnvVars() (string, string) {
|
||||
return p.EnvName(), p.String()
|
||||
}
|
||||
|
||||
type IntParam struct {
|
||||
paramCommon
|
||||
val *int64
|
||||
}
|
||||
|
||||
func (p *IntParam) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.val = &v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *IntParam) String() string {
|
||||
if p.val == nil {
|
||||
return p.Default()
|
||||
}
|
||||
return fmt.Sprintf("%v", *p.val)
|
||||
}
|
||||
|
||||
func (p *IntParam) New() Param {
|
||||
return &IntParam{p.paramCommon, nil}
|
||||
}
|
||||
|
||||
func (p *IntParam) Args() []string {
|
||||
return []string{fmt.Sprintf("--%v", p.CLIName()), p.String()}
|
||||
}
|
||||
|
||||
func (p *IntParam) EnvVars() (string, string) {
|
||||
return p.EnvName(), p.String()
|
||||
}
|
||||
|
||||
func (p *IntParam) Vars() (string, string) {
|
||||
return p.Name(), p.String()
|
||||
}
|
||||
|
||||
type ListParam struct {
|
||||
paramCommon
|
||||
el Param
|
||||
values []Param
|
||||
}
|
||||
|
||||
func (p *ListParam) CLIName() string {
|
||||
return p.el.CLIName()
|
||||
}
|
||||
|
||||
func (p *ListParam) EnvName() string {
|
||||
return p.el.EnvName()
|
||||
}
|
||||
|
||||
func (p *ListParam) Set(s string) error {
|
||||
// this is to support setting from environment variables
|
||||
values := cstrings.Split(',', '\\', s)
|
||||
for _, v := range values {
|
||||
el := p.el.New()
|
||||
if err := el.Set(v); err != nil {
|
||||
return err
|
||||
}
|
||||
p.values = append(p.values, el)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ListParam) New() Param {
|
||||
return &ListParam{p.paramCommon, p.el, nil}
|
||||
}
|
||||
|
||||
func (p *ListParam) String() string {
|
||||
if len(p.values) == 0 {
|
||||
return p.Default()
|
||||
}
|
||||
out := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
out[i] = v.String()
|
||||
}
|
||||
return fmt.Sprintf("[%v]", strings.Join(out, ","))
|
||||
}
|
||||
|
||||
func (p *ListParam) Args() []string {
|
||||
if len(p.values) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
out := make([]string, 0, len(p.values))
|
||||
for _, v := range p.values {
|
||||
out = append(out, v.Args()...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (p *ListParam) EnvVars() (string, string) {
|
||||
if len(p.values) == 0 {
|
||||
return p.EnvName(), p.Default()
|
||||
}
|
||||
out := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
_, out[i] = v.EnvVars()
|
||||
}
|
||||
return p.el.EnvName(), strings.Join(out, ",")
|
||||
}
|
||||
|
||||
func (p *ListParam) Vars() (string, string) {
|
||||
if len(p.values) == 0 {
|
||||
return p.Name(), p.Default()
|
||||
}
|
||||
out := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
_, out[i] = v.EnvVars()
|
||||
}
|
||||
return p.Name(), strings.Join(out, ",")
|
||||
}
|
||||
|
||||
type KVParam struct {
|
||||
paramCommon
|
||||
separator string
|
||||
keys []Param
|
||||
values []Param
|
||||
}
|
||||
|
||||
func (p *KVParam) sep() string {
|
||||
if p.separator == "" {
|
||||
return ":"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *KVParam) Set(s string) error {
|
||||
sep := p.sep()
|
||||
|
||||
parts := strings.Split(s, sep)
|
||||
if len(parts) != len(p.keys) {
|
||||
return trace.Errorf(
|
||||
"expected elements separated by '%v', got '%v'", sep, s)
|
||||
}
|
||||
values := make([]Param, len(p.keys))
|
||||
for i, pt := range parts {
|
||||
el := p.keys[i].New()
|
||||
if err := el.Set(pt); err != nil {
|
||||
return err
|
||||
}
|
||||
values[i] = el
|
||||
}
|
||||
|
||||
p.values = values
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *KVParam) String() string {
|
||||
if len(p.values) == 0 {
|
||||
return p.Default()
|
||||
}
|
||||
out := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
out[i] = v.String()
|
||||
}
|
||||
return fmt.Sprintf("{%v}", strings.Join(out, p.sep()))
|
||||
}
|
||||
|
||||
func (p *KVParam) New() Param {
|
||||
keys := make([]Param, len(p.keys))
|
||||
for i, k := range p.keys {
|
||||
keys[i] = k.New()
|
||||
}
|
||||
return &KVParam{p.paramCommon, p.separator, keys, nil}
|
||||
}
|
||||
|
||||
func (p *KVParam) Args() []string {
|
||||
if len(p.values) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
vals := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
vals[i] = v.String()
|
||||
}
|
||||
return []string{
|
||||
fmt.Sprintf("--%v", p.CLIName()), strings.Join(vals, p.sep())}
|
||||
}
|
||||
|
||||
func (p *KVParam) EnvVars() (string, string) {
|
||||
if len(p.values) == 0 {
|
||||
return p.EnvName(), p.Default()
|
||||
}
|
||||
vals := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
vals[i] = v.String()
|
||||
}
|
||||
return p.EnvName(), strings.Join(vals, p.sep())
|
||||
}
|
||||
|
||||
func (p *KVParam) Vars() (string, string) {
|
||||
if len(p.values) == 0 {
|
||||
return p.Name(), p.Default()
|
||||
}
|
||||
vals := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
vals[i] = v.String()
|
||||
}
|
||||
return p.Name(), strings.Join(vals, p.sep())
|
||||
}
|
||||
|
||||
type EnumParam struct {
|
||||
paramCommon
|
||||
values []string
|
||||
value *string
|
||||
}
|
||||
|
||||
func (p *EnumParam) Set(s string) error {
|
||||
found := false
|
||||
for _, v := range p.values {
|
||||
if s == v {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return trace.Errorf(
|
||||
"value '%v' is not one of the allowed '%v'",
|
||||
s, strings.Join(p.values, ","),
|
||||
)
|
||||
}
|
||||
p.value = &s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *EnumParam) String() string {
|
||||
if p.value == nil {
|
||||
return p.Default()
|
||||
}
|
||||
return *p.value
|
||||
}
|
||||
|
||||
func (p *EnumParam) New() Param {
|
||||
return &EnumParam{p.paramCommon, p.values, nil}
|
||||
}
|
||||
|
||||
func (p *EnumParam) Args() []string {
|
||||
if p.value == nil {
|
||||
return []string{}
|
||||
}
|
||||
return []string{fmt.Sprintf("--%v", p.CLIName()), *p.value}
|
||||
}
|
||||
|
||||
func (p *EnumParam) EnvVars() (string, string) {
|
||||
return p.EnvName(), p.String()
|
||||
}
|
||||
|
||||
func (p *EnumParam) Vars() (string, string) {
|
||||
return p.Name(), p.String()
|
||||
}
|
487
Godeps/_workspace/src/github.com/gravitational/configure/schema/schema_test.go
generated
vendored
Normal file
487
Godeps/_workspace/src/github.com/gravitational/configure/schema/schema_test.go
generated
vendored
Normal file
|
@ -0,0 +1,487 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
"github.com/kylelemons/godebug/diff"
|
||||
|
||||
. "github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func TestConfig(t *testing.T) { TestingT(t) }
|
||||
|
||||
type ConfigSuite struct {
|
||||
}
|
||||
|
||||
var _ = Suite(&ConfigSuite{})
|
||||
|
||||
func (s *ConfigSuite) TestParseTypes(c *C) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
cfg string
|
||||
expect *Config
|
||||
}{
|
||||
{
|
||||
name: "string param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "string1",
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&StringParam{paramCommon{name: "string1"}, nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bool param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "bool1",
|
||||
"type": "Bool"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&BoolParam{paramCommon{name: "bool1"}, nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "enum param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "enum1",
|
||||
"type": "Enum",
|
||||
"spec": {
|
||||
"values": ["a", "b"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&EnumParam{paramCommon{name: "enum1"}, []string{"a", "b"}, nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "key val param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "kv1",
|
||||
"type": "KeyVal",
|
||||
"default": "path1:hello",
|
||||
"required": true,
|
||||
"spec": {
|
||||
"separator": ":",
|
||||
"keys": [
|
||||
{"type": "Path", "name": "path1"},
|
||||
{"type": "Path", "name": "path2"}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&KVParam{
|
||||
paramCommon{name: "kv1", req: true, def: "path1:hello"},
|
||||
":",
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "path1"}, nil},
|
||||
&PathParam{paramCommon{name: "path2"}, nil},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list key val param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "mounts",
|
||||
"type": "List",
|
||||
"spec": {
|
||||
"name": "volume",
|
||||
"type": "KeyVal",
|
||||
"spec": {
|
||||
"separator": ":",
|
||||
"keys": [
|
||||
{"type": "Path", "name": "path1"},
|
||||
{"type": "Path", "name": "path2"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&ListParam{
|
||||
paramCommon{name: "mounts"},
|
||||
&KVParam{
|
||||
paramCommon{name: "volume"},
|
||||
":",
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "path1"}, nil},
|
||||
&PathParam{paramCommon{name: "path2"}, nil},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, tc := range tcs {
|
||||
comment := Commentf("test #%d (%v) cfg=%v, param=%v", i+1, tc.name, tc.cfg)
|
||||
cfg, err := ParseJSON(strings.NewReader(tc.cfg))
|
||||
c.Assert(err, IsNil, comment)
|
||||
c.Assert(len(cfg.Params), Equals, len(tc.expect.Params))
|
||||
for i, _ := range cfg.Params {
|
||||
c.Assert(cfg.Params[i], DeepEquals, tc.expect.Params[i], comment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ConfigSuite) TestArgs(c *C) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
cfg string
|
||||
expect *Config
|
||||
expectErr bool
|
||||
args []string
|
||||
vars map[string]string
|
||||
}{
|
||||
{
|
||||
name: "string param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "string1",
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&StringParam{paramCommon{name: "string1"}, str("val1")},
|
||||
},
|
||||
},
|
||||
args: []string{"--string1", "val1"},
|
||||
vars: map[string]string{"STRING1": "val1"},
|
||||
},
|
||||
{
|
||||
name: "check defaults",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "string1",
|
||||
"type": "String",
|
||||
"default": "default value"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&StringParam{
|
||||
paramCommon{name: "string1", def: "default value"},
|
||||
str("default value")},
|
||||
},
|
||||
},
|
||||
args: []string{},
|
||||
vars: map[string]string{"STRING1": "default value"},
|
||||
},
|
||||
{
|
||||
name: "check missing required param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "string1",
|
||||
"type": "String",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expectErr: true,
|
||||
args: []string{},
|
||||
},
|
||||
{
|
||||
name: "check key values",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "volume",
|
||||
"env": "PREFIX_VOLUME",
|
||||
"type": "KeyVal",
|
||||
"spec": {
|
||||
"keys": [
|
||||
{"name": "src", "type":"Path"},
|
||||
{"name": "dst", "type":"Path"}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
args: []string{"--volume", "/tmp/hello:/var/hello"},
|
||||
vars: map[string]string{"PREFIX_VOLUME": "/tmp/hello:/var/hello"},
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&KVParam{
|
||||
paramCommon{name: "volume", env: "PREFIX_VOLUME"},
|
||||
"",
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "src"}, nil},
|
||||
&PathParam{paramCommon{name: "dst"}, nil},
|
||||
},
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "src"}, str("/tmp/hello")},
|
||||
&PathParam{paramCommon{name: "dst"}, str("/var/hello")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list of key values",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"type": "List",
|
||||
"name": "mounts",
|
||||
"spec": {
|
||||
"name": "volume",
|
||||
"type": "KeyVal",
|
||||
"spec": {
|
||||
"keys": [
|
||||
{"name": "src", "type":"Path"},
|
||||
{"name": "dst", "type":"Path"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
args: []string{"--volume", "/tmp/hello:/var/hello"},
|
||||
vars: map[string]string{"VOLUME": "/tmp/hello:/var/hello"},
|
||||
expect: &Config{
|
||||
Params: []Param{
|
||||
&ListParam{
|
||||
paramCommon{name: "mounts"},
|
||||
&KVParam{
|
||||
paramCommon{name: "volume"},
|
||||
"",
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "src"}, nil},
|
||||
&PathParam{paramCommon{name: "dst"}, nil},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
[]Param{
|
||||
&KVParam{
|
||||
paramCommon{name: "volume"},
|
||||
"",
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "src"}, nil},
|
||||
&PathParam{paramCommon{name: "dst"}, nil},
|
||||
},
|
||||
[]Param{
|
||||
&PathParam{paramCommon{name: "src"}, str("/tmp/hello")},
|
||||
&PathParam{paramCommon{name: "dst"}, str("/var/hello")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, tc := range tcs {
|
||||
comment := Commentf(
|
||||
"test #%d (%v) cfg=%v, args=%v", i+1, tc.name, tc.cfg, tc.args)
|
||||
cfg, err := ParseJSON(strings.NewReader(tc.cfg))
|
||||
c.Assert(err, IsNil, comment)
|
||||
|
||||
if tc.expectErr {
|
||||
c.Assert(cfg.ParseArgs(tc.args), NotNil)
|
||||
continue
|
||||
}
|
||||
|
||||
// make sure all the values have been parsed
|
||||
c.Assert(cfg.ParseArgs(tc.args), IsNil)
|
||||
c.Assert(len(cfg.Params), Equals, len(tc.expect.Params))
|
||||
for i, _ := range cfg.Params {
|
||||
comment := Commentf(
|
||||
"test #%d (%v) cfg=%v, args=%v\n%v",
|
||||
i+1, tc.name, tc.cfg, tc.args,
|
||||
diff.Diff(
|
||||
fmt.Sprintf("%# v", pretty.Formatter(cfg.Params[i])),
|
||||
fmt.Sprintf("%# v", pretty.Formatter(tc.expect.Params[i]))),
|
||||
)
|
||||
c.Assert(cfg.Params[i], DeepEquals, tc.expect.Params[i], comment)
|
||||
}
|
||||
|
||||
// make sure args are equivalent to the passed arguments
|
||||
if len(tc.args) != 0 {
|
||||
args := cfg.Args()
|
||||
c.Assert(args, DeepEquals, tc.args, comment)
|
||||
}
|
||||
|
||||
// make sure vars are what we expect them to be
|
||||
if len(tc.vars) != 0 {
|
||||
c.Assert(cfg.EnvVars(), DeepEquals, tc.vars, comment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ConfigSuite) TestEnvVars(c *C) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
cfg string
|
||||
expect map[string]string
|
||||
}{
|
||||
{
|
||||
name: "string param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"env": "ENV_STRING1",
|
||||
"name": "string1",
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: map[string]string{"ENV_STRING1": "val1"},
|
||||
},
|
||||
{
|
||||
name: "list of key values",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"type": "List",
|
||||
"name": "mounts",
|
||||
"spec": {
|
||||
"name": "volume",
|
||||
"env": "PREFIX_VOLUME",
|
||||
"type": "KeyVal",
|
||||
"spec": {
|
||||
"keys": [
|
||||
{"name": "src", "type":"Path"},
|
||||
{"name": "dst", "type":"Path"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: map[string]string{
|
||||
"PREFIX_VOLUME": "/tmp/hello:/var/hello,/tmp/hello1:/var/hello2",
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, tc := range tcs {
|
||||
comment := Commentf(
|
||||
"test #%d (%v) cfg=%v", i+1, tc.name, tc.cfg)
|
||||
cfg, err := ParseJSON(strings.NewReader(tc.cfg))
|
||||
c.Assert(err, IsNil, comment)
|
||||
|
||||
os.Clearenv()
|
||||
for k, v := range tc.expect {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
c.Assert(cfg.ParseEnv(), IsNil)
|
||||
c.Assert(cfg.EnvVars(), DeepEquals, tc.expect, comment)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ConfigSuite) TestParseVars(c *C) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
cfg string
|
||||
expect map[string]string
|
||||
}{
|
||||
{
|
||||
name: "string param",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"env": "ENV_STRING1",
|
||||
"name": "string1",
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: map[string]string{"string1": "val1"},
|
||||
},
|
||||
{
|
||||
name: "int param default",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"name": "int1",
|
||||
"type": "Int",
|
||||
"default": "-1"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: map[string]string{"int1": "-1"},
|
||||
},
|
||||
{
|
||||
name: "list of key values",
|
||||
cfg: `{
|
||||
"params": [
|
||||
{
|
||||
"type": "List",
|
||||
"name": "mounts",
|
||||
"spec": {
|
||||
"name": "volume",
|
||||
"type": "KeyVal",
|
||||
"spec": {
|
||||
"keys": [
|
||||
{"name": "src", "type":"Path"},
|
||||
{"name": "dst", "type":"Path"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expect: map[string]string{
|
||||
"mounts": "/tmp/hello:/var/hello,/tmp/hello1:/var/hello2",
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, tc := range tcs {
|
||||
comment := Commentf(
|
||||
"test #%d (%v) cfg=%v", i+1, tc.name, tc.cfg)
|
||||
cfg, err := ParseJSON(strings.NewReader(tc.cfg))
|
||||
c.Assert(err, IsNil, comment)
|
||||
|
||||
vars := make(map[string]string)
|
||||
for k, v := range tc.expect {
|
||||
vars[k] = v
|
||||
}
|
||||
c.Assert(cfg.ParseVars(vars), IsNil)
|
||||
c.Assert(cfg.Vars(), DeepEquals, tc.expect, comment)
|
||||
}
|
||||
}
|
||||
|
||||
func str(val string) *string {
|
||||
return &val
|
||||
}
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/gravitational/teleport/lib/utils"
|
||||
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure/cstrings"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
|
@ -169,7 +170,7 @@ type ReverseTunnelConfig struct {
|
|||
type NetAddrSlice []utils.NetAddr
|
||||
|
||||
func (s *NetAddrSlice) Set(val string) error {
|
||||
values := configure.SplitComma(val)
|
||||
values := cstrings.SplitComma(val)
|
||||
out := make([]utils.NetAddr, len(values))
|
||||
for i, v := range values {
|
||||
a, err := utils.ParseAddr(v)
|
||||
|
@ -189,7 +190,7 @@ func (kv *KeyVal) Set(v string) error {
|
|||
if len(*kv) == 0 {
|
||||
*kv = make(map[string]string)
|
||||
}
|
||||
for _, i := range configure.SplitComma(v) {
|
||||
for _, i := range cstrings.SplitComma(v) {
|
||||
vals := strings.SplitN(i, ":", 2)
|
||||
if len(vals) != 2 {
|
||||
return trace.Errorf("extra options should be defined like KEY:VAL")
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/configure/cstrings"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
|
@ -60,7 +60,7 @@ func (c *ctx) Env(key string) (string, error) {
|
|||
if !ok {
|
||||
return "", trace.Errorf("environment variable '%v' is not set", key)
|
||||
}
|
||||
values := configure.SplitComma(v)
|
||||
values := cstrings.SplitComma(v)
|
||||
out := make([]string, len(values))
|
||||
for i, p := range values {
|
||||
out[i] = quoteYAML(p)
|
||||
|
|
Loading…
Reference in a new issue