update golangci
This commit is contained in:
@@ -24,6 +24,6 @@ steps:
|
|||||||
- go test -parallel 10 -race ./...
|
- go test -parallel 10 -race ./...
|
||||||
|
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
image: golangci/golangci-lint:v1.39
|
image: golangci/golangci-lint:v1.53
|
||||||
commands:
|
commands:
|
||||||
- golangci-lint run
|
- golangci-lint run
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ linters-settings:
|
|||||||
suggest-new: true
|
suggest-new: true
|
||||||
misspell:
|
misspell:
|
||||||
locale: US
|
locale: US
|
||||||
|
varnamelen:
|
||||||
|
min-name-length: 2
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
enable-all: true
|
||||||
@@ -30,6 +32,15 @@ linters:
|
|||||||
- maligned
|
- maligned
|
||||||
- interfacer
|
- interfacer
|
||||||
- scopelint
|
- scopelint
|
||||||
|
- exhaustruct
|
||||||
|
- depguard
|
||||||
|
#deprecated
|
||||||
|
- structcheck
|
||||||
|
- varcheck
|
||||||
|
- golint
|
||||||
|
- deadcode
|
||||||
|
- ifshort
|
||||||
|
- nosnakecase
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||||
@@ -39,8 +50,14 @@ issues:
|
|||||||
- gomnd
|
- gomnd
|
||||||
- exhaustivestruct
|
- exhaustivestruct
|
||||||
- wrapcheck
|
- wrapcheck
|
||||||
|
- exhaustruct
|
||||||
|
- varnamelen
|
||||||
|
- tenv
|
||||||
|
- funlen
|
||||||
- path: test/*
|
- path: test/*
|
||||||
linters:
|
linters:
|
||||||
- gomnd
|
- gomnd
|
||||||
- exhaustivestruct
|
- exhaustivestruct
|
||||||
- wrapcheck
|
- wrapcheck
|
||||||
|
- exhaustruct
|
||||||
|
- varnamelen
|
||||||
|
|||||||
30
client.go
30
client.go
@@ -49,17 +49,21 @@ type provider struct {
|
|||||||
factory func(ctx context.Context) (Provider, error)
|
factory func(ctx context.Context) (Provider, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *provider) init(ctx context.Context) (err error) {
|
func (p *provider) init(ctx context.Context) error {
|
||||||
if atomic.LoadUint32(&p.done) == 0 {
|
if atomic.LoadUint32(&p.done) == 0 {
|
||||||
if !p.mu.TryLock() {
|
if !p.mu.TryLock() {
|
||||||
return fmt.Errorf("%w", ErrInitFactory)
|
return fmt.Errorf("%w", ErrInitFactory)
|
||||||
}
|
}
|
||||||
defer atomic.StoreUint32(&p.done, 1)
|
defer atomic.StoreUint32(&p.done, 1)
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
p.provider, err = p.factory(ctx)
|
|
||||||
|
var err error
|
||||||
|
if p.provider, err = p.factory(ctx); err != nil {
|
||||||
|
return fmt.Errorf("init provider factory:%w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *provider) Watch(ctx context.Context, key Key, callback WatchCallback) error {
|
func (p *provider) Watch(ctx context.Context, key Key, callback WatchCallback) error {
|
||||||
@@ -67,8 +71,13 @@ func (p *provider) Watch(ctx context.Context, key Key, callback WatchCallback) e
|
|||||||
return fmt.Errorf("init read:%w", err)
|
return fmt.Errorf("init read:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if watch, ok := p.provider.(WatchProvider); ok {
|
watch, ok := p.provider.(WatchProvider)
|
||||||
return watch.Watch(ctx, key, callback)
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := watch.Watch(ctx, key, callback); err != nil {
|
||||||
|
return fmt.Errorf("factory provider: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -79,7 +88,12 @@ func (p *provider) Read(ctx context.Context, key Key) (Variable, error) {
|
|||||||
return Variable{}, fmt.Errorf("init read:%w", err)
|
return Variable{}, fmt.Errorf("init read:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.provider.Read(ctx, key)
|
variable, err := p.provider.Read(ctx, key)
|
||||||
|
if err != nil {
|
||||||
|
return Variable{}, fmt.Errorf("factory provider: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return variable, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
@@ -96,10 +110,12 @@ func (c *Client) key(name string) Key {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value get value by name.
|
||||||
|
// nolint: ireturn
|
||||||
func (c *Client) Value(ctx context.Context, name string) (Value, error) {
|
func (c *Client) Value(ctx context.Context, name string) (Value, error) {
|
||||||
variable, err := c.Variable(ctx, name)
|
variable, err := c.Variable(ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("variable:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return variable.Value, nil
|
return variable.Value, nil
|
||||||
|
|||||||
@@ -284,11 +284,11 @@ func ExampleClient_Value_factory() {
|
|||||||
|
|
||||||
fmt.Printf("listen from env: %d\n", port.Int())
|
fmt.Printf("listen from env: %d\n", port.Int())
|
||||||
fmt.Printf("title from json: %v\n", title.String())
|
fmt.Printf("title from json: %v\n", title.String())
|
||||||
fmt.Printf("title from yaml: %v\n", yamlTitle.String())
|
fmt.Printf("yaml title: %v\n", yamlTitle.String())
|
||||||
fmt.Printf("struct from json: %+v\n", cfg)
|
fmt.Printf("struct from json: %+v\n", cfg)
|
||||||
// Output:
|
// Output:
|
||||||
// listen from env: 8080
|
// listen from env: 8080
|
||||||
// title from json: config title
|
// title from json: config title
|
||||||
// title from yaml: yaml title
|
// yaml title: yaml title
|
||||||
// struct from json: {Duration:21m0s Enabled:true}
|
// struct from json: {Duration:21m0s Enabled:true}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import (
|
|||||||
|
|
||||||
func LastIndex(sep string, factory config.KeyFactory) func(ctx context.Context, key config.Key) (string, string) {
|
func LastIndex(sep string, factory config.KeyFactory) func(ctx context.Context, key config.Key) (string, string) {
|
||||||
return func(ctx context.Context, key config.Key) (string, string) {
|
return func(ctx context.Context, key config.Key) (string, string) {
|
||||||
k := factory(ctx, key)
|
name := factory(ctx, key)
|
||||||
|
|
||||||
idx := strings.LastIndex(k, sep)
|
idx := strings.LastIndex(name, sep)
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
return k, ""
|
return name, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return k[0:idx], k[idx+len(sep):]
|
return name[0:idx], name[idx+len(sep):]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,15 +21,16 @@ func WithKeyFactory(factory config.KeyFactory) Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(opts ...Option) *Provider {
|
func New(opts ...Option) *Provider {
|
||||||
p := Provider{
|
prov := Provider{
|
||||||
key: key.Name,
|
key: key.Name,
|
||||||
|
args: make(map[string][]string, len(os.Args[1:])),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(&p)
|
opt(&prov)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &p
|
return &prov
|
||||||
}
|
}
|
||||||
|
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
@@ -38,9 +39,10 @@ type Provider struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nolint: cyclop
|
// nolint: cyclop
|
||||||
func (p *Provider) parseOne(arg string) (name, val string, err error) {
|
// return name, value, error.
|
||||||
|
func (p *Provider) parseOne(arg string) (string, string, error) {
|
||||||
if arg[0] != '-' {
|
if arg[0] != '-' {
|
||||||
return
|
return "", "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
numMinuses := 1
|
numMinuses := 1
|
||||||
@@ -49,19 +51,21 @@ func (p *Provider) parseOne(arg string) (name, val string, err error) {
|
|||||||
numMinuses++
|
numMinuses++
|
||||||
}
|
}
|
||||||
|
|
||||||
name = strings.TrimSpace(arg[numMinuses:])
|
name := strings.TrimSpace(arg[numMinuses:])
|
||||||
if len(name) == 0 {
|
if len(name) == 0 {
|
||||||
return
|
return name, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if name[0] == '-' || name[0] == '=' {
|
if name[0] == '-' || name[0] == '=' {
|
||||||
return "", "", fmt.Errorf("%w: bad flag syntax: %s", config.ErrInvalidValue, arg)
|
return "", "", fmt.Errorf("%w: bad flag syntax: %s", config.ErrInvalidValue, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 1; i < len(name); i++ {
|
var val string
|
||||||
if name[i] == '=' || name[i] == ' ' {
|
|
||||||
val = strings.TrimSpace(name[i+1:])
|
for idx := 1; idx < len(name); idx++ {
|
||||||
name = name[0:i]
|
if name[idx] == '=' || name[idx] == ' ' {
|
||||||
|
val = strings.TrimSpace(name[idx+1:])
|
||||||
|
name = name[0:idx]
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -79,8 +83,6 @@ func (p *Provider) parse() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.args = make(map[string][]string, len(os.Args[1:]))
|
|
||||||
|
|
||||||
for _, arg := range os.Args[1:] {
|
for _, arg := range os.Args[1:] {
|
||||||
name, value, err := p.parseOne(arg)
|
name, value, err := p.parseOne(arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,32 +107,36 @@ func (p *Provider) IsSupport(ctx context.Context, key config.Key) bool {
|
|||||||
|
|
||||||
func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
||||||
if err := p.parse(); err != nil {
|
if err := p.parse(); err != nil {
|
||||||
return config.Variable{Provider: p.Name()}, err
|
return config.Variable{
|
||||||
|
Name: "",
|
||||||
|
Value: nil,
|
||||||
|
Provider: p.Name(),
|
||||||
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
k := p.key(ctx, key)
|
name := p.key(ctx, key)
|
||||||
if val, ok := p.args[k]; ok {
|
if val, ok := p.args[name]; ok {
|
||||||
switch {
|
switch {
|
||||||
case len(val) == 1:
|
case len(val) == 1:
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: k,
|
Name: name,
|
||||||
Provider: p.Name(),
|
Provider: p.Name(),
|
||||||
Value: value.JString(val[0]),
|
Value: value.JString(val[0]),
|
||||||
}, nil
|
}, nil
|
||||||
default:
|
default:
|
||||||
var n yaml.Node
|
var yNode yaml.Node
|
||||||
|
|
||||||
if err := yaml.Unmarshal([]byte("["+strings.Join(val, ",")+"]"), &n); err != nil {
|
if err := yaml.Unmarshal([]byte("["+strings.Join(val, ",")+"]"), &yNode); err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("arg: failed unmarshal yaml:%w", err)
|
return config.Variable{}, fmt.Errorf("arg: failed unmarshal yaml:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: k,
|
Name: name,
|
||||||
Provider: p.Name(),
|
Provider: p.Name(),
|
||||||
Value: value.Decode(n.Decode),
|
Value: value.Decode(yNode.Decode),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{Name: k, Provider: p.Name()}, config.ErrVariableNotFound
|
return config.Variable{}, fmt.Errorf("%w: %s", config.ErrVariableNotFound, name)
|
||||||
}
|
}
|
||||||
|
|||||||
17
provider/env/provider.go
vendored
17
provider/env/provider.go
vendored
@@ -19,17 +19,17 @@ func WithKeyFactory(factory config.KeyFactory) Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(opts ...Option) *Provider {
|
func New(opts ...Option) *Provider {
|
||||||
p := Provider{
|
provider := Provider{
|
||||||
key: func(ctx context.Context, k config.Key) string {
|
key: func(ctx context.Context, k config.Key) string {
|
||||||
return strings.ToUpper(key.NsAppName("_")(ctx, k))
|
return strings.ToUpper(key.NsAppName("_")(ctx, k))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(&p)
|
opt(&provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &p
|
return &provider
|
||||||
}
|
}
|
||||||
|
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
@@ -45,17 +45,14 @@ func (p *Provider) IsSupport(ctx context.Context, key config.Key) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
||||||
k := p.key(ctx, key)
|
name := p.key(ctx, key)
|
||||||
if val, ok := os.LookupEnv(k); ok {
|
if val, ok := os.LookupEnv(name); ok {
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: k,
|
Name: name,
|
||||||
Provider: p.Name(),
|
Provider: p.Name(),
|
||||||
Value: value.JString(val),
|
Value: value.JString(val),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{}, config.ErrVariableNotFound
|
||||||
Name: k,
|
|
||||||
Provider: p.Name(),
|
|
||||||
}, config.ErrVariableNotFound
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,16 +44,16 @@ func (p *Provider) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
||||||
k := p.key(ctx, key)
|
name := p.key(ctx, key)
|
||||||
|
|
||||||
resp, err := p.client.Get(ctx, k, client.WithPrefix())
|
resp, err := p.client.Get(ctx, name, client.WithPrefix())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("%w: key:%s, prov:%s", err, k, p.Name())
|
return config.Variable{}, fmt.Errorf("%w: key:%s, prov:%s", err, name, p.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := p.resolve(k, resp.Kvs)
|
val, err := p.resolve(name, resp.Kvs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("%w: key:%s, prov:%s", err, k, p.Name())
|
return config.Variable{}, fmt.Errorf("%w: key:%s, prov:%s", err, name, p.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
return val, nil
|
return val, nil
|
||||||
@@ -94,6 +94,7 @@ func (p *Provider) resolve(key string, kvs []*pb.KeyValue) (config.Variable, err
|
|||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: key,
|
Name: key,
|
||||||
Provider: p.Name(),
|
Provider: p.Name(),
|
||||||
|
Value: nil,
|
||||||
}, nil
|
}, nil
|
||||||
case string(kv.Key) == key:
|
case string(kv.Key) == key:
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
@@ -104,8 +105,5 @@ func (p *Provider) resolve(key string, kvs []*pb.KeyValue) (config.Variable, err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{}, fmt.Errorf("%w: name %s", config.ErrVariableNotFound, key)
|
||||||
Name: key,
|
|
||||||
Provider: p.Name(),
|
|
||||||
}, config.ErrVariableNotFound
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import (
|
|||||||
var _ config.Provider = (*Provider)(nil)
|
var _ config.Provider = (*Provider)(nil)
|
||||||
|
|
||||||
func New(data *ini.File) *Provider {
|
func New(data *ini.File) *Provider {
|
||||||
|
const nameParts = 2
|
||||||
|
|
||||||
return &Provider{
|
return &Provider{
|
||||||
data: data,
|
data: data,
|
||||||
resolve: func(ctx context.Context, key config.Key) (string, string) {
|
resolve: func(ctx context.Context, key config.Key) (string, string) {
|
||||||
keys := strings.SplitN(key.Name, "/", 2)
|
keys := strings.SplitN(key.Name, "/", nameParts)
|
||||||
if len(keys) == 1 {
|
if len(keys) == 1 {
|
||||||
return "", keys[0]
|
return "", keys[0]
|
||||||
}
|
}
|
||||||
@@ -46,12 +48,12 @@ func (p *Provider) Read(ctx context.Context, key config.Key) (config.Variable, e
|
|||||||
|
|
||||||
iniSection, err := p.data.GetSection(section)
|
iniSection, err := p.data.GetSection(section)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("%w: %s: %v", config.ErrVariableNotFound, p.Name(), err)
|
return config.Variable{}, fmt.Errorf("%w: %s: %w", config.ErrVariableNotFound, p.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iniKey, err := iniSection.GetKey(name)
|
iniKey, err := iniSection.GetKey(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("%w: %s: %v", config.ErrVariableNotFound, p.Name(), err)
|
return config.Variable{}, fmt.Errorf("%w: %s: %w", config.ErrVariableNotFound, p.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func NewFile(path string, opts ...Option) (*Provider, error) {
|
|||||||
return nil, fmt.Errorf("%w: unable to read config file %#q: file not found or unreadable", err, path)
|
return nil, fmt.Errorf("%w: unable to read config file %#q: file not found or unreadable", err, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return New(file), nil
|
return New(file, opts...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(*Provider)
|
type Option func(*Provider)
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ func NewFile(file string, opts ...Option) (*Provider, error) {
|
|||||||
type Option func(*Provider)
|
type Option func(*Provider)
|
||||||
|
|
||||||
func configure(tree *toml.Tree, opts ...Option) *Provider {
|
func configure(tree *toml.Tree, opts ...Option) *Provider {
|
||||||
p := &Provider{
|
prov := &Provider{
|
||||||
tree: tree,
|
tree: tree,
|
||||||
key: key.Name,
|
key: key.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(p)
|
opt(prov)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return prov
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(data []byte, opts ...Option) (*Provider, error) {
|
func New(data []byte, opts ...Option) (*Provider, error) {
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ func (s Value) ParseInt() (int, error) {
|
|||||||
func (s Value) Unmarshal(target interface{}) error {
|
func (s Value) Unmarshal(target interface{}) error {
|
||||||
b, err := json.Marshal(s.Raw())
|
b, err := json.Marshal(s.Raw())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(b, target); err != nil {
|
if err := json.Unmarshal(b, target); err != nil {
|
||||||
return fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ func WithSecretResolve(f func(context.Context, config.Key) (string, string)) Sec
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSecretKV2(client *api.Client, opts ...SecretOption) *SecretKV2 {
|
func NewSecretKV2(client *api.Client, opts ...SecretOption) *SecretKV2 {
|
||||||
s := SecretKV2{
|
prov := SecretKV2{
|
||||||
client: client,
|
client: client,
|
||||||
resolve: key.LastIndexField(":", "value", key.PrefixName("secret/data/", key.NsAppName("/"))),
|
resolve: key.LastIndexField(":", "value", key.PrefixName("secret/data/", key.NsAppName("/"))),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(&s)
|
opt(&prov)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &s
|
return &prov
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecretKV2 struct {
|
type SecretKV2 struct {
|
||||||
@@ -50,26 +50,26 @@ func (p *SecretKV2) Name() string {
|
|||||||
func (p *SecretKV2) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
func (p *SecretKV2) Read(ctx context.Context, key config.Key) (config.Variable, error) {
|
||||||
path, field := p.resolve(ctx, key)
|
path, field := p.resolve(ctx, key)
|
||||||
|
|
||||||
s, err := p.client.Logical().Read(path)
|
secret, err := p.client.Logical().Read(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("%w: path:%s, field:%s, provider:%s", err, path, field, p.Name())
|
return config.Variable{}, fmt.Errorf("%w: path:%s, field:%s, provider:%s", err, path, field, p.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
if s == nil || len(s.Data) == 0 {
|
if secret == nil || len(secret.Data) == 0 {
|
||||||
return config.Variable{}, fmt.Errorf("%w: path:%s, field:%s, provider:%s", config.ErrVariableNotFound, path, field, p.Name())
|
return config.Variable{}, fmt.Errorf("%w: path:%s, field:%s, provider:%s", config.ErrVariableNotFound, path, field, p.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s.Warnings) > 0 {
|
if len(secret.Warnings) > 0 {
|
||||||
return config.Variable{},
|
return config.Variable{},
|
||||||
fmt.Errorf("%w: warn: %s, path:%s, field:%s, provider:%s", config.ErrVariableNotFound, s.Warnings, path, field, p.Name())
|
fmt.Errorf("%w: warn: %s, path:%s, field:%s, provider:%s", config.ErrVariableNotFound, secret.Warnings, path, field, p.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
d, ok := s.Data["data"].(map[string]interface{})
|
data, ok := secret.Data["data"].(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return config.Variable{}, fmt.Errorf("%w: path:%s, field:%s, provider:%s", config.ErrVariableNotFound, path, field, p.Name())
|
return config.Variable{}, fmt.Errorf("%w: path:%s, field:%s, provider:%s", config.ErrVariableNotFound, path, field, p.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, ok := d[field]; ok {
|
if val, ok := data[field]; ok {
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: path + field,
|
Name: path + field,
|
||||||
Provider: p.Name(),
|
Provider: p.Name(),
|
||||||
@@ -77,9 +77,9 @@ func (p *SecretKV2) Read(ctx context.Context, key config.Key) (config.Variable,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
md, err := json.Marshal(d)
|
md, err := json.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return config.Variable{}, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func New(duration time.Duration, provider config.Provider, opts ...Option) *Provider {
|
func New(duration time.Duration, provider config.Provider, opts ...Option) *Provider {
|
||||||
p := &Provider{
|
prov := &Provider{
|
||||||
Provider: provider,
|
Provider: provider,
|
||||||
ticker: time.NewTicker(duration),
|
ticker: time.NewTicker(duration),
|
||||||
logger: func(_ context.Context, msg string) {
|
logger: func(_ context.Context, msg string) {
|
||||||
@@ -24,10 +24,10 @@ func New(duration time.Duration, provider config.Provider, opts ...Option) *Prov
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(p)
|
opt(prov)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return prov
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithLogger(l func(context.Context, string)) Option {
|
func WithLogger(l func(context.Context, string)) Option {
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ func (p *provider) Name() string {
|
|||||||
return "test"
|
return "test"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *provider) Read(ctx context.Context, k config.Key) (config.Variable, error) {
|
func (p *provider) Read(context.Context, config.Key) (config.Variable, error) {
|
||||||
p.cnt++
|
p.cnt++
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: "tmpname",
|
Name: "tmpname",
|
||||||
|
Provider: p.Name(),
|
||||||
Value: value.JString(fmt.Sprint(p.cnt)),
|
Value: value.JString(fmt.Sprint(p.cnt)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
var _ config.Provider = (*Provider)(nil)
|
var _ config.Provider = (*Provider)(nil)
|
||||||
|
|
||||||
func keyFactory(ctx context.Context, key config.Key) []string {
|
func keyFactory(_ context.Context, key config.Key) []string {
|
||||||
return strings.Split(key.Name, "/")
|
return strings.Split(key.Name, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,15 +37,15 @@ func New(yml []byte, opts ...Option) (*Provider, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func create(opts ...Option) *Provider {
|
func create(opts ...Option) *Provider {
|
||||||
p := Provider{
|
prov := Provider{
|
||||||
key: keyFactory,
|
key: keyFactory,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(&p)
|
opt(&prov)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &p
|
return &prov
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(*Provider)
|
type Option func(*Provider)
|
||||||
@@ -76,8 +76,8 @@ type node struct {
|
|||||||
*yaml.Node
|
*yaml.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) read(name string, k []string) (config.Variable, error) {
|
func (n *node) read(name string, keys []string) (config.Variable, error) {
|
||||||
val, err := getData(n.Node.Content[0].Content, k)
|
val, err := getData(n.Node.Content[0].Content, keys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, config.ErrVariableNotFound) {
|
if errors.Is(err, config.ErrVariableNotFound) {
|
||||||
return config.Variable{}, fmt.Errorf("%w: %s", config.ErrVariableNotFound, name)
|
return config.Variable{}, fmt.Errorf("%w: %s", config.ErrVariableNotFound, name)
|
||||||
@@ -87,20 +87,20 @@ func (n *node) read(name string, k []string) (config.Variable, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return config.Variable{
|
return config.Variable{
|
||||||
Name: strings.Join(k, "."),
|
Name: strings.Join(keys, "."),
|
||||||
Provider: name,
|
Provider: name,
|
||||||
Value: value.Decode(val),
|
Value: value.Decode(val),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getData(node []*yaml.Node, keys []string) (func(interface{}) error, error) {
|
func getData(node []*yaml.Node, keys []string) (func(interface{}) error, error) {
|
||||||
for i := len(node) - 1; i > 0; i -= 2 {
|
for idx := len(node) - 1; idx > 0; idx -= 2 {
|
||||||
if node[i-1].Value == keys[0] {
|
if node[idx-1].Value == keys[0] {
|
||||||
if len(keys) > 1 {
|
if len(keys) > 1 {
|
||||||
return getData(node[i].Content, keys[1:])
|
return getData(node[idx].Content, keys[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
return node[i].Decode, nil
|
return node[idx].Decode, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ func (p *Watch) Read(ctx context.Context, key config.Key) (config.Variable, erro
|
|||||||
return config.Variable{}, fmt.Errorf("yaml_file: read error: %w", err)
|
return config.Variable{}, fmt.Errorf("yaml_file: read error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var n yaml.Node
|
var yNode yaml.Node
|
||||||
if err = yaml.Unmarshal(in, &n); err != nil {
|
if err = yaml.Unmarshal(in, &yNode); err != nil {
|
||||||
return config.Variable{}, fmt.Errorf("yaml_file: unmarshal error: %w", err)
|
return config.Variable{}, fmt.Errorf("yaml_file: unmarshal error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.prov.With(&n).Read(ctx, key)
|
return p.prov.With(&yNode).Read(ctx, key)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// nolint: nonamedreturns
|
||||||
package value
|
package value
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ type Empty struct {
|
|||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Empty) Unmarshal(val interface{}) error {
|
func (e Empty) Unmarshal(_ interface{}) error {
|
||||||
return e.Err
|
return e.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
func ParseDuration(raw string) (time.Duration, error) {
|
func ParseDuration(raw string) (time.Duration, error) {
|
||||||
d, err := time.ParseDuration(raw)
|
d, err := time.ParseDuration(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return 0, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return d, nil
|
return d, nil
|
||||||
@@ -21,7 +21,7 @@ func ParseDuration(raw string) (time.Duration, error) {
|
|||||||
func ParseInt(s string) (int64, error) {
|
func ParseInt(s string) (int64, error) {
|
||||||
i, err := strconv.ParseInt(s, 10, 64)
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return 0, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return i, nil
|
return i, nil
|
||||||
@@ -30,7 +30,7 @@ func ParseInt(s string) (int64, error) {
|
|||||||
func ParseUint(s string) (uint64, error) {
|
func ParseUint(s string) (uint64, error) {
|
||||||
i, err := strconv.ParseUint(s, 10, 64)
|
i, err := strconv.ParseUint(s, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return 0, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return i, nil
|
return i, nil
|
||||||
@@ -39,7 +39,7 @@ func ParseUint(s string) (uint64, error) {
|
|||||||
func Atoi(s string) (int, error) {
|
func Atoi(s string) (int, error) {
|
||||||
i, err := strconv.Atoi(s)
|
i, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return 0, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return i, nil
|
return i, nil
|
||||||
@@ -48,7 +48,7 @@ func Atoi(s string) (int, error) {
|
|||||||
func ParseTime(s string) (time.Time, error) {
|
func ParseTime(s string) (time.Time, error) {
|
||||||
i, err := time.Parse(time.RFC3339, s)
|
i, err := time.Parse(time.RFC3339, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return time.Time{}, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return i, nil
|
return i, nil
|
||||||
@@ -57,7 +57,7 @@ func ParseTime(s string) (time.Time, error) {
|
|||||||
func ParseFloat(s string) (float64, error) {
|
func ParseFloat(s string) (float64, error) {
|
||||||
f, err := strconv.ParseFloat(s, 64)
|
f, err := strconv.ParseFloat(s, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return 0, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
@@ -66,7 +66,7 @@ func ParseFloat(s string) (float64, error) {
|
|||||||
func ParseBool(s string) (bool, error) {
|
func ParseBool(s string) (bool, error) {
|
||||||
b, err := strconv.ParseBool(s)
|
b, err := strconv.ParseBool(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return false, fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return b, nil
|
return b, nil
|
||||||
@@ -74,7 +74,7 @@ func ParseBool(s string) (bool, error) {
|
|||||||
|
|
||||||
func JUnmarshal(b []byte, v interface{}) error {
|
func JUnmarshal(b []byte, v interface{}) error {
|
||||||
if err := json.Unmarshal(b, v); err != nil {
|
if err := json.Unmarshal(b, v); err != nil {
|
||||||
return fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func (s Value) Unmarshal(target interface{}) error {
|
|||||||
if v, ok := s.Raw().([]byte); ok {
|
if v, ok := s.Raw().([]byte); ok {
|
||||||
err := json.Unmarshal(v, target)
|
err := json.Unmarshal(v, target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %s", config.ErrInvalidValue, err)
|
return fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user