func postBackend(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Errorln("ERROR: ", 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("ERROR: ", 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())) }
// 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("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } defer r.Body.Close() err = json.Unmarshal(body, &cfg) if err != nil { log.Errorln("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := Registry.UpdateConfig(cfg); err != nil { log.Errorln("ERROR: ", err) // TODO: differentiate between ServerError and BadRequest http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func writeStateConfig() { configMutex.Lock() defer configMutex.Unlock() if stateConfig == "" { log.Debug("DEBUG: No state file. Not saving changes") return } cfg := marshal(Registry.Config()) if len(cfg) == 0 { return } lastCfg, _ := ioutil.ReadFile(stateConfig) if bytes.Equal(cfg, lastCfg) { log.Println("INFO: No change in config") return } // We should probably write a temp file and mv for atomic update. err := ioutil.WriteFile(stateConfig, cfg, 0644) if err != nil { log.Errorln("ERROR: Can't save config state:", err) } }
// 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("ERROR: ", 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("ERROR: ", 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.Errorln("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("ERROR: ", err) http.Error(w, err.Error(), http.StatusBadRequest) return } w.Write(marshal(Registry.Config())) }