github.com/influxdata/influxdb/v2@v2.7.6/kit/feature/override/override.go (about)

     1  package override
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/influxdata/influxdb/v2/kit/feature"
    10  )
    11  
    12  // Flagger can override default flag values.
    13  type Flagger struct {
    14  	overrides map[string]string
    15  	byKey     feature.ByKeyFn
    16  }
    17  
    18  // Make a Flagger that returns defaults with any overrides parsed from the string.
    19  func Make(overrides map[string]string, byKey feature.ByKeyFn) (Flagger, error) {
    20  	if byKey == nil {
    21  		byKey = feature.ByKey
    22  	}
    23  
    24  	// Check all provided override keys correspond to an existing Flag.
    25  	var missing []string
    26  	for k := range overrides {
    27  		if _, found := byKey(k); !found {
    28  			missing = append(missing, k)
    29  		}
    30  	}
    31  	if len(missing) > 0 {
    32  		return Flagger{}, fmt.Errorf("configured overrides for non-existent flags: %s", strings.Join(missing, ","))
    33  	}
    34  
    35  	return Flagger{
    36  		overrides: overrides,
    37  		byKey:     byKey,
    38  	}, nil
    39  }
    40  
    41  // Flags returns a map of default values with overrides applied. It never returns an error.
    42  func (f Flagger) Flags(_ context.Context, flags ...feature.Flag) (map[string]interface{}, error) {
    43  	if len(flags) == 0 {
    44  		flags = feature.Flags()
    45  	}
    46  
    47  	m := make(map[string]interface{}, len(flags))
    48  	for _, flag := range flags {
    49  		if s, overridden := f.overrides[flag.Key()]; overridden {
    50  			iface, err := f.coerce(s, flag)
    51  			if err != nil {
    52  				return nil, err
    53  			}
    54  			m[flag.Key()] = iface
    55  		} else {
    56  			m[flag.Key()] = flag.Default()
    57  		}
    58  	}
    59  
    60  	return m, nil
    61  }
    62  
    63  func (f Flagger) coerce(s string, flag feature.Flag) (iface interface{}, err error) {
    64  	if base, ok := flag.(feature.Base); ok {
    65  		flag, _ = f.byKey(base.Key())
    66  	}
    67  
    68  	switch flag.Default().(type) {
    69  	case bool:
    70  		iface, err = strconv.ParseBool(s)
    71  	case int32:
    72  		iface, err = strconv.Atoi(s)
    73  	case float64:
    74  		iface, err = strconv.ParseFloat(s, 64)
    75  	default:
    76  		iface = s
    77  	}
    78  
    79  	if err != nil {
    80  		return nil, fmt.Errorf("coercing string %q based on flag type %T: %v", s, flag, err)
    81  	}
    82  	return
    83  }