Golang打包配置文件的實現示例

眾所周知,Golang 適合寫 CLI 工具,但你可能還不知道 Golang 還可以打包配置文件。

背景

最近在寫一個涉及到管理阿裡雲 ECS 的 CLI 工具,這裡當然就要考慮阿裡雲資源使用的安全性瞭,要求阿裡雲賬號的 AccessKeyId 和 AccessKeySecret 不能下發給 CLI 工具的使用者。

所以這裡選擇將一份包含 AccessKeyId 和 AccessKeySecret 的配置文件打包進瞭 CLI 工具中,CLI 工具的使用者默認將使用已經打包瞭的配置文件,當然也可以通過指定配置文件或傳遞參數的方式使用新的配置信息。

實現

工具

這裡將介紹 Golang 的一個可以把任意文件轉換成 Go 代碼的庫 go-bindata,可以用於嵌入二進制文件到 Go 程序中。同時,也支持在轉換成原始的字節切片前使用 gzip 進行壓縮文件數據。
關於該工具的具體介紹請跳轉至 https://github.com/go-bindata/go-bindata

打包

使用 go-bindata 工具將包含敏感信息的配置文件轉換成 Go 的源代碼,下面是項目 Makefile 的部分內容,工具名稱就叫 mycli 吧。

NAME = mycli
CONFIG = configs/config.yaml

.PHONY: build

build:
    cp $(CONFIG) config.yaml
    mkdir -p cmd/mycli/asset
    go-bindata -pkg asset -o cmd/mycli/asset/asset.go \
        scripts/... \
        config.yaml
    
    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/linux/mycli cmd/mycli/*.go
    CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o bin/darwin/mycli cmd/mycli/*.go
    
    chmod +x ./bin/linux/mycli ./bin/darwin/mycli
    rm -f config.yaml mycli
    ln -s bin/linux/mycli mycli

其中將文件轉換成 Go 源代碼的部分如下:

go-bindata -pkg asset -o cmd/mycli/asset/asset.go \
    scripts/... \
    config.yaml

關於 go-bindata 命令行工具的選項說明:

  • -pkg 指定 package 名稱,調用的寫法將變成 asset.Asset(“config.yaml”)
  • -o 指定生成的 Go 源代碼存放的位置

生成的 asset.go 代碼如下:

// Code generated by go-bindata.
// sources:
// scripts/create.sh
// scripts/sub/delete.sh
// config.yaml
// DO NOT EDIT!

package asset

func bindataRead(data []byte, name string) ([]byte, error) {
    ...
}

type asset struct {
 bytes []byte
 info  os.FileInfo
}

type bindataFileInfo struct {
 name    string
 size    int64
 mode    os.FileMode
 modTime time.Time
}

func (fi bindataFileInfo) Name() string {
 return fi.name
}
func (fi bindataFileInfo) Size() int64 {
 return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
 return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
 return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
 return false
}
func (fi bindataFileInfo) Sys() interface{} {
 return nil
}

...

調用

使用 Asset 方法進行加載打包好的配置文件:

const preloadConfigFile = "config.yaml"

type Config struct {
    ...
}

func PreloadConfig() (*Config, error) {
    b, err := asset.Asset(preloadConfigFile)
    if err != nil {
        return nil, fmt.Errorf("failed to read config: %v", err)
    }
    var config *Config
    err = yaml.Unmarshal(b, &config)
    return config, err
}

總結

使用 go-bindata 將文件轉換成 Go 的源代碼,然後編譯成二進制文件,最終隻需要將二進制文件交給使用者,通過這種方式可以減少工具的使用者對一些敏感信息的直接接觸,保障資源的安全性。
其實,真正要做到對資源訪問的完全把控,可以將 CLI 工具再次進行封裝成 Jenkins job 類似的可視化操作界面,既方便使用者使用,又可以限制使用者對工具的使用范圍,包括傳遞給 CLI 工具的參數。

到此這篇關於Golang打包配置文件的實現示例的文章就介紹到這瞭,更多相關Golang打包配置文件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: