Exemple #1
0
func postBackend(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Errorln(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer r.Body.Close()

	backendName := vars["backend"]
	serviceName := vars["service"]

	backendCfg := client.BackendConfig{Name: backendName}
	err = json.Unmarshal(body, &backendCfg)
	if err != nil {
		log.Errorln(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if err := Registry.AddBackend(serviceName, backendCfg); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	go writeStateConfig()
	w.Write(marshal(Registry.Config()))
}
Exemple #2
0
// Update the global config
func postConfig(w http.ResponseWriter, r *http.Request) {
	cfg := client.Config{}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Errorln(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer r.Body.Close()

	err = json.Unmarshal(body, &cfg)
	if err != nil {
		log.Errorln(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if err := Registry.UpdateConfig(cfg); err != nil {
		log.Errorln(err)
		// TODO: differentiate between ServerError and BadRequest
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
Exemple #3
0
// Update a service and/or backends.
func postService(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Errorln(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer r.Body.Close()

	svcCfg := client.ServiceConfig{Name: vars["service"]}
	err = json.Unmarshal(body, &svcCfg)
	if err != nil {
		log.Errorln(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// don't let someone update the wrong service
	if svcCfg.Name != vars["service"] {
		errMsg := "Mismatched service name in API call"
		log.Error(errMsg)
		http.Error(w, errMsg, http.StatusBadRequest)
		return
	}

	cfg := client.Config{
		Services: []client.ServiceConfig{svcCfg},
	}

	err = Registry.UpdateConfig(cfg)
	//FIXME: this doesn't return an error for an empty or broken service
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.Write(marshal(Registry.Config()))
}
Exemple #4
0
// Update the global config state, including services and backends.
// This does not remove any Services, but will add or update any provided in
// the config.
func (s *ServiceRegistry) UpdateConfig(cfg client.Config) error {

	// Set globals
	// TODO: we might need to unset something
	// TODO: this should remove services and backends to match the submitted config

	if cfg.Balance != "" {
		s.cfg.Balance = cfg.Balance
	}
	if cfg.CheckInterval != 0 {
		s.cfg.CheckInterval = cfg.CheckInterval
	}
	if cfg.Fall != 0 {
		s.cfg.Fall = cfg.Fall
	}
	if cfg.Rise != 0 {
		s.cfg.Rise = cfg.Rise
	}
	if cfg.ClientTimeout != 0 {
		s.cfg.ClientTimeout = cfg.ClientTimeout
	}
	if cfg.ServerTimeout != 0 {
		s.cfg.ServerTimeout = cfg.ServerTimeout
	}
	if cfg.DialTimeout != 0 {
		s.cfg.DialTimeout = cfg.DialTimeout
	}

	// apply the https rediect flag
	if httpsRedirect {
		s.cfg.HTTPSRedirect = true
	}

	invalidPorts := []string{
		// FIXME: lookup bound addresses some other way.  We may have multiple
		//        http listeners, as well as all listening Services.
		// listenAddr[strings.Index(listenAddr, ":")+1:],
		adminListenAddr[strings.Index(adminListenAddr, ":")+1:],
	}

	errors := &multiError{}

	for _, svc := range cfg.Services {
		for _, port := range invalidPorts {
			if strings.HasSuffix(svc.Addr, port) {
				// TODO: report conflicts between service listeners
				errors.Add(fmt.Errorf("Port conflict: %s port %s already bound by shuttle", svc.Name, port))
				continue
			}
		}

		// Add a new service, or update an existing one.
		if Registry.GetService(svc.Name) == nil {
			if err := Registry.AddService(svc); err != nil {
				log.Errorln("Unable to add service %s: %s", svc.Name, err.Error())
				errors.Add(err)
				continue
			}
		} else if err := Registry.UpdateService(svc); err != nil {
			log.Errorln("Unable to update service %s: %s", svc.Name, err.Error())
			errors.Add(err)
			continue
		}
	}

	go writeStateConfig()

	if errors.Len() == 0 {
		return nil
	}
	return errors
}