func (c *threadSafeMap) AddIndexers(newIndexers Indexers) error { c.lock.Lock() defer c.lock.Unlock() if len(c.items) > 0 { return fmt.Errorf("cannot add indexers to running index") } oldKeys := sets.StringKeySet(c.indexers) newKeys := sets.StringKeySet(newIndexers) if oldKeys.HasAny(newKeys.List()...) { return fmt.Errorf("indexer conflict: %v", oldKeys.Intersection(newKeys)) } for k, v := range newIndexers { c.indexers[k] = v } return nil }
func newNavigationSteps(path string) (*navigationSteps, error) { steps := []navigationStep{} individualParts := strings.Split(path, ".") currType := reflect.TypeOf(clientcmdapi.Config{}) currPartIndex := 0 for currPartIndex < len(individualParts) { switch currType.Kind() { case reflect.Map: // if we're in a map, we need to locate a name. That name may contain dots, so we need to know what tokens are legal for the map's value type // for example, we could have a set request like: `set clusters.10.10.12.56.insecure-skip-tls-verify true`. We enter this case with // steps representing 10, 10, 12, 56, insecure-skip-tls-verify. The name is "10.10.12.56", so we want to collect all those parts together and // store them as a single step. In order to do that, we need to determine what set of tokens is a legal step AFTER the name of the map key // This set of reflective code pulls the type of the map values, uses that type to look up the set of legal tags. Those legal tags are used to // walk the list of remaining parts until we find a match to a legal tag or the end of the string. That name is used to burn all the used parts. mapValueType := currType.Elem().Elem() mapValueOptions, err := getPotentialTypeValues(mapValueType) if err != nil { return nil, err } nextPart := findNameStep(individualParts[currPartIndex:], sets.StringKeySet(mapValueOptions)) steps = append(steps, navigationStep{nextPart, mapValueType}) currPartIndex += len(strings.Split(nextPart, ".")) currType = mapValueType case reflect.Struct: nextPart := individualParts[currPartIndex] options, err := getPotentialTypeValues(currType) if err != nil { return nil, err } fieldType, exists := options[nextPart] if !exists { return nil, fmt.Errorf("unable to parse %v after %v at %v", path, steps, currType) } steps = append(steps, navigationStep{nextPart, fieldType}) currPartIndex += len(strings.Split(nextPart, ".")) currType = fieldType } } return &navigationSteps{steps, 0}, nil }