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  }