1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package server
16
17 import (
18 "encoding/json"
19 "fmt"
20 "net/http"
21
22 "github.com/go-chi/chi/v5"
23 "gitlab.com/flimzy/httpe"
24
25 internal "github.com/go-kivik/kivik/v4/int/errors"
26 "github.com/go-kivik/kivik/v4/x/server/config"
27 )
28
29 const nodeLocal = "_local"
30
31 func (s *Server) allConfig() httpe.HandlerWithError {
32 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error {
33 if node := chi.URLParam(r, "node-name"); node != nodeLocal {
34 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)}
35 }
36 conf, err := s.config.All(r.Context())
37 if err != nil {
38 return err
39 }
40 return serveJSON(w, http.StatusOK, conf)
41 })
42 }
43
44 func (s *Server) configSection() httpe.HandlerWithError {
45 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error {
46 if node := chi.URLParam(r, "node-name"); node != nodeLocal {
47 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)}
48 }
49 section, err := s.config.Section(r.Context(), chi.URLParam(r, "section"))
50 if err != nil {
51 return err
52 }
53 return serveJSON(w, http.StatusOK, section)
54 })
55 }
56
57 func (s *Server) configKey() httpe.HandlerWithError {
58 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error {
59 if node := chi.URLParam(r, "node-name"); node != nodeLocal {
60 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)}
61 }
62 key, err := s.config.Key(r.Context(), chi.URLParam(r, "section"), chi.URLParam(r, "key"))
63 if err != nil {
64 return err
65 }
66 return serveJSON(w, http.StatusOK, key)
67 })
68 }
69
70 func (s *Server) reloadConfig() httpe.HandlerWithError {
71 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error {
72 if node := chi.URLParam(r, "node-name"); node != nodeLocal {
73 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)}
74 }
75 if err := s.config.Reload(r.Context()); err != nil {
76 return err
77 }
78 return serveJSON(w, http.StatusOK, map[string]bool{"ok": true})
79 })
80 }
81
82 func (s *Server) setConfigKey() httpe.HandlerWithError {
83 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error {
84 if node := chi.URLParam(r, "node-name"); node != nodeLocal {
85 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)}
86 }
87 confWriter, ok := s.config.(config.Writer)
88 if !ok {
89 return &internal.Error{Status: http.StatusMethodNotAllowed, Message: "configuration is read-only"}
90 }
91 var newValue string
92 if err := json.NewDecoder(r.Body).Decode(&newValue); err != nil {
93 return &internal.Error{Status: http.StatusBadRequest, Err: err}
94 }
95 oldValue, err := confWriter.SetKey(r.Context(), chi.URLParam(r, "section"), chi.URLParam(r, "key"), newValue)
96 if err != nil {
97 return err
98 }
99 return serveJSON(w, http.StatusOK, oldValue)
100 })
101 }
102
103 func (s *Server) deleteConfigKey() httpe.HandlerWithError {
104 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error {
105 if node := chi.URLParam(r, "node-name"); node != nodeLocal {
106 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)}
107 }
108 confWriter, ok := s.config.(config.Writer)
109 if !ok {
110 return &internal.Error{Status: http.StatusMethodNotAllowed, Message: "configuration is read-only"}
111 }
112 oldValue, err := confWriter.Delete(r.Context(), chi.URLParam(r, "section"), chi.URLParam(r, "key"))
113 if err != nil {
114 return err
115 }
116 return serveJSON(w, http.StatusOK, oldValue)
117 })
118 }
119
View as plain text