...

Source file src/github.com/ory/x/configx/options.go

Documentation: github.com/ory/x/configx

     1  package configx
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  
    10  	"github.com/spf13/pflag"
    11  
    12  	"github.com/ory/jsonschema/v3"
    13  	"github.com/ory/x/logrusx"
    14  
    15  	"github.com/knadh/koanf"
    16  
    17  	"github.com/ory/x/watcherx"
    18  )
    19  
    20  type (
    21  	OptionModifier func(p *Provider)
    22  )
    23  
    24  func WithContext(ctx context.Context) OptionModifier {
    25  	return func(p *Provider) {
    26  		p.originalContext = ctx
    27  		for _, o := range ConfigOptionsFromContext(ctx) {
    28  			o(p)
    29  		}
    30  	}
    31  }
    32  
    33  func WithConfigFiles(files ...string) OptionModifier {
    34  	return func(p *Provider) {
    35  		p.files = append(p.files, files...)
    36  	}
    37  }
    38  
    39  func WithImmutables(immutables ...string) OptionModifier {
    40  	return func(p *Provider) {
    41  		p.immutables = append(p.immutables, immutables...)
    42  	}
    43  }
    44  
    45  func WithFlags(flags *pflag.FlagSet) OptionModifier {
    46  	return func(p *Provider) {
    47  		p.flags = flags
    48  	}
    49  }
    50  
    51  func WithLogger(l *logrusx.Logger) OptionModifier {
    52  	return func(p *Provider) {
    53  		p.logger = l
    54  	}
    55  }
    56  
    57  func SkipValidation() OptionModifier {
    58  	return func(p *Provider) {
    59  		p.skipValidation = true
    60  	}
    61  }
    62  
    63  func WithValue(key string, value interface{}) OptionModifier {
    64  	return func(p *Provider) {
    65  		p.forcedValues = append(p.forcedValues, tuple{Key: key, Value: value})
    66  	}
    67  }
    68  
    69  func WithValues(values map[string]interface{}) OptionModifier {
    70  	return func(p *Provider) {
    71  		for key, value := range values {
    72  			p.forcedValues = append(p.forcedValues, tuple{Key: key, Value: value})
    73  		}
    74  	}
    75  }
    76  
    77  func WithBaseValues(values map[string]interface{}) OptionModifier {
    78  	return func(p *Provider) {
    79  		for key, value := range values {
    80  			p.baseValues = append(p.baseValues, tuple{Key: key, Value: value})
    81  		}
    82  	}
    83  }
    84  
    85  func OmitKeysFromTracing(keys ...string) OptionModifier {
    86  	return func(p *Provider) {
    87  		p.excludeFieldsFromTracing = keys
    88  	}
    89  }
    90  
    91  func AttachWatcher(watcher func(event watcherx.Event, err error)) OptionModifier {
    92  	return func(p *Provider) {
    93  		p.onChanges = append(p.onChanges, watcher)
    94  	}
    95  }
    96  
    97  func WithLogrusWatcher(l *logrusx.Logger) OptionModifier {
    98  	return AttachWatcher(LogrusWatcher(l))
    99  }
   100  
   101  func LogrusWatcher(l *logrusx.Logger) func(e watcherx.Event, err error) {
   102  	return func(e watcherx.Event, err error) {
   103  		l.WithField("file", e.Source()).
   104  			WithField("event", e.String()).
   105  			WithField("event_type", fmt.Sprintf("%T", e)).
   106  			Info("A change to a configuration file was detected.")
   107  
   108  		if et := new(jsonschema.ValidationError); errors.As(err, &et) {
   109  			l.WithField("event", fmt.Sprintf("%#v", et)).
   110  				Errorf("The changed configuration is invalid and could not be loaded. Rolling back to the last working configuration revision. Please address the validation errors before restarting the process.")
   111  		} else if et := new(ImmutableError); errors.As(err, &et) {
   112  			l.WithError(err).
   113  				WithField("key", et.Key).
   114  				WithField("old_value", fmt.Sprintf("%v", et.From)).
   115  				WithField("new_value", fmt.Sprintf("%v", et.To)).
   116  				Errorf("A configuration value marked as immutable has changed. Rolling back to the last working configuration revision. To reload the values please restart the process.")
   117  		} else if err != nil {
   118  			l.WithError(err).Errorf("An error occurred while watching config file %s", e.Source())
   119  		} else {
   120  			l.WithField("file", e.Source()).
   121  				WithField("event", e).
   122  				WithField("event_type", fmt.Sprintf("%T", e)).
   123  				Info("Configuration change processed successfully.")
   124  		}
   125  	}
   126  }
   127  
   128  func WithStderrValidationReporter() OptionModifier {
   129  	return func(p *Provider) {
   130  		p.onValidationError = func(k *koanf.Koanf, err error) {
   131  			p.printHumanReadableValidationErrors(k, os.Stderr, err)
   132  		}
   133  	}
   134  }
   135  
   136  func WithStandardValidationReporter(w io.Writer) OptionModifier {
   137  	return func(p *Provider) {
   138  		p.onValidationError = func(k *koanf.Koanf, err error) {
   139  			p.printHumanReadableValidationErrors(k, w, err)
   140  		}
   141  	}
   142  }
   143  

View as plain text