(w http.ResponseWriter, r *http.Request)
| 153 | } |
| 154 | |
| 155 | func (a *API) handleNodes(w http.ResponseWriter, r *http.Request) { |
| 156 | switch r.Method { |
| 157 | case http.MethodGet: |
| 158 | items, err := a.store.List() |
| 159 | if err != nil { |
| 160 | writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) |
| 161 | return |
| 162 | } |
| 163 | out := make([]map[string]any, 0, len(items)) |
| 164 | for _, n := range items { |
| 165 | out = append(out, a.nodeWithOnline(n)) |
| 166 | } |
| 167 | writeJSON(w, http.StatusOK, map[string]any{"nodes": out}) |
| 168 | case http.MethodPost: |
| 169 | var req upsertNodeRequest |
| 170 | if err := json.NewDecoder(r.Body).Decode(&req); err != nil { |
| 171 | writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid json body"}) |
| 172 | return |
| 173 | } |
| 174 | if req.Name == "" { |
| 175 | writeJSON(w, http.StatusBadRequest, map[string]any{"error": "name is required"}) |
| 176 | return |
| 177 | } |
| 178 | if strings.TrimSpace(req.ID) == "" { |
| 179 | req.ID = idgen.NextString() |
| 180 | } |
| 181 | node, err := a.store.Upsert(nodes.Node{ |
| 182 | ID: req.ID, |
| 183 | Name: req.Name, |
| 184 | BaseURL: strings.TrimRight(req.BaseURL, "/"), |
| 185 | ExpireAt: parseExpireAt(req.ExpireAt), |
| 186 | PanelURL: req.PanelURL, |
| 187 | Remark: req.Remark, |
| 188 | IPOverride: strings.TrimSpace(req.IPOverride), |
| 189 | Disabled: req.Disabled, |
| 190 | ACMEEmail: req.ACMEEmail, |
| 191 | PanelDomain: req.PanelDomain, |
| 192 | ExtraProxies: req.ExtraProxies, |
| 193 | HTTPSPort: req.HTTPSPort, |
| 194 | }) |
| 195 | if err != nil { |
| 196 | writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) |
| 197 | return |
| 198 | } |
| 199 | writeJSON(w, http.StatusOK, node) |
| 200 | default: |
| 201 | writeMethodNotAllowed(w, http.MethodGet+", "+http.MethodPost) |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | func (a *API) handleNodeRoutes(w http.ResponseWriter, r *http.Request) { |
| 206 | path := strings.TrimPrefix(r.URL.Path, "/v1/nodes/") |
nothing calls this directly
no test coverage detected