Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gustavohenrique/coolconf
Share configuration across all Go packages
https://github.com/gustavohenrique/coolconf
configuration golang
Last synced: about 1 month ago
JSON representation
Share configuration across all Go packages
- Host: GitHub
- URL: https://github.com/gustavohenrique/coolconf
- Owner: gustavohenrique
- License: apache-2.0
- Created: 2021-01-13T11:20:58.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2023-11-30T21:41:01.000Z (about 1 year ago)
- Last Synced: 2024-04-16T03:18:22.493Z (9 months ago)
- Topics: configuration, golang
- Language: Go
- Homepage:
- Size: 45.9 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CoolConf
[![Coverage Status](https://coveralls.io/repos/github/gustavohenrique/coolconf/badge.svg?branch=main)](https://coveralls.io/github/gustavohenrique/coolconf?branch=main)
CoolConf shares information across all packages. You can use your custom struct with annotated fields to store da read from environment variables, YAML files, or encrypted strings.
## Installation
```sh
go get github.com/gustavohenrique/coolconf/.../
```## Usage
### Reading data
#### Environment variables
Initial values:
```sh
export SOME_INT=9
export SOME_STR=hi
export SOME_BOOL=true
export DATABASE_URL_DEV="postgres://user:pass@dev"
export STAGING__DATABASE_URL="postgres://user:pass@staging"
```The configuration struct must have the `env` annotation with the envvar's name.
```go
package main
import (
"fmt"
"github.com/gustavohenrique/coolconf"
)type MyConfig struct {
Number int `env:"SOME_INT"`
Text string `env:"SOME_STR"`
Yes bool `env:"SOME_BOOL"`
}func init() {
coolconf.New()
}func main() {
var myConfig MyConfig
coolconf.Load(&myConfig)
fmt.Println(myConfig.Text)
fmt.Println(myConfig.Number)
fmt.Println(myConfig.Yes)
}
```You can use a second argument to add a suffix or prefix with _ as the default separator.
```go
type MyConfig struct {
DatabaseURL string `env:"DATABASE_URL"`
}func init() {
coolconf.New()
}func main() {
var myConfig MyConfig
coolconf.Load(&myConfig, "DEV")
fmt.Println(myConfig.DatabaseURL)
// output is postgres://user:pass@devcoolconf.New(coolconf.Settings{
Source: coolconf.ENV,
Env: coolconf.Option{
UseGroupAsPrefix: true,
Separator: "__",
},
})
coolconf.Load(&myConfig, "STAGING")
fmt.Println(myConfig.DatabaseURL)
// output is postgres://user:pass@staging
}
```#### YAML file
File must end with .yaml or .yml.
```sh
echo "database_url: postgres://user:pass@localhost" > /tmp/config.yaml
echo "database_url: postgres://user:pass@dev" > /tmp/config_dev.yaml
```The configuration struct must have the `YAML` annotation with the envvar's name.
```go
package main
import (
"fmt"
"github.com/gustavohenrique/coolconf"
)type MyConfig struct {
DatabaseURL string `yaml:"database_url"`
}func init() {
coolconf.New(coolconf.Settings{
Source: "/tmp/config.yaml",
})
}func main() {
var myConfig MyConfig
coolconf.Load(&myConfig)
fmt.Println(myConfig.DatabaseURL)
// output: postgres://user:pass@localhost
}
```
The second argument is the suffix or prefix with _ as default separator to the filename.```go
func main() {
var myConfig MyConfig
coolconf.Load(&myConfig, "dev")
fmt.Println(myConfig.DatabaseURL)
// output: postgres://user:pass@dev
}
```You can configure to create the YAML file using default values, if the file does not exists:
```go
package main
import (
"fmt"
"github.com/gustavohenrique/coolconf"
)
type MyConfig struct {
Host string `yaml:"host" default:"localhost"`
Port int `yaml:"port" default:"8080"`
}
func main() {
coolconf.New(coolconf.Settings{
Source: "/tmp/server.yaml",
ShouldCreateDefaultYaml: true,
})
var myConfig MyConfig
coolconf.Load(&myConfig)
fmt.Println(myConfig.Host, ":", myConfig.Port)
// output: localhost:8080
}
```#### Encrypted string
CoolConf provides the `cccli` tool to allow you to encrypt/decrypt files using [AES256-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
You can encrypt a YAML file and store it in an S3 bucket and decrypt this file on the application's boot, for example.**Be careful**: keep your password safe and do not allow public access to your encrypted file.
```sh
echo "database_url: postgres://user:pass@localhost" > /tmp/config.yaml# generate an encrypted file
cccli -encrypt /tmp/config.yaml -output /tmp/encrypted.yaml -secret mystrongpassword# reverse the file to an decrypted state
cccli -decrypt /tmp/encrypted.yaml -output /tmp/config.yaml -secret mystrongpassword
```This example read the hex string encrypted from the file:
```go
package main
import (
"fmt"
"log"
"io/ioutil""github.com/gustavohenrique/coolconf"
)type MyConfig struct {
DatabaseURL string `yaml:"database_url"`
}func init() {
coolconf.New(coolconf.Settings{
Encrypted: true,
SecretKey: "mystrongpass",
})
}func main() {
bytes, _ := ioutil.ReadFile("/tmp/encrypted.yaml")
err := coolconf.DecryptYaml(bytes)
if err != nil {
log.Fatalln(err)
}
var myConfig MyConfig
coolconf.Load(&myConfig)
fmt.Println(myConfig.DatabaseURL)
// output: postgres://user:pass@localhost
}
```### Reset configuration
You can reset the configuration clearing the old data and loading the new one.
For web applications, you can add a secret endpoint to do it, allowing your application gets a new configuration without a redeploy.```go
package mainimport (
"os"
"log"
"net/http"
"github.com/gustavohenrique/coolconf"
)type MyConfig struct {
DatabaseURL string `env:"DATABASE_URL"`
}func init() {
coolconf.New()
os.Setenv("DATABASE_URL", "postgres://user:pass@localhost")
}func view(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
var myConfig MyConfig
coolconf.Load(&myConfig)
w.WriteHeader(http.StatusOK)
w.Write([]byte("value=" + myConfig.DatabaseURL))
}
}func reload(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
coolconf.Clear()
os.Setenv("DATABASE_URL", "postgres://admin:[email protected]")
w.WriteHeader(http.StatusOK)
w.Write([]byte("reloaded!"))
}
}func main() {
http.HandleFunc("/", view)
http.HandleFunc("/reload", reload)
log.Println("Listening :8080")
log.Fatal(http.ListenAndServe(":8080",nil))
}
```See the magic happening:
```sh
curl http://localhost:8080/
value=postgres://user:pass@localhostcurl http://localhost:8080/reload
reloaded!curl http://localhost:8080/
value=postgres://admin:[email protected]
```## License
Copyright 2021 Gustavo Henrique
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.