proxy: start on api and caddy based proxy
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
parent
15619b08f8
commit
a89aa40dda
24 changed files with 461 additions and 48 deletions
24
server/add.go
Normal file
24
server/add.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/ehazlett/element/proxy"
|
||||
)
|
||||
|
||||
func (s *Server) addFrontend(w http.ResponseWriter, r *http.Request) {
|
||||
var frontend *proxy.Frontend
|
||||
if err := json.NewDecoder(r.Body).Decode(&frontend); err != nil {
|
||||
http.Error(w, fmt.Sprintf("invalid fronend: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.proxy.AddFrontend(frontend); err != nil {
|
||||
http.Error(w, fmt.Sprintf("error adding frontend: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
30
server/config.go
Normal file
30
server/config.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (s *Server) getConfig(w http.ResponseWriter, r *http.Request) {
|
||||
cfg, err := s.proxy.Config()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("error getting config: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(cfg); err != nil {
|
||||
http.Error(w, fmt.Sprintf("error serializing config: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) getConfigRaw(w http.ResponseWriter, r *http.Request) {
|
||||
cfg, err := s.proxy.Config()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("error getting config: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(cfg.Body())
|
||||
}
|
|
@ -2,11 +2,25 @@ package server
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ehazlett/element/version"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (s *Server) getRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-Content-Server", "element "+version.FullVersion())
|
||||
w.WriteHeader(http.StatusOK)
|
||||
func (s *Server) genericHandler(w http.ResponseWriter, r *http.Request) {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"host": r.Host,
|
||||
"uri": r.RequestURI,
|
||||
}).Debug("new domain request")
|
||||
|
||||
// TODO: check and / or configure backend container
|
||||
time.Sleep(time.Millisecond * 1000)
|
||||
|
||||
// TODO: update proxy config with new backend
|
||||
time.Sleep(time.Millisecond * 1000)
|
||||
|
||||
// TODO: issue redirect to host to have client re-send and connect to backend
|
||||
|
||||
w.Header().Set("Location", r.RequestURI)
|
||||
w.WriteHeader(http.StatusFound)
|
||||
}
|
||||
|
|
13
server/reload.go
Normal file
13
server/reload.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (s *Server) reload(w http.ResponseWriter, r *http.Request) {
|
||||
if err := s.proxy.Reload(); err != nil {
|
||||
http.Error(w, fmt.Sprintf("error reloading: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
19
server/remove.go
Normal file
19
server/remove.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (s *Server) removeFrontend(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
name := vars["name"]
|
||||
if err := s.proxy.RemoveFrontend(name); err != nil {
|
||||
http.Error(w, fmt.Sprintf("error removing frontend: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
16
server/router.go
Normal file
16
server/router.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package server
|
||||
|
||||
import "github.com/gorilla/mux"
|
||||
|
||||
func (s *Server) router() *mux.Router {
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/", s.genericHandler)
|
||||
r.HandleFunc("/config", s.getConfig).Methods("GET")
|
||||
r.HandleFunc("/config/raw", s.getConfigRaw).Methods("GET")
|
||||
r.HandleFunc("/frontends", s.addFrontend).Methods("POST")
|
||||
r.HandleFunc("/frontends", s.updateFrontend).Methods("PUT")
|
||||
r.HandleFunc("/frontends/{name}", s.removeFrontend).Methods("DELETE")
|
||||
r.HandleFunc("/reload", s.reload).Methods("POST")
|
||||
|
||||
return r
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (s *Server) router() (*mux.Router, error) {
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/", s.getRequestHandler).Methods("GET")
|
||||
|
||||
return r, nil
|
||||
}
|
|
@ -1,44 +1,90 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/ehazlett/element/config"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/ehazlett/element/proxy"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
cfg *config.Config
|
||||
cfg *config.Config
|
||||
proxy *proxy.Proxy
|
||||
}
|
||||
|
||||
func NewServer(cfg *config.Config) (*Server, error) {
|
||||
p, err := proxy.NewProxy(&proxy.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Server{
|
||||
cfg: cfg,
|
||||
cfg: cfg,
|
||||
proxy: p,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Run() error {
|
||||
if s.cfg.EnableMetrics {
|
||||
// start prometheus listener
|
||||
http.Handle("/metrics", prometheus.Handler())
|
||||
go func() {
|
||||
if err := http.ListenAndServe(s.cfg.ListenAddr, nil); err != nil {
|
||||
logrus.Error("unable to start metric listener: %s", err)
|
||||
r := s.router()
|
||||
|
||||
srv := &http.Server{
|
||||
Handler: r,
|
||||
}
|
||||
|
||||
go func() {
|
||||
// check for existing socket
|
||||
if _, err := os.Stat(s.cfg.SocketPath); err == nil {
|
||||
os.Remove(s.cfg.SocketPath)
|
||||
}
|
||||
l, err := net.Listen("unix", s.cfg.SocketPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("unable to start element server: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
srv.Serve(l)
|
||||
}()
|
||||
|
||||
cfg := &proxy.Config{
|
||||
Frontends: map[string]*proxy.Frontend{
|
||||
"element": &proxy.Frontend{
|
||||
Name: "element",
|
||||
Hosts: []string{s.cfg.ListenAddr},
|
||||
Backend: &proxy.Backend{
|
||||
Path: "/",
|
||||
Upstreams: []string{"unix:" + s.cfg.SocketPath},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := s.proxy.Update(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.proxy.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP)
|
||||
go func() {
|
||||
for range c {
|
||||
if err := s.proxy.Reload(); err != nil {
|
||||
logrus.Errorf("error reloading proxy: %s", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
r, err := s.router()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
http.Handle("/", r)
|
||||
|
||||
if err := http.ListenAndServe(s.cfg.ListenAddr, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
s.proxy.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Stop() error {
|
||||
return s.proxy.Stop()
|
||||
}
|
||||
|
|
24
server/update.go
Normal file
24
server/update.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/ehazlett/element/proxy"
|
||||
)
|
||||
|
||||
func (s *Server) updateFrontend(w http.ResponseWriter, r *http.Request) {
|
||||
var frontend *proxy.Frontend
|
||||
if err := json.NewDecoder(r.Body).Decode(&frontend); err != nil {
|
||||
http.Error(w, fmt.Sprintf("invalid fronend: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.proxy.UpdateFrontend(frontend); err != nil {
|
||||
http.Error(w, fmt.Sprintf("error adding frontend: %s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue