service -> configuration

This commit is contained in:
emile 2015-09-08 00:15:14 +02:00
parent 7fcc4761da
commit cef926379c
5 changed files with 53 additions and 51 deletions

View file

@ -19,7 +19,7 @@ type Route struct {
Rules map[string]Rule Rules map[string]Rule
} }
type Service struct { type Configuration struct {
Backends map[string]Backend Backends map[string]Backend
Routes map[string]Route Routes map[string]Route
} }

View file

@ -1,5 +1,5 @@
package main package main
import( import (
"github.com/fsouza/go-dockerclient" "github.com/fsouza/go-dockerclient"
"github.com/leekchan/gtf" "github.com/leekchan/gtf"
"bytes" "bytes"
@ -13,27 +13,29 @@ type DockerProvider struct {
dockerClient *docker.Client dockerClient *docker.Client
} }
func (provider *DockerProvider) Provide(serviceChan chan<- *Service){ func (provider *DockerProvider) Provide(configurationChan chan <- *Configuration) {
provider.dockerClient, _ = docker.NewClient(provider.Endpoint) provider.dockerClient, _ = docker.NewClient(provider.Endpoint)
dockerEvents := make(chan *docker.APIEvents) dockerEvents := make(chan *docker.APIEvents)
if(provider.Watch) { if (provider.Watch) {
provider.dockerClient.AddEventListener(dockerEvents) provider.dockerClient.AddEventListener(dockerEvents)
} }
go func() { go func() {
for { for {
event := <-dockerEvents event := <-dockerEvents
log.Println("Event receveived", event) log.Println("Event receveived", event)
service:= provider.loadDockerConfig() configuration := provider.loadDockerConfig()
serviceChan <- service if (configuration != nil) {
configurationChan <- configuration
}
} }
}() }()
service:= provider.loadDockerConfig() configuration := provider.loadDockerConfig()
serviceChan <- service configurationChan <- configuration
} }
func (provider *DockerProvider) loadDockerConfig() *Service { func (provider *DockerProvider) loadDockerConfig() *Configuration {
service := new(Service) configuration := new(Configuration)
containerList, _ := provider.dockerClient.ListContainers(docker.ListContainersOptions{}) containerList, _ := provider.dockerClient.ListContainers(docker.ListContainersOptions{})
containersInspected := []docker.Container{} containersInspected := []docker.Container{}
for _, container := range containerList { for _, container := range containerList {
@ -59,9 +61,9 @@ func (provider *DockerProvider) loadDockerConfig() *Service {
return nil return nil
} }
if _, err := toml.Decode(buffer.String(), service); err != nil { if _, err := toml.Decode(buffer.String(), configuration); err != nil {
log.Println("Error creating docker service:", err) log.Println("Error creating docker configuration:", err)
return nil return nil
} }
return service return configuration
} }

20
file.go
View file

@ -14,7 +14,7 @@ type FileProvider struct {
Filename string Filename string
} }
func (provider *FileProvider) Provide(serviceChan chan<- *Service){ func (provider *FileProvider) Provide(configurationChan chan<- *Configuration){
watcher, err := fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -37,9 +37,9 @@ func (provider *FileProvider) Provide(serviceChan chan<- *Service){
case event := <-watcher.Events: case event := <-watcher.Events:
if(strings.Contains(event.Name,file.Name())){ if(strings.Contains(event.Name,file.Name())){
log.Println("File event:", event) log.Println("File event:", event)
service := provider.LoadFileConfig(file.Name()) configuration := provider.LoadFileConfig(file.Name())
if(service != nil) { if(configuration != nil) {
serviceChan <- service configurationChan <- configuration
} }
} }
case error := <-watcher.Errors: case error := <-watcher.Errors:
@ -58,17 +58,17 @@ func (provider *FileProvider) Provide(serviceChan chan<- *Service){
} }
service:= provider.LoadFileConfig(file.Name()) configuration := provider.LoadFileConfig(file.Name())
serviceChan <- service configurationChan <- configuration
<-done <-done
} }
func (provider *FileProvider) LoadFileConfig(filename string) *Service { func (provider *FileProvider) LoadFileConfig(filename string) *Configuration {
service := new(Service) configuration := new(Configuration)
if _, err := toml.DecodeFile(filename, service); err != nil { if _, err := toml.DecodeFile(filename, configuration); err != nil {
log.Println("Error reading file:", err) log.Println("Error reading file:", err)
return nil return nil
} }
return service return configuration
} }

View file

@ -1,5 +1,5 @@
package main package main
type Provider interface { type Provider interface {
Provide(chan<- *Service) Provide(chan<- *Configuration)
} }

View file

@ -18,16 +18,16 @@ import (
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
) )
type Configuration struct { type FileConfiguration struct {
Docker *DockerProvider Docker *DockerProvider
File *FileProvider File *FileProvider
} }
var srv *graceful.Server var srv *graceful.Server
var serviceRouter *mux.Router var configurationRouter *mux.Router
var renderer = render.New() var renderer = render.New()
var currentService = new(Service) var currentConfiguration = new(Configuration)
var serviceChan = make(chan *Service) var configurationChan = make(chan *Configuration)
var providers = []Provider{} var providers = []Provider{}
func main() { func main() {
@ -41,15 +41,15 @@ func main() {
go func() { go func() {
for { for {
service := <-serviceChan configuration := <-configurationChan
log.Println("Service receveived", service) log.Println("Configuration receveived", configuration)
if service == nil { if configuration == nil {
log.Println("Skipping nil service") log.Println("Skipping empty configuration")
} else if(reflect.DeepEqual(currentService, service)){ } else if(reflect.DeepEqual(currentConfiguration, configuration)){
log.Println("Skipping same service") log.Println("Skipping same configuration")
} else{ } else{
currentService = service currentConfiguration = configuration
serviceRouter = LoadConfig(service) configurationRouter = LoadConfig(configuration)
srv.Stop(10 * time.Second) srv.Stop(10 * time.Second)
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
} }
@ -66,11 +66,11 @@ func main() {
providers = append(providers, configuration.File) providers = append(providers, configuration.File)
} }
go func() {
for _, provider := range providers { for _, provider := range providers {
provider.Provide(serviceChan) go func() {
} provider.Provide(configurationChan)
}() }()
}
goAway := false goAway := false
go func() { go func() {
@ -94,7 +94,7 @@ func main() {
Server: &http.Server{ Server: &http.Server{
Addr: ":8001", Addr: ":8001",
Handler: serviceRouter, Handler: configurationRouter,
}, },
} }
@ -105,9 +105,9 @@ func main() {
} }
} }
func LoadConfig(service *Service) *mux.Router { func LoadConfig(configuration *Configuration) *mux.Router {
router := mux.NewRouter() router := mux.NewRouter()
for routeName, route := range service.Routes { for routeName, route := range configuration.Routes {
log.Println("Creating route", routeName) log.Println("Creating route", routeName)
fwd, _ := forward.New() fwd, _ := forward.New()
newRoutes := []*mux.Route{} newRoutes := []*mux.Route{}
@ -121,7 +121,7 @@ func LoadConfig(service *Service) *mux.Router {
log.Println("Creating backend", backendName) log.Println("Creating backend", backendName)
lb, _ := roundrobin.New(fwd) lb, _ := roundrobin.New(fwd)
rb, _ := roundrobin.NewRebalancer(lb) rb, _ := roundrobin.NewRebalancer(lb)
for serverName, server := range service.Backends[backendName].Servers { for serverName, server := range configuration.Backends[backendName].Servers {
log.Println("Creating server", serverName) log.Println("Creating server", serverName)
url, _ := url.Parse(server.Url) url, _ := url.Parse(server.Url)
rb.UpsertServer(url) rb.UpsertServer(url)
@ -135,7 +135,7 @@ func LoadConfig(service *Service) *mux.Router {
} }
func DeployService() { func DeployService() {
serviceRouter = LoadConfig(currentService) configurationRouter = LoadConfig(currentConfiguration)
} }
func ReloadConfigHandler(rw http.ResponseWriter, r *http.Request) { func ReloadConfigHandler(rw http.ResponseWriter, r *http.Request) {
@ -149,7 +149,7 @@ func RestartHandler(rw http.ResponseWriter, r *http.Request) {
} }
func GetConfigHandler(rw http.ResponseWriter, r *http.Request) { func GetConfigHandler(rw http.ResponseWriter, r *http.Request) {
renderer.JSON(rw, http.StatusOK, currentService) renderer.JSON(rw, http.StatusOK, currentConfiguration)
} }
func Invoke(any interface{}, name string, args ...interface{}) []reflect.Value { func Invoke(any interface{}, name string, args ...interface{}) []reflect.Value {
@ -160,8 +160,8 @@ func Invoke(any interface{}, name string, args ...interface{}) []reflect.Value {
return reflect.ValueOf(any).MethodByName(name).Call(inputs) return reflect.ValueOf(any).MethodByName(name).Call(inputs)
} }
func LoadFileConfig() *Configuration { func LoadFileConfig() *FileConfiguration {
configuration := new(Configuration) configuration := new(FileConfiguration)
if _, err := toml.DecodeFile("tortuous.toml", configuration); err != nil { if _, err := toml.DecodeFile("tortuous.toml", configuration); err != nil {
log.Fatal("Error reading file:", err) log.Fatal("Error reading file:", err)
} }