forked from hyperledger/fabric-sdk-go
/
config.go
164 lines (132 loc) · 3.77 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package config
import (
"bytes"
"io"
"strings"
"github.com/spf13/viper"
"github.com/hyperledger/fabric-sdk-go/pkg/common/logging"
"github.com/pkg/errors"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
)
var logModules = [...]string{"fabsdk", "fabsdk/client", "fabsdk/core", "fabsdk/fab", "fabsdk/common",
"fabsdk/msp", "fabsdk/util", "fabsdk/context"}
type options struct {
envPrefix string
templatePath string
}
const (
cmdRoot = "FABRIC_SDK"
)
// Option configures the package.
type Option func(opts *options) error
// FromReader loads configuration from in.
// configType can be "json" or "yaml".
func FromReader(in io.Reader, configType string, opts ...Option) core.ConfigProvider {
return func() ([]core.ConfigBackend, error) {
return initFromReader(in, configType, opts...)
}
}
// FromFile reads from named config file
func FromFile(name string, opts ...Option) core.ConfigProvider {
return func() ([]core.ConfigBackend, error) {
backend, err := newBackend(opts...)
if err != nil {
return nil, err
}
if name == "" {
return nil, errors.New("filename is required")
}
// create new viper
backend.configViper.SetConfigFile(name)
// If a config file is found, read it in.
err = backend.configViper.MergeInConfig()
if err != nil {
return nil, errors.Wrapf(err, "loading config file failed: %s", name)
}
setLogLevel(backend)
return []core.ConfigBackend{backend}, nil
}
}
// FromRaw will initialize the configs from a byte array
func FromRaw(configBytes []byte, configType string, opts ...Option) core.ConfigProvider {
return func() ([]core.ConfigBackend, error) {
buf := bytes.NewBuffer(configBytes)
return initFromReader(buf, configType, opts...)
}
}
func initFromReader(in io.Reader, configType string, opts ...Option) ([]core.ConfigBackend, error) {
backend, err := newBackend(opts...)
if err != nil {
return nil, err
}
if configType == "" {
return nil, errors.New("empty config type")
}
// read config from bytes array, but must set ConfigType
// for viper to properly unmarshal the bytes array
backend.configViper.SetConfigType(configType)
err = backend.configViper.MergeConfig(in)
if err != nil {
return nil, err
}
setLogLevel(backend)
return []core.ConfigBackend{backend}, nil
}
// WithEnvPrefix defines the prefix for environment variable overrides.
// See viper SetEnvPrefix for more information.
func WithEnvPrefix(prefix string) Option {
return func(opts *options) error {
opts.envPrefix = prefix
return nil
}
}
func newBackend(opts ...Option) (*defConfigBackend, error) {
o := options{
envPrefix: cmdRoot,
}
for _, option := range opts {
err := option(&o)
if err != nil {
return nil, errors.WithMessage(err, "Error in options passed to create new config backend")
}
}
v := newViper(o.envPrefix)
//default backend for config
backend := &defConfigBackend{
configViper: v,
opts: o,
}
err := backend.loadTemplateConfig()
if err != nil {
return nil, err
}
return backend, nil
}
func newViper(cmdRootPrefix string) *viper.Viper {
myViper := viper.New()
myViper.SetEnvPrefix(cmdRootPrefix)
myViper.AutomaticEnv()
replacer := strings.NewReplacer(".", "_")
myViper.SetEnvKeyReplacer(replacer)
return myViper
}
// setLogLevel will set the log level of the client
func setLogLevel(backend core.ConfigBackend) {
loggingLevelString, _ := backend.Lookup("client.logging.level")
logLevel := logging.INFO
if loggingLevelString != nil {
var err error
logLevel, err = logging.LogLevel(loggingLevelString.(string))
if err != nil {
panic(err)
}
}
// TODO: allow separate settings for each
for _, logModule := range logModules {
logging.SetLevel(logModule, logLevel)
}
}