golang支持多层配置和加密的配置文件解析插件库onion的使用
Golang支持多层配置和加密的配置文件解析插件库onion的使用
onion是一个基于层的、可插拔的Golang配置管理库。它的主要特点是支持多层配置和加密配置文件。
基本用法
首先选择需要的层。标准文件层和json是内置的,但其他格式需要导入对应的包。
JSON文件层示例
package main
import (
"fmt"
"github.com/goraz/onion"
)
func main() {
// 创建一个文件层从json文件加载数据。onion根据扩展名加载文件,所以json文件应该有`.json`扩展名
l1, err := onion.NewFileLayer("/etc/shared.json", nil)
if err != nil {
panic(err)
}
// 创建一个基于环境变量的层。它会加载所有以APP_为前缀的环境变量
// 例如APP_TEST_STRING可以通过o.Get("test.string")获取
l2 := onion.NewEnvLayerPrefix("_", "APP")
// 创建onion,最终结果是l1和l2的联合,但l2会覆盖l1
o := onion.New(l1, l2)
str := o.GetStringDefault("test.string", "empty")
fmt.Println(str)
// 现在str的值按以下顺序确定:
// 1- 如果环境变量APP_TEST_STRING存在
// 2- 如果shared.json有类似{"test":{"string":"value"}}这样的键,则str为"value"
// 3- 提供的默认值"empty"
}
加载其他文件格式
目前onion内置支持json
格式,其他格式需要导入对应的加载器包:
toml
(0.4.0版本)toml-0.5.0
(0.5.0版本)yaml
properties
例如:
import (
_ "github.com/goraz/onion/loaders/toml" // 需要加载TOML格式
)
监听文件和etcd变化
还有其他层(如etcd
和filewatchlayer
)可以监听变化。
package main
import (
"fmt"
"github.com/goraz/onion"
"github.com/goraz/onion/layers/etcdlayer"
"github.com/goraz/onion/layers/filewatchlayer"
)
func main() {
// 创建一个文件层从json文件加载数据,同时监听文件变化
l1, err := filewatchlayer.NewFileWatchLayer("/etc/shared.json", nil)
if err != nil {
panic(err)
}
l2, err := etcdlayer.NewEtcdLayer("/app/config", "json", []string{"http://127.0.0.1:2379"}, nil)
if err != nil {
panic(err)
}
// 创建onion,最终结果是l1和l2的联合,但l2会覆盖l1
o := onion.New(l1, l2)
// 获取key的最新版本
str := o.GetStringDefault("test.string", "empty")
fmt.Println(str)
}
加密配置
如果你想存储加密内容,目前只支持secconf
(基于crypt项目)。还有一个onioncli工具可以帮助管理这些密钥。
package main
import (
"bytes"
"fmt"
"github.com/goraz/onion"
"github.com/goraz/onion/ciphers/secconf"
"github.com/goraz/onion/layers/etcdlayer"
"github.com/goraz/onion/layers/filewatchlayer"
)
// 正常情况下这个私钥应该放在安全的地方,而不是这里
const privateKey = `PRIVATE KEY`
func main() {
// 私钥应该放在安全的地方。这只是一个演示,还有一个cli工具可以创建这个
// `go get -u github.com/goraz/onion/cli/onioncli`
cipher, err := secconf.NewCipher(bytes.NewReader([]byte(privateKey)))
if err != nil {
panic(err)
}
// 创建一个文件层从json文件加载数据,同时监听文件变化
// 传递cipher意味着文件是base64和pgp加密的
l1, err := filewatchlayer.NewFileWatchLayer("/etc/shared.json", cipher)
if err != nil {
panic(err)
}
// 创建一个etcd层。它监听/app/config键,应该是用base64和pgp编码的json文件
l2, err := etcdlayer.NewEtcdLayer("/app/config", "json", []string{"http://127.0.0.1:2379"}, cipher)
if err != nil {
panic(err)
}
// 创建onion,最终结果是l1和l2的联合,但l2会覆盖l1
o := onion.New(l1, l2)
// 获取key的最新版本
str := o.GetStringDefault("test.string", "empty")
fmt.Println(str)
}
更多关于golang支持多层配置和加密的配置文件解析插件库onion的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang支持多层配置和加密的配置文件解析插件库onion的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用onion库解析多层加密配置
onion是一个Go语言配置管理库,支持多层配置源、配置热加载和加密配置等功能。下面我将详细介绍如何使用onion库。
基本安装
首先安装onion库:
go get github.com/goraz/onion
基本使用示例
package main
import (
"fmt"
"github.com/goraz/onion"
"log"
)
func main() {
// 创建配置层
o := onion.New()
// 添加环境变量层
o.AddLayer(onion.NewEnvLayer("APP_", true))
// 添加JSON文件层
o.AddLayer(onion.NewFileLayer("./config.json"))
// 获取配置值
port := o.GetIntDefault("server.port", 8080)
debug := o.GetBoolDefault("debug", false)
fmt.Printf("Server will start on port %d, debug mode: %v\n", port, debug)
}
多层配置支持
onion支持多种配置源,可以按优先级叠加:
o := onion.New()
// 1. 默认值层 (最低优先级)
defaults := map[string]interface{}{
"server.port": 8080,
"debug": false,
}
o.AddLayer(onion.NewMapLayer(defaults))
// 2. 配置文件层 (JSON/YAML)
o.AddLayer(onion.NewFileLayer("./config.json"))
// 3. 环境变量层 (较高优先级)
o.AddLayer(onion.NewEnvLayer("APP_", true))
// 4. 命令行参数层 (最高优先级)
o.AddLayer(onion.NewFlagLayer(flag.CommandLine))
加密配置支持
onion支持加密的配置值,使用crypto
子包:
import "github.com/goraz/onion/crypto"
func main() {
o := onion.New()
// 添加加密层
enc := crypto.NewAES([]byte("16-or-32-byte-key-here"))
o.AddLayer(crypto.NewLayer(enc))
// 加密配置文件内容为:
// {
// "db": {
// "password": "enc:AES:U2FsdGVkX1+3v2ZJ6ZvXoQ=="
// }
// }
// 自动解密
dbPass := o.GetString("db.password")
fmt.Println(dbPass) // 输出解密后的密码
}
热加载配置
onion支持配置热加载:
func main() {
o := onion.New()
// 创建可热加载的文件层
layer, err := onion.NewFileLayerWithReload("./config.yaml", time.Minute)
if err != nil {
log.Fatal(err)
}
o.AddLayer(layer)
// 定期检查配置变化
go func() {
for range time.Tick(30 * time.Second) {
if o.ReloadIfNeeded() {
log.Println("Configuration reloaded")
}
}
}()
}
结构体绑定
可以将配置绑定到结构体:
type Config struct {
Server struct {
Port int `onion:"port"`
Host string `onion:"host"`
} `onion:"server"`
Debug bool `onion:"debug"`
}
func main() {
o := onion.New()
o.AddLayer(onion.NewFileLayer("./config.yaml"))
var cfg Config
if err := o.Bind(&cfg); err != nil {
log.Fatal(err)
}
fmt.Printf("Server: %s:%d, Debug: %v\n", cfg.Server.Host, cfg.Server.Port, cfg.Debug)
}
完整示例
package main
import (
"flag"
"fmt"
"log"
"time"
"github.com/goraz/onion"
"github.com/goraz/onion/crypto"
)
func main() {
// 命令行参数
flag.Int("port", 0, "Server port")
flag.Parse()
// 创建配置
o := onion.New()
// 1. 默认值
defaults := map[string]interface{}{
"server.port": 8080,
"server.host": "localhost",
"debug": false,
}
o.AddLayer(onion.NewMapLayer(defaults))
// 2. JSON配置文件
o.AddLayer(onion.NewFileLayer("./config.json"))
// 3. 加密配置层
enc := crypto.NewAES([]byte("my-32-byte-aes-encryption-key"))
o.AddLayer(crypto.NewLayer(enc))
// 4. 环境变量
o.AddLayer(onion.NewEnvLayer("APP_", true))
// 5. 命令行参数
o.AddLayer(onion.NewFlagLayer(flag.CommandLine))
// 热加载配置
layer, err := onion.NewFileLayerWithReload("./config.json", time.Minute)
if err == nil {
o.AddLayer(layer)
go watchConfig(o)
}
// 使用配置
startServer(o)
}
func watchConfig(o *onion.Onion) {
for range time.Tick(30 * time.Second) {
if o.ReloadIfNeeded() {
log.Println("Configuration reloaded")
}
}
}
func startServer(o *onion.Onion) {
port := o.GetInt("server.port")
host := o.GetString("server.host")
debug := o.GetBool("debug")
fmt.Printf("Starting server on %s:%d, debug mode: %v\n", host, port, debug)
}
总结
onion库提供了强大的配置管理功能:
- 支持多层配置源叠加
- 内置加密配置支持
- 支持热加载配置
- 提供结构体绑定
- 支持多种配置格式(JSON/YAML/Env/Flag等)
通过合理使用这些功能,可以构建灵活、安全的应用程序配置系统。