Centralized Configuration System
Features
- configurable by a GIT repo
- GRPC
- Spring cloud configuration compatible
- REST
- Auto update (currently only with golang client)
QuickStart (demo)
The demo uses the config-sample repository
Run the server
$> docker pull vecosy/vecosy:demo
$> docker run --rm -p 8080:8080 -p 8081:8081 vecosy/vecosy:demo
Generate the JWS token
Use the app1/1.0.0 branch to run
echo "app1" | jose-util sign --key priv.key --alg RS256
the code below has already a valid token for the vecosy:demo
Golang Client
package main
import (
"fmt"
"github.com/spf13/viper"
"github.com/vecosy/vecosy/v2/pkg/vecosy"
)
func main() {
jwsToken := "eyJhbGciOiJSUzI1NiJ9.YXBwMQo.A98GFL-P3vtehn0r5GCO_a0OYb5h6trxg3a8WE9hOPDzJ40yOEGtZxyUM6_3Exk65c52-nzWEEc5P-QtgGrgJFOOZlKneKoa1bYBlWRONoysuq95UtSY0doEOMWGvI9AqB685OzmVPuW2UlHg_HlQuuTO6Re1uKc5gr1qZPlyyWEsfoVYTFbfidLoBKWPOuZTxpd8uRx0Rv3LrrmFEcGPHaMNQ2WiXAEJG6OaMTBtwKiynEFH3DU5Rx2WP9M98bH-emC_w7Zq1xKaCOsj2t09F00KohcGC49zSPgPVpp_TwF1qt6_0d0Mnh_Eqi_NHpobVvO85ZOLS05AyW9LQyA5A"
vecosyCl, err := vecosy.NewClientBuilder("localhost:8081", "app1", "1.0.0", "dev").WithJWSToken(jwsToken).Build(nil)
panicOnError(err)
err = vecosyCl.WatchChanges()
panicOnError(err)
fmt.Printf("db.user:%s\n", viper.GetString("db.user"))
}
func panicOnError(err error) {
if err != nil {
panic(err)
}
}
Spring Client
Take a look to spring-boot-example
Endpoints
Remember to add the Authorization
header with the token generated before Bearer [token]
(except if the server has been started with --insecure
option)
SmartConfig Strategies
from app1/1.0.0
Spring-could Strategies
for spring-app1/v1.0.0
Raw file
for app1/1.0.0
for spring-app1/1.0.0
Docker run
Prepare the configuration
Create a folder for the server configuration $HOME/myVecosyConf
.
Create a $HOME/myVecosyConf/vecosy.yml
with your configuration (see [configuration](#Server Configuration) chapter)
Run
$> docker -d --name myVecosyInstance -v $HOME/myVecosyConf:/config -p 8080:8080 -p 8081:8081 vecosy/vecosy:latest
Server Configuration
some configuration options can be passed via command line run vecosy-server --help
for the options
TLS
server:
tls:
enabled: true
certificateFile: ./myCert.crt
keyFile: ./myCert.key
rest:
address: ":8443"
grpc:
address: ":8081"
...
GIT authentication
No authentication
...
repo:
remote:
url: https://github.com/vecosy/config-sample.git
pullEvery: 30s
local:
path: /tmp/vecosyData
plain authentication
...
repo:
remote:
url: https://github.com/vecosy/config-sample.git
pullEvery: 30s
auth:
type: plain
username: gitRepoUsername
password: gitRepoPassword
local:
path: /tmp/vecosyData
http (basic) authentication
...
repo:
remote:
url: https://github.com/vecosy/config-sample.git
pullEvery: 30s
auth:
type: http
username: gitRepoUsername
password: gitRepoPassword
local:
path: /tmp/vecosyData
public key authentication
...
repo:
remote:
url: github.com:vecosy/config-sample.git
pullEvery: 30s
auth:
type: pubKey
username: git
keyFile: ./myPubKeyFile
keyFilePassword: myPubKeyPassword
local:
path: /tmp/vecosyData
Full Example
server:
tls:
enabled: true
certificateFile: ./myCert.crt
keyFile: ./myCert.key
rest:
address: ":8443"
grpc:
address: ":8081"
repo:
remote:
url: github.com:vecosy/config-sample.git
pullEvery: 30s
auth:
type: pubKey
username: git
keyFile: ./myPubKeyFile
keyFilePassword: myPubKeyPassword
local:
path: /tmp/vecosyData
Configuration Repo
Branching convention
The app configuration is stored in a git repository, vecosy use a branch name convention to manage different configuration on the same repository appName/version
(i.e app1/1.0.0).
Versions
When a configuration request is processed, the system will find the related branch on the git repo appname/appVersion
if the specific version is not present, the nearest (<=
) version will be used.
Merging strategies
Vecosy supports two different merging systems, each one use a different naming convention to merge configuration files.
SmartConfig
The config.yml
in the root folder is the common configuration that will be merged by the specific environment (for dev env: dev/config.yml
).
Example
https://github.com/vecosy/config-sample/tree/app1/1.0.0
Spring style
It uses the spring-cloud naming convention.
The application.yml
will be overriden by [appname].yml
file that will be overriden by [appname]-[profile].yml
Example
https://github.com/vecosy/config-sample/tree/spring-app1/1.0.0
Security
The security is based on a JWS token.
Every application branch has to contains a pub.key
file with the public key of the specific application.
Example
1. Generate the application keys
$ openssl genrsa -out priv.key 2048
$ openssl rsa -in priv.key -outform PEM -pubout -out pub.key
The pub.key
has to be added on the application branch on the git repo at the root level.
The priv.key
will be necessary generating the JWS token for each application that will need the configuration
and should be saved in an external safe place like vault
2. generate a jws token
install jose-util
$ go get -u github.com/square/go-jose/jose-util
$ go install github.com/square/go-jose/jose-util
generate jws token
# the jws payload is not important
$ echo "myAppName" | jose-util sign --key priv.key --alg RS256
the generated token can be used as Bearer Authorization header, in the token
variable in the GRPC metadata header or as spring cloud configuration token
vecosy-client (golang)
passing on the vecosy.NewBuilder(...).WithJWSToken(jwsToken)
parameter
Spring-cloud application (java)
by Spring cloud configuration token
Disable the security
the --insecure
command line option will disable the security system.
Client (Golang)
Vecosy client use viper as configuration system.
Specific viper configuration
cfg := viper.New()
vecosyCl,err := vecosy.NewBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
WithJWStoken(jwsToken).
Build(cfg)
// now you can use cfg to get the your app configuration
cfg.getString("my.app.config")
Default viper configuration
vecosyCl,err := vecosy.NewBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
WithJWStoken(jwsToken).
Build(nil)
viper.getString("my.app.config")
Insecure connection
The server has to be started with --insecure
option
vecosyCl,err := vecosy.NewBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
Insecure().
Build(nil)
viper.getString("my.app.config")
TLS connection
vecosyCl,err:= vecosy.NewBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
WithTLS("./myTrust.crt").
WithJWSToken(jwsToken).
Build(nil)
viper.getString("my.app.config")
Watch changes
vecosyCl,err:= vecosy.NewBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
WithJWStoken(jwsToken).
Build(nil)
vecosyCl.WatchChanges()
This will maintain a GRPC connection with the server that will inform the client on every configuration changes on the git repo.
It's also possible to add handlers to react to the changes
vecosyCl.AddOnChangeHandler(func() {
fmt.Println("something has changed")
})
More info
have a look to the integration test for more details
Future features/improvements
- web interface
- metrics
- different config repo type (etcd, redis,...)
- improving spring compatibility (watch changes doesn't work right now)
Work in progress
Kubernetes helm chart https://github.com/vecosy/helm
License