Skip to content

vecosy/vecosy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

72 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Centralized Configuration System

Build Status codecov Build Status Go Report Card Gitter chat

GitHub FOSSA Status

What is Vecosy

Vecosy is a configuration service exposed through REST/GRPC.

Is Spring Cloud Conf compatible and also provide a Golang client.

The Golang client (or any other GRPC client) has the ability to detect the configuration changes maintaining a connection to the server via a GRPC stream.

A configuration is identified by three elements: application name, application version and the environment.

Vecosy uses a GIT repository as configuration store with a naming convention to identify the correct application branch (appName/appVersion),

The system will find the closest (<=) version *very useful when a new release doesn't need any configuration changes

The security is guaranteed by a JWS token for each application branch and via a TLS connection.

Each application branch can use three different structures/merging strategies: smartConfig, spring, raw (see Configuration repo for more details)

Logical schema

Schema

Why VeCoSy (Versioned Configuration System)

  • Easy to use
  • Secure
    • JWS token for each application
    • TLS
  • Three different merging strategies
    • Smart
    • Spring
    • Raw
  • Compatible

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

Example repo

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

Installation

Prepare the configuration

Create a folder for the server configuration $HOME/myVecosyConf.

Create a $HOME/myVecosyConf/vecosy.ymlwith your configuration (see 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

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

smart config

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

spring config

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

3. Configure your application to use the JWS token

vecosy-client (golang)

passing on the vecosy.NewClientBuilder(...).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.NewClientBuilder("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.NewClientBuilder("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.NewClientBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
        Insecure().
        Build(nil)
    viper.getString("my.app.config")

TLS connection

    vecosyCl,err:= vecosy.NewClientBuilder("my-vecosy-server:8080","myApp", "myAppVersion", "integration").
        WithTLS("./myTrust.crt").
        WithJWSToken(jwsToken).
        Build(nil)
    viper.getString("my.app.config")

Watch changes

    vecosyCl,err:= vecosy.NewClientBuilder("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(prevConfiguration map[string]interface{}) {
        fmt.Printf("something has changed from %+v to %+v",prevConfiguration, viper.AllSettings())
    })

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

FOSSA Status

About

Centralized Configuration System written in Golang - Spring cloud compatible

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages