mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +02:00
feat(settings): add settings management (#906)
This commit is contained in:
parent
5e74a3993b
commit
c7e306841a
93 changed files with 1086 additions and 457 deletions
|
@ -18,6 +18,7 @@ type Handler struct {
|
|||
TeamMembershipHandler *TeamMembershipHandler
|
||||
EndpointHandler *EndpointHandler
|
||||
ResourceHandler *ResourceHandler
|
||||
StatusHandler *StatusHandler
|
||||
SettingsHandler *SettingsHandler
|
||||
TemplatesHandler *TemplatesHandler
|
||||
DockerHandler *DockerHandler
|
||||
|
@ -53,6 +54,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
http.StripPrefix("/api", h.ResourceHandler).ServeHTTP(w, r)
|
||||
} else if strings.HasPrefix(r.URL.Path, "/api/settings") {
|
||||
http.StripPrefix("/api", h.SettingsHandler).ServeHTTP(w, r)
|
||||
} else if strings.HasPrefix(r.URL.Path, "/api/status") {
|
||||
http.StripPrefix("/api", h.StatusHandler).ServeHTTP(w, r)
|
||||
} else if strings.HasPrefix(r.URL.Path, "/api/templates") {
|
||||
http.StripPrefix("/api", h.TemplatesHandler).ServeHTTP(w, r)
|
||||
} else if strings.HasPrefix(r.URL.Path, "/api/upload") {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/portainer/portainer"
|
||||
httperror "github.com/portainer/portainer/http/error"
|
||||
"github.com/portainer/portainer/http/security"
|
||||
|
@ -12,32 +15,69 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// SettingsHandler represents an HTTP API handler for managing settings.
|
||||
// SettingsHandler represents an HTTP API handler for managing Settings.
|
||||
type SettingsHandler struct {
|
||||
*mux.Router
|
||||
Logger *log.Logger
|
||||
settings *portainer.Settings
|
||||
Logger *log.Logger
|
||||
SettingsService portainer.SettingsService
|
||||
}
|
||||
|
||||
// NewSettingsHandler returns a new instance of SettingsHandler.
|
||||
func NewSettingsHandler(bouncer *security.RequestBouncer, settings *portainer.Settings) *SettingsHandler {
|
||||
// NewSettingsHandler returns a new instance of OldSettingsHandler.
|
||||
func NewSettingsHandler(bouncer *security.RequestBouncer) *SettingsHandler {
|
||||
h := &SettingsHandler{
|
||||
Router: mux.NewRouter(),
|
||||
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
||||
settings: settings,
|
||||
Router: mux.NewRouter(),
|
||||
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
||||
}
|
||||
h.Handle("/settings",
|
||||
bouncer.PublicAccess(http.HandlerFunc(h.handleGetSettings)))
|
||||
bouncer.PublicAccess(http.HandlerFunc(h.handleGetSettings))).Methods(http.MethodGet)
|
||||
h.Handle("/settings",
|
||||
bouncer.AdministratorAccess(http.HandlerFunc(h.handlePutSettings))).Methods(http.MethodPut)
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// handleGetSettings handles GET requests on /settings
|
||||
func (handler *SettingsHandler) handleGetSettings(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
httperror.WriteMethodNotAllowedResponse(w, []string{http.MethodGet})
|
||||
settings, err := handler.SettingsService.Settings()
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
encodeJSON(w, handler.settings, handler.Logger)
|
||||
encodeJSON(w, settings, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
// handlePutSettings handles PUT requests on /settings
|
||||
func (handler *SettingsHandler) handlePutSettings(w http.ResponseWriter, r *http.Request) {
|
||||
var req putSettingsRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
httperror.WriteErrorResponse(w, ErrInvalidJSON, http.StatusBadRequest, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
_, err := govalidator.ValidateStruct(req)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, ErrInvalidRequestFormat, http.StatusBadRequest, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
settings := &portainer.Settings{
|
||||
TemplatesURL: req.TemplatesURL,
|
||||
LogoURL: req.LogoURL,
|
||||
BlackListedLabels: req.BlackListedLabels,
|
||||
DisplayExternalContributors: req.DisplayExternalContributors,
|
||||
}
|
||||
|
||||
err = handler.SettingsService.StoreSettings(settings)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
}
|
||||
}
|
||||
|
||||
type putSettingsRequest struct {
|
||||
TemplatesURL string `valid:"required"`
|
||||
LogoURL string `valid:""`
|
||||
BlackListedLabels []portainer.Pair `valid:""`
|
||||
DisplayExternalContributors bool `valid:""`
|
||||
}
|
||||
|
|
38
api/http/handler/status.go
Normal file
38
api/http/handler/status.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"github.com/portainer/portainer"
|
||||
"github.com/portainer/portainer/http/security"
|
||||
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// StatusHandler represents an HTTP API handler for managing Status.
|
||||
type StatusHandler struct {
|
||||
*mux.Router
|
||||
Logger *log.Logger
|
||||
Status *portainer.Status
|
||||
}
|
||||
|
||||
// NewStatusHandler returns a new instance of StatusHandler.
|
||||
func NewStatusHandler(bouncer *security.RequestBouncer, status *portainer.Status) *StatusHandler {
|
||||
h := &StatusHandler{
|
||||
Router: mux.NewRouter(),
|
||||
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
||||
Status: status,
|
||||
}
|
||||
h.Handle("/status",
|
||||
bouncer.PublicAccess(http.HandlerFunc(h.handleGetStatus))).Methods(http.MethodGet)
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// handleGetStatus handles GET requests on /status
|
||||
func (handler *StatusHandler) handleGetStatus(w http.ResponseWriter, r *http.Request) {
|
||||
encodeJSON(w, handler.Status, handler.Logger)
|
||||
return
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/portainer/portainer"
|
||||
httperror "github.com/portainer/portainer/http/error"
|
||||
"github.com/portainer/portainer/http/security"
|
||||
)
|
||||
|
@ -14,8 +15,8 @@ import (
|
|||
// TemplatesHandler represents an HTTP API handler for managing templates.
|
||||
type TemplatesHandler struct {
|
||||
*mux.Router
|
||||
Logger *log.Logger
|
||||
containerTemplatesURL string
|
||||
Logger *log.Logger
|
||||
SettingsService portainer.SettingsService
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -23,11 +24,10 @@ const (
|
|||
)
|
||||
|
||||
// NewTemplatesHandler returns a new instance of TemplatesHandler.
|
||||
func NewTemplatesHandler(bouncer *security.RequestBouncer, containerTemplatesURL string) *TemplatesHandler {
|
||||
func NewTemplatesHandler(bouncer *security.RequestBouncer) *TemplatesHandler {
|
||||
h := &TemplatesHandler{
|
||||
Router: mux.NewRouter(),
|
||||
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
||||
containerTemplatesURL: containerTemplatesURL,
|
||||
Router: mux.NewRouter(),
|
||||
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
||||
}
|
||||
h.Handle("/templates",
|
||||
bouncer.AuthenticatedAccess(http.HandlerFunc(h.handleGetTemplates)))
|
||||
|
@ -49,7 +49,12 @@ func (handler *TemplatesHandler) handleGetTemplates(w http.ResponseWriter, r *ht
|
|||
|
||||
var templatesURL string
|
||||
if key == "containers" {
|
||||
templatesURL = handler.containerTemplatesURL
|
||||
settings, err := handler.SettingsService.Settings()
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
templatesURL = settings.TemplatesURL
|
||||
} else if key == "linuxserver.io" {
|
||||
templatesURL = containerTemplatesURLLinuxServerIo
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue