-
Notifications
You must be signed in to change notification settings - Fork 53
/
config.go
117 lines (104 loc) · 2.55 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package config
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/rancher/opni/pkg/config/meta"
"github.com/rancher/opni/pkg/config/v1beta1"
"github.com/rancher/opni/pkg/logger"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/util/yaml"
)
var (
ErrConfigNotFound = errors.New("config not found")
ErrUnsupportedApiVersion = errors.New("unsupported api version")
)
type Unmarshaler interface {
Unmarshal(into interface{}) error
}
var configLog = logger.New().Named("config")
type GatewayConfig = v1beta1.GatewayConfig
func LoadObjectsFromFile(path string) (meta.ObjectList, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return LoadObjects(bytes.Split(data, []byte("\n---\n")))
}
func LoadObjects(documents [][]byte) (meta.ObjectList, error) {
objects := []meta.Object{}
for i, document := range documents {
lg := configLog.With(
"documentIndex", i,
)
if len(strings.TrimSpace(string(document))) == 0 {
continue
}
object, err := LoadObject(document)
if err != nil {
lg.With(
zap.Error(err),
).Error("error loading config")
continue
}
objects = append(objects, object)
}
return objects, nil
}
func LoadObject(document []byte) (meta.Object, error) {
decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(document), 4096)
typeMeta := meta.TypeMeta{}
if err := decoder.Decode(&typeMeta); err != nil {
return nil, errors.New("object has missing or invalid TypeMeta")
}
if typeMeta.APIVersion == "" || typeMeta.Kind == "" {
return nil, errors.New("object has missing or invalid TypeMeta")
}
object, err := decodeObject(typeMeta, document)
if err != nil {
return nil, fmt.Errorf("failed to decode object: %w", err)
}
return object, nil
}
func decodeObject(typeMeta meta.TypeMeta, document []byte) (meta.Object, error) {
switch typeMeta.APIVersion {
case v1beta1.APIVersion:
return v1beta1.DecodeObject(typeMeta.Kind, document)
default:
return nil, ErrUnsupportedApiVersion
}
}
func FindConfig() (string, error) {
pathsToSearch := []string{
".",
"/etc/opni",
}
filenamesToSearch := []string{
"gateway.yaml",
"gateway.yml",
"gateway.json",
"agent.yaml",
"agent.yml",
"agent.json",
"config.yaml",
"config.yml",
"config.json",
}
for _, path := range pathsToSearch {
for _, filename := range filenamesToSearch {
p, err := filepath.Abs(filepath.Join(path, filename))
if err != nil {
return "", err
}
if f, err := os.Open(p); err == nil {
f.Close()
return p, nil
}
}
}
return "", ErrConfigNotFound
}