diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 926a3ac58..dd9153d69 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,9 +1,6 @@ { "ImportPath": "github.com/kelseyhightower/confd", "GoVersion": "go1.3", - "Packages": [ - "." - ], "Deps": [ { "ImportPath": "github.com/BurntSushi/toml", @@ -20,7 +17,7 @@ }, { "ImportPath": "github.com/kelseyhightower/memkv", - "Rev": "752d630b47eca8d5b192402b3dae6df6049391cc" + "Rev": "1204f2b3fda3ac05014e637a7ad78e9049a691fa" } ] } diff --git a/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store.go b/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store.go index b36c70d3d..302eb57e0 100644 --- a/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store.go +++ b/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store.go @@ -9,6 +9,7 @@ import ( "errors" "path/filepath" "sort" + "strings" "sync" ) @@ -90,6 +91,46 @@ func (s Store) GetAllValues(pattern string) ([]string, error) { return vs, nil } +func (s Store) List(path string) []string { + vs := make([]string, 0) + m := make(map[string]bool) + s.RLock() + defer s.RUnlock() + for _, kv := range s.m { + if strings.HasPrefix(kv.Key, path) { + strippedKey := strings.TrimPrefix(kv.Key, path) + m[strings.SplitN(strippedKey[1:], "/", 2)[0]] = true + } + } + for k := range m { + vs = append(vs, k) + } + sort.Strings(vs) + return vs +} + +func (s Store) ListDir(path string) []string { + vs := make([]string, 0) + m := make(map[string]bool) + s.RLock() + defer s.RUnlock() + for _, kv := range s.m { + if strings.HasPrefix(kv.Key, path) { + strippedKey := strings.TrimPrefix(kv.Key, path) + items := strings.SplitN(strippedKey[1:], "/", 2) + if len(items) < 2 { + continue + } + m[items[0]] = true + } + } + for k := range m { + vs = append(vs, k) + } + sort.Strings(vs) + return vs +} + // Set sets the KVPair entry associated with key to value. func (s Store) Set(key string, value string) { s.Lock() diff --git a/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store_test.go b/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store_test.go index 12a7f2d63..d5a6c016e 100644 --- a/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store_test.go +++ b/Godeps/_workspace/src/github.com/kelseyhightower/memkv/store_test.go @@ -92,3 +92,39 @@ func TestDel(t *testing.T) { } s.Del("/app/port") } + +var listTestMap = map[string]string{ + "/deis/database/user": "user", + "/deis/database/pass": "pass", + "/deis/services/key": "value", + "/deis/services/notaservice/foo": "bar", + "/deis/services/srv1/node1": "10.244.1.1:80", + "/deis/services/srv1/node2": "10.244.1.2:80", + "/deis/services/srv1/node3": "10.244.1.3:80", + "/deis/services/srv2/node1": "10.244.2.1:80", + "/deis/services/srv2/node2": "10.244.2.2:80", +} + +func TestList(t *testing.T) { + s := New() + for k, v := range listTestMap { + s.Set(k, v) + } + want := []string{"key", "notaservice", "srv1", "srv2"} + got := s.List("/deis/services") + if !reflect.DeepEqual(got, want) { + t.Errorf("List(%s) = %v, want %v", "/deis/services", got, want) + } +} + +func TestListDir(t *testing.T) { + s := New() + for k, v := range listTestMap { + s.Set(k, v) + } + want := []string{"notaservice", "srv1", "srv2"} + got := s.ListDir("/deis/services") + if !reflect.DeepEqual(got, want) { + t.Errorf("List(%s) = %v, want %v", "/deis/services", got, want) + } +} diff --git a/docs/templates.md b/docs/templates.md index a26933d41..ccb641181 100644 --- a/docs/templates.md +++ b/docs/templates.md @@ -20,7 +20,7 @@ Alias for the path.Base function. ### get -Returns the KVPair where key matches its argument. +Returns the KVPair where key matches its argument. Returns an error if key is not found. ``` {{with get "/key"}} @@ -31,7 +31,7 @@ Returns the KVPair where key matches its argument. ### gets -Returns all KVPair, []KVPair, where key matches its argument. +Returns all KVPair, []KVPair, where key matches its argument. Returns an error if key is not found. ``` {{range gets "/*"}} @@ -42,7 +42,7 @@ Returns all KVPair, []KVPair, where key matches its argument. ### getv -Returns the value as a string where key matches its argument. +Returns the value as a string where key matches its argument. Returns an error if key is not found. ``` value: {{getv "/key"}} @@ -50,7 +50,7 @@ value: {{getv "/key"}} ### getvs -Returns all values, []string, where key matches its argument. +Returns all values, []string, where key matches its argument. Returns an error if key is not found. ``` {{range getvs "/*"}} @@ -58,6 +58,26 @@ Returns all values, []string, where key matches its argument. {{end}} ``` +### ls + +Returns all subkeys, []string, where path matches its argument. Returns an empty list if path is not found. + +``` +{{range ls "/deis/services"}} + value: {{.}} +{{end}} +``` + +### lsdir + +Returns all subkeys, []string, where path matches its argument. It only returns subkeys that also have subkeys. Returns an empty list if path is not found. + +``` +{{range lsdir "/deis/services"}} + value: {{.}} +{{end}} +``` + ## Example Usage ```Bash diff --git a/resource/template/resource.go b/resource/template/resource.go index 6d5e6e0a1..c6baafe34 100644 --- a/resource/template/resource.go +++ b/resource/template/resource.go @@ -119,14 +119,16 @@ func (t *TemplateResource) createStageFile() error { // Add template functions tplFuncMap := make(template.FuncMap) tplFuncMap["base"] = path.Base - tplFuncMap["parent"] = path.Dir - tplFuncMap["sibling"] = t.GetSibling + tplFuncMap["ls"] = t.store.List + tplFuncMap["lsdir"] = t.store.ListDir tplFuncMap["get"] = t.store.Get tplFuncMap["gets"] = t.store.GetAll tplFuncMap["getv"] = t.store.GetValue tplFuncMap["getvs"] = t.store.GetAllValues tplFuncMap["json"] = t.UnmarshalJsonObject tplFuncMap["jsonArray"] = t.UnmarshalJsonArray + tplFuncMap["sibling"] = t.GetSibling + tplFuncMap["parent"] = path.Dir tmpl := template.Must(template.New(path.Base(t.Src)).Funcs(tplFuncMap).ParseFiles(t.Src)) if err = tmpl.Execute(temp, nil); err != nil {