git.zd.zone/hrpc/hrpc@v0.0.12/configs/configs.go (about) 1 package configs 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 8 "github.com/hashicorp/consul/api" 9 ) 10 11 var ( 12 // ErrKeyNotExist for invalid key provided 13 ErrKeyNotExist = errors.New("the key does not exist") 14 // ErrNotInitialized for uninitialized 15 ErrNotInitialized = errors.New("the client does not be initialized, call With() first") 16 ) 17 18 type Configs interface { 19 Prefix() string 20 21 Get(key string) ([]byte, error) 22 SGet(k string) ([]byte, error) 23 24 Set(key, val string) error 25 } 26 27 type configs struct { 28 Token string 29 DataCenter string 30 Address string 31 prefix string 32 33 client *api.Client 34 } 35 36 var ( 37 cfg configs 38 serverName string 39 ) 40 41 func New(addr, dc, prefix, token, sName string) *configs { 42 serverName = sName 43 cfg = configs{ 44 DataCenter: dc, 45 prefix: prefix, 46 Address: addr, 47 Token: token, 48 } 49 return &cfg 50 } 51 52 func (c *configs) DependsOn() []string { 53 return nil 54 } 55 56 func (c *configs) Name() string { 57 return "hrpc-configs" 58 } 59 60 func (c *configs) Loaded() bool { 61 return c != nil && c.client != nil 62 } 63 64 func (c *configs) mergeENV() { 65 if token := os.Getenv("CONFIGS_TOKEN"); token != "" { 66 c.Token = token 67 } 68 if addr := os.Getenv("CONFIGS_ADDR"); addr != "" { 69 c.Address = addr 70 } 71 if dc := os.Getenv("CONFIGS_DATACENTER"); dc != "" { 72 c.DataCenter = dc 73 } 74 } 75 76 func (c *configs) Load() error { 77 c.mergeENV() 78 config := api.DefaultConfig() 79 config.Address = c.Address 80 config.Token = c.Token 81 config.Datacenter = c.DataCenter 82 v, err := api.NewClient(config) 83 if err != nil { 84 return err 85 } 86 c.client = v 87 return nil 88 } 89 90 func (c *configs) Prefix() string { 91 return c.prefix 92 } 93 94 // Get returns the value of the key from consul 95 // WARNING: Please try to use SGet() to get the configs from consul 96 func (c *configs) Get(key string) ([]byte, error) { 97 if c.client == nil { 98 return nil, ErrNotInitialized 99 } 100 data, _, err := c.client.KV().Get( 101 fmt.Sprintf("%s/%s", c.prefix, key), 102 nil, 103 ) 104 if err != nil { 105 return nil, err 106 } 107 if data == nil { 108 return nil, ErrKeyNotExist 109 } 110 return data.Value, nil 111 } 112 113 // Set will push a config pair to consul 114 func (c *configs) Set(key, val string) error { 115 if c.client == nil { 116 return ErrNotInitialized 117 } 118 _, err := c.client.KV().Put( 119 &api.KVPair{ 120 Key: fmt.Sprintf("%s/%s", c.prefix, key), 121 Value: []byte(val), 122 }, nil, 123 ) 124 if err != nil { 125 return err 126 } 127 return nil 128 } 129 130 // SGet is recommended to use for getting configs from consul instead of using `Get()` directly. 131 // The main difference between `Get()` and `SGet()` is that the `SGet()` makes a limitation for the config's path. 132 // Before using this function to retrive the configs, you should make sure that your configs must be created at: 133 // 134 // [environment]/services/[server name]/[your key] 135 // 136 // Ex. the service name is `userservice`. 137 // 138 // the config key is `abcd` 139 // development/services/userservice/abcd 140 func (c *configs) SGet(k string) ([]byte, error) { 141 if c.client == nil { 142 return nil, ErrNotInitialized 143 } 144 data, _, err := c.client.KV().Get( 145 fmt.Sprintf("%s/services/%s/%s", c.prefix, serverName, k), 146 nil, 147 ) 148 if err != nil { 149 return nil, err 150 } 151 if data == nil { 152 return nil, ErrKeyNotExist 153 } 154 return data.Value, nil 155 } 156 157 // Client returns the consul client 158 func Client() *api.Client { 159 return cfg.client 160 } 161 162 func Get() Configs { 163 return &cfg 164 }