Jelajahi Sumber

simple admin dumps working to remotely get JSON dump of leveldb
for backup purposes

Steve Brunton 9 tahun lalu
induk
melakukan
980a87b622
4 mengubah file dengan 65 tambahan dan 4 penghapusan
  1. 17 0
      context/context.go
  2. 3 1
      main.go
  3. 39 0
      web/admin.go
  4. 6 3
      web/web.go

+ 17 - 0
context/context.go

@@ -159,6 +159,23 @@ func (c *Context) Del(key string) error {
 	return c.db.Delete([]byte(key), &opt.WriteOptions{Sync: true})
 }
 
+// get everything in the db so dump it out for backup purposes
+func (c *Context) GetAll() (map [string]Route, error) {
+	golinks := map[string]Route{}
+	iter := c.db.NewIterator(nil, nil)
+	for iter.Next() {
+		key := iter.Key()
+		val := iter.Value()
+		rt := &Route{}
+		if err := rt.read(bytes.NewBuffer(val)); err != nil {
+			return nil, err
+		}
+		golinks[string(key[:])] = *rt
+	}
+
+	return golinks, nil
+}
+
 func (c *Context) commit(id uint64) error {
 	w, err := os.Create(filepath.Join(c.path, idLogFilename))
 	if err != nil {

+ 3 - 1
main.go

@@ -22,6 +22,8 @@ func main() {
 		"The location to use for the data store")
 	flagAddr := flag.String("addr", ":8067",
 		"The address that the HTTP server will bind")
+	flagAdmin := flag.Bool("admin", false,
+		"If allowing admin level requests")
 	flag.Parse()
 
 	ctx, err := context.Open(*flagData)
@@ -30,5 +32,5 @@ func main() {
 	}
 	defer ctx.Close()
 
-	log.Panic(web.ListenAndServe(*flagAddr, getVersion(), ctx))
+	log.Panic(web.ListenAndServe(*flagAddr, *flagAdmin, getVersion(), ctx))
 }

+ 39 - 0
web/admin.go

@@ -0,0 +1,39 @@
+package web
+
+import (
+	"net/http"
+
+	"github.com/kellegous/go/context"
+)
+
+type adminHandler struct {
+	ctx *context.Context
+}
+
+func adminGet(ctx *context.Context, w http.ResponseWriter, r *http.Request) {
+	p := parseName("/admin/", r.URL.Path)
+
+	if p == "" {
+		writeJSONOk(w)
+		return
+	}
+
+	if p == "dumps" {
+		if golinks, err := ctx.GetAll(); err != nil {
+			writeJSONBackendError(w, err)
+			return
+		} else {
+			writeJSON(w, golinks, http.StatusOK)
+		}
+	}
+
+}
+
+func (h *adminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	switch r.Method {
+	case "GET":
+		adminGet(h.ctx, w, r)
+	default:
+		writeJSONError(w, http.StatusText(http.StatusMethodNotAllowed))
+	}
+}

+ 6 - 3
web/web.go

@@ -279,7 +279,7 @@ func (h *defaultHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 }
 
 // Setup a Mux with all web routes.
-func allRoutes(ctx *context.Context, version string) *http.ServeMux {
+func allRoutes(ctx *context.Context, admin bool, version string) *http.ServeMux {
 	mux := http.NewServeMux()
 	mux.Handle("/", &defaultHandler{ctx})
 	mux.Handle("/api/url/", &apiHandler{ctx})
@@ -295,11 +295,14 @@ func allRoutes(ctx *context.Context, version string) *http.ServeMux {
 	mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprintln(w, "OK")
 	})
+	if admin {
+		mux.Handle("/admin/", &adminHandler{ctx})
+	}
 	return mux
 }
 
 // ListenAndServe sets up all web routes, binds the port and handles incoming
 // web requests.
-func ListenAndServe(addr, version string, ctx *context.Context) error {
-	return http.ListenAndServe(addr, allRoutes(ctx, version))
+func ListenAndServe(addr string, admin bool, version string, ctx *context.Context) error {
+	return http.ListenAndServe(addr, allRoutes(ctx, admin, version))
 }