vitess.io/vitess@v0.16.2/go/vt/topo/k8stopo/directory.go (about) 1 /* 2 Copyright 2020 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreedto in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package k8stopo 18 19 import ( 20 "path/filepath" 21 "sort" 22 "strings" 23 24 "context" 25 26 "vitess.io/vitess/go/vt/log" 27 "vitess.io/vitess/go/vt/topo" 28 vtv1beta1 "vitess.io/vitess/go/vt/topo/k8stopo/apis/topo/v1beta1" 29 ) 30 31 // ListDir is part of the topo.Conn interface. 32 // It uses an internal cache to find all the objects matching a specific key and returns 33 // a slice of results sorted alphabetically to emulate the behavior of etcd, zk, consul, etc 34 func (s *Server) ListDir(ctx context.Context, dirPath string, full bool) ([]topo.DirEntry, error) { 35 dirPath = filepath.Join(s.root, dirPath) 36 37 log.V(7).Infof("Listing dir at: '%s', full: %v", dirPath, full) 38 39 dirMap := map[string]topo.DirEntry{} 40 41 if children, err := s.memberIndexer.ByIndex("by_parent", dirPath); err == nil { 42 for _, obj := range children { 43 vtn := obj.(*vtv1beta1.VitessTopoNode) 44 45 key := vtn.Data.Key 46 47 // skip duplicates 48 if _, ok := dirMap[key]; ok { 49 continue 50 } 51 52 // new empty entry 53 e := topo.DirEntry{ 54 Ephemeral: vtn.Data.Ephemeral, 55 } 56 57 // Clean dirPath from key to get name 58 key = strings.TrimPrefix(key, dirPath+"/") 59 60 // If the key represents a directory 61 if strings.Contains(key, "/") { 62 if full { 63 e.Type = topo.TypeDirectory 64 } 65 66 // get first part of path as name 67 key = strings.Split(filepath.Dir(key), "/")[0] 68 } else if full { 69 e.Type = topo.TypeFile 70 } 71 72 // set name 73 e.Name = key 74 75 // add to results 76 dirMap[e.Name] = e 77 } 78 } else { 79 return nil, err 80 } 81 82 // An empty map means not found 83 if len(dirMap) == 0 { 84 return nil, topo.NewError(topo.NoNode, dirPath) 85 } 86 87 // Get slice of keys 88 var keys []string 89 for key := range dirMap { 90 keys = append(keys, key) 91 } 92 93 // sort keys 94 sort.Strings(keys) 95 96 // Get ordered result 97 var result []topo.DirEntry 98 for _, k := range keys { 99 result = append(result, dirMap[k]) 100 } 101 102 return result, nil 103 }