Files
upstream-ory-keto/oryx/configx/options.go
upstream-mirror 9456a4e922
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:08:34 +05:00

160 lines
4.1 KiB
Go

// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package configx
import (
"context"
"errors"
"fmt"
"io"
"os"
"github.com/spf13/pflag"
"github.com/ory/jsonschema/v3"
"github.com/ory/x/logrusx"
"github.com/knadh/koanf/v2"
"github.com/ory/x/watcherx"
)
type (
OptionModifier func(p *Provider)
)
func WithContext(ctx context.Context) OptionModifier {
return func(p *Provider) {
for _, o := range ConfigOptionsFromContext(ctx) {
o(p)
}
}
}
func WithConfigFiles(files ...string) OptionModifier {
return func(p *Provider) {
p.files = append(p.files, files...)
}
}
func WithImmutables(immutables ...string) OptionModifier {
return func(p *Provider) {
p.immutables = append(p.immutables, immutables...)
}
}
func WithExceptImmutables(exceptImmutables ...string) OptionModifier {
return func(p *Provider) {
p.exceptImmutables = append(p.exceptImmutables, exceptImmutables...)
}
}
func WithFlags(flags *pflag.FlagSet) OptionModifier {
return func(p *Provider) {
p.flags = flags
}
}
func WithLogger(l *logrusx.Logger) OptionModifier {
return func(p *Provider) {
p.logger = l
}
}
func SkipValidation() OptionModifier {
return func(p *Provider) {
p.skipValidation = true
}
}
func DisableEnvLoading() OptionModifier {
return func(p *Provider) {
p.disableEnvLoading = true
}
}
func WithValue(key string, value interface{}) OptionModifier {
return func(p *Provider) {
p.forcedValues = append(p.forcedValues, tuple{Key: key, Value: value})
}
}
func WithValues(values map[string]interface{}) OptionModifier {
return func(p *Provider) {
for key, value := range values {
p.forcedValues = append(p.forcedValues, tuple{Key: key, Value: value})
}
}
}
func WithBaseValues(values map[string]interface{}) OptionModifier {
return func(p *Provider) {
for key, value := range values {
p.baseValues = append(p.baseValues, tuple{Key: key, Value: value})
}
}
}
func WithUserProviders(providers ...koanf.Provider) OptionModifier {
return func(p *Provider) {
p.userProviders = providers
}
}
// DEPRECATED without replacement. This option is a no-op.
func OmitKeysFromTracing(keys ...string) OptionModifier {
return func(*Provider) {}
}
func AttachWatcher(watcher func(event watcherx.Event, err error)) OptionModifier {
return func(p *Provider) {
p.onChanges = append(p.onChanges, watcher)
}
}
func WithLogrusWatcher(l *logrusx.Logger) OptionModifier {
return AttachWatcher(LogrusWatcher(l))
}
func LogrusWatcher(l *logrusx.Logger) func(e watcherx.Event, err error) {
return func(e watcherx.Event, err error) {
l.WithField("file", e.Source()).
WithField("event_type", fmt.Sprintf("%T", e)).
Info("A change to a configuration file was detected.")
if et := new(jsonschema.ValidationError); errors.As(err, &et) {
l.WithField("event", fmt.Sprintf("%#v", et)).
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.")
} else if et := new(ImmutableError); errors.As(err, &et) {
l.WithError(err).
WithField("key", et.Key).
WithField("old_value", fmt.Sprintf("%v", et.From)).
WithField("new_value", fmt.Sprintf("%v", et.To)).
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.")
} else if err != nil {
l.WithError(err).Errorf("An error occurred while watching config file %s", e.Source())
} else {
l.WithField("file", e.Source()).
WithField("event_type", fmt.Sprintf("%T", e)).
Info("Configuration change processed successfully.")
}
}
}
func WithStderrValidationReporter() OptionModifier {
return func(p *Provider) {
p.onValidationError = func(k *koanf.Koanf, err error) {
p.printHumanReadableValidationErrors(k, os.Stderr, err)
}
}
}
func WithStandardValidationReporter(w io.Writer) OptionModifier {
return func(p *Provider) {
p.onValidationError = func(k *koanf.Koanf, err error) {
p.printHumanReadableValidationErrors(k, w, err)
}
}
}