Go语言实现堡垒机项目实战

          Go语言解析YAML配置文件案例

                                 作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.yaml配置文件

################### Springboard machine Configuration Example #########################

#================================ General ======================================
general:
  # 使用的 cpu 核数,默认使用操作系统的所有 cpu
  max_procs_enable: true
  # log 文件路径
  log_path: /etc/springboardMchine/seelog.xml
  # debug 模式
  debug: true
#================================ HTTP API ======================================
# 用来以 http server 的形式提供对外的api
api:
  host: 0.0.0.0
  port: 8080
#================================ mysql ======================================
#  mysql配置
mysql:
  host: 172.200.1.254
  port: 3306
  name: jumpserver
  user: jason
  password: yinzhengjie

# cache 配置
cache:
  host: 172.200.1.254
  port: 6379
  password: yinzhengjie
  db: 0
#========== rpc ===========
#rpc 配置
rpc:
  host: 0.0.0.0
  port: 8888

二.自定义解析包

package config

import (
    "errors"
    "fmt"
    "github.com/toolkits/file"
    "gopkg.in/yaml.v1"
)

//根据配置文件定义与之对应的结构体字段
type GeneralConfig struct {
    LogPath        string `yaml:"log_path"`
    Debug          bool   `yaml:"debug"`
    MaxProcsEnable bool   `yaml:max_procs_enable`
}

//根据定义的结构体,将配置文件的数据手动生成一个结构体对象
func newGeneralConfig() *GeneralConfig {
    return &GeneralConfig{
        LogPath:        "/etc/springboardMchine/seelog.xml",
        Debug:          true,
        MaxProcsEnable: true,
    }
}

type APIConfig struct {
    Host string `yaml:"host"`
    Port int    `yaml:port`
}

func newAPIConfig() *APIConfig {
    return &APIConfig{
        Host: "0.0.0.0",
        Port: 8080,
    }
}

type MysqlConfig struct {
    Host     string `yaml:"host"`
    Name     string `yaml:"name"`
    Port     int    `yaml:"port"`
    Password string `yaml:"password"`
    User     string `yaml:"user"`
}

func newMysqlConfig() *MysqlConfig {
    return &MysqlConfig{
        Host:     "172.200.1.254",
        Name:     "jumpserver",
        Port:     3306,
        User:     "jason",
        Password: "yinzhengjie",
    }
}

type CacheConfig struct {
    Host     string `yaml:""host`
    Port     int    `yaml:"port"`
    Password string `yaml:"password"`
    Db       int    `yaml:"db"`
}

func newCacheConfig() *CacheConfig {
    return &CacheConfig{
        Host:     "172.200.1.254",
        Port:     6379,
        Db:       0,
        Password: "yinzhengjie",
    }
}

type RpcConfig struct {
    Host string `yaml:"host"`
    Port int    `yaml:"port"`
}

func newRpcConfig() *RpcConfig {
    return &RpcConfig{
        Host: "0.0.0.0",
        Port: 8888,
    }
}

//定义一个结构体,将上述定义的结构体进行封装
type ConfigYaml struct {
    Mysql     *MysqlConfig   `yaml:"mysql"`
    API       *APIConfig     `yaml:"api"`
    RpcClient *RpcConfig     `yaml:"rpc"`
    Cache     *CacheConfig   `yaml:"cache"`
    General   *GeneralConfig `yaml:"general"`
}

//使用封装后的结构体进行实例化
var (
    Config *ConfigYaml = &ConfigYaml{
        Mysql:     newMysqlConfig(),
        API:       newAPIConfig(),
        RpcClient: newRpcConfig(),
        Cache:     newCacheConfig(),
        General:   newGeneralConfig(),
    }
)

//定义连接数据库的函数
func DatabaseDialString() string {
    return fmt.Sprintf("%s:%s@%s(%s:%d)/%s?charset=%s",
        Config.Mysql.User,
        Config.Mysql.Password,
        "tcp",
        Config.Mysql.Host,
        Config.Mysql.Port,
        Config.Mysql.Name,
        "utf8mb4",
    )
}

func Parse(configFile string) error {
    //判断文件是否存在,如果不存在就返回错误
    if !file.IsExist(configFile) {
        return errors.New("config file " + configFile + " is not exist")
    }

    //读取配置文件信息(读取到的数据实际上是字符串),读取失败也会返回错误
    configContent, err := file.ToTrimString(configFile)
    if err != nil {
        return err
    }

    //使用YAML格式进行解析上一步读取到的字符串。
    err = yaml.Unmarshal([]byte(configContent), &Config)
    if err != nil {
        return err
    }
    return nil
}

三.调用解析包

package main

import (
    "flag"
    "fmt"
    "log"
    "os"
    "yinzhengjie/springboardmachine/config"
)

func main() {
    /**
    flag的string方法源代码如下:
        func String(name string, value string, usage string) *string {
            return CommandLine.String(name, value, usage)
        }
    下面是对flag的string方法进行解释说明:
        name:
            指定自定义名称,即用来标识该flag是用来干嘛的。
        value:
            指定默认值。
        usage:
            对当前的flag的一个描述信息
        *string:
            返回值是存储标志值的字符串变量的地址(指针变量)。
     */
    configFile := flag.String("c", "/etc/springboardMchine/seelog.xml", "yaml config file")
    /*
    flag下面的这种写法和上面的作用是一样的,只不过上面的写法更简便,推荐大家使用上面的写法

    var mode string
    flag.StringVar(&mode,"m", "client", "mode[client|server|jump|audit]")
    version := flag.Bool("v", false, "show version")
    */
    //开始进行解析,会将解析的结果复制给上述的configFile,version,mode这3个指针变量。
    flag.Parse()

    //判断配置文件的长度
    if len(*configFile) == 0 {
        log.Println("not have config file.")
        os.Exit(0)
    }

    //解析配置文件
    err := config.Parse(*configFile)
    if err != nil {
        log.Println("parse config file error:", err)
        os.Exit(0)
    }

    //打印解析的参数
    fmt.Println(config.Config.Mysql.Host,config.Config.Mysql.Name,config.Config.Mysql.Port)
}

猜你喜欢

转载自www.cnblogs.com/yinzhengjie2020/p/12902833.html