目录
  • 背景
  • 实现
    • 工具
    • 打包
    • 调用
  • 总结

    众所周知,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打包配置文件内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!