crossplane
82 строки · 2.1 Кб
1/*
2Copyright 2023 The Crossplane Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package upbound
18
19import (
20"encoding/json"
21"io"
22"strings"
23
24"github.com/alecthomas/kong"
25)
26
27// JSON returns a Resolver that retrieves values from a JSON source.
28// Based slightly off of https://github.com/alecthomas/kong/blob/f48da244f54370c0cb63e22b0e500e5459a491bf/resolver.go#L33-L60
29// Hyphens in flag names are replaced with underscores.
30func JSON(base, overlay io.Reader) (kong.Resolver, error) {
31baseValues := map[string]interface{}{}
32overlayValues := map[string]interface{}{}
33err := json.NewDecoder(base).Decode(&baseValues)
34if err != nil {
35return nil, err
36}
37err = json.NewDecoder(overlay).Decode(&overlayValues)
38if err != nil {
39return nil, err
40}
41
42var f kong.ResolverFunc = func(_ *kong.Context, _ *kong.Path, flag *kong.Flag) (interface{}, error) {
43name := strings.ReplaceAll(flag.Name, "-", "_")
44bRaw, bOk := resolveValue(name, flag.Envs, baseValues)
45oRaw, oOk := resolveValue(name, flag.Envs, overlayValues)
46
47// if found in base and in overlay AND is not the defaultValue for overlay
48if bOk && oOk && flag.Default != oRaw {
49return oRaw, nil
50}
51
52if bOk {
53return bRaw, nil
54}
55
56if oOk {
57return oRaw, nil
58}
59
60return nil, nil
61}
62
63return f, nil
64}
65
66func resolveValue(fieldName string, envVarsName []string, vals map[string]interface{}) (interface{}, bool) {
67// attempt to lookup by field name first
68raw, ok := vals[fieldName]
69if !ok {
70// fall back to env var name
71for _, envVarName := range envVarsName {
72raw, ok = vals[envVarName]
73if ok {
74break
75}
76}
77if !ok {
78return nil, false
79}
80}
81return raw, true
82}
83