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变化

还有其他层(如etcdfilewatchlayer)可以监听变化。

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库提供了强大的配置管理功能:

  1. 支持多层配置源叠加
  2. 内置加密配置支持
  3. 支持热加载配置
  4. 提供结构体绑定
  5. 支持多种配置格式(JSON/YAML/Env/Flag等)

通过合理使用这些功能,可以构建灵活、安全的应用程序配置系统。

回到顶部