mirror of https://github.com/portainer/portainer
144 lines
4.0 KiB
Go
144 lines
4.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
|
|
"github.com/asaskevich/govalidator"
|
|
"github.com/portainer/portainer"
|
|
httperror "github.com/portainer/portainer/http/error"
|
|
"github.com/portainer/portainer/http/proxy"
|
|
"github.com/portainer/portainer/http/security"
|
|
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
// ExtensionHandler represents an HTTP API handler for managing Settings.
|
|
type ExtensionHandler struct {
|
|
*mux.Router
|
|
Logger *log.Logger
|
|
EndpointService portainer.EndpointService
|
|
ProxyManager *proxy.Manager
|
|
}
|
|
|
|
// NewExtensionHandler returns a new instance of ExtensionHandler.
|
|
func NewExtensionHandler(bouncer *security.RequestBouncer) *ExtensionHandler {
|
|
h := &ExtensionHandler{
|
|
Router: mux.NewRouter(),
|
|
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
|
}
|
|
h.Handle("/{endpointId}/extensions",
|
|
bouncer.AuthenticatedAccess(http.HandlerFunc(h.handlePostExtensions))).Methods(http.MethodPost)
|
|
h.Handle("/{endpointId}/extensions/{extensionType}",
|
|
bouncer.AuthenticatedAccess(http.HandlerFunc(h.handleDeleteExtensions))).Methods(http.MethodDelete)
|
|
return h
|
|
}
|
|
|
|
type (
|
|
postExtensionRequest struct {
|
|
Type int `valid:"required"`
|
|
URL string `valid:"required"`
|
|
}
|
|
)
|
|
|
|
func (handler *ExtensionHandler) handlePostExtensions(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
id, err := strconv.Atoi(vars["endpointId"])
|
|
if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusBadRequest, handler.Logger)
|
|
return
|
|
}
|
|
endpointID := portainer.EndpointID(id)
|
|
|
|
endpoint, err := handler.EndpointService.Endpoint(endpointID)
|
|
if err == portainer.ErrEndpointNotFound {
|
|
httperror.WriteErrorResponse(w, err, http.StatusNotFound, handler.Logger)
|
|
return
|
|
} else if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
|
return
|
|
}
|
|
|
|
var req postExtensionRequest
|
|
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
|
|
}
|
|
|
|
extensionType := portainer.EndpointExtensionType(req.Type)
|
|
|
|
var extension *portainer.EndpointExtension
|
|
|
|
for _, ext := range endpoint.Extensions {
|
|
if ext.Type == extensionType {
|
|
extension = &ext
|
|
}
|
|
}
|
|
|
|
if extension != nil {
|
|
extension.URL = req.URL
|
|
} else {
|
|
extension = &portainer.EndpointExtension{
|
|
Type: extensionType,
|
|
URL: req.URL,
|
|
}
|
|
endpoint.Extensions = append(endpoint.Extensions, *extension)
|
|
}
|
|
|
|
err = handler.EndpointService.UpdateEndpoint(endpoint.ID, endpoint)
|
|
if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
|
return
|
|
}
|
|
|
|
encodeJSON(w, extension, handler.Logger)
|
|
}
|
|
|
|
func (handler *ExtensionHandler) handleDeleteExtensions(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
id, err := strconv.Atoi(vars["endpointId"])
|
|
if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusBadRequest, handler.Logger)
|
|
return
|
|
}
|
|
endpointID := portainer.EndpointID(id)
|
|
|
|
endpoint, err := handler.EndpointService.Endpoint(endpointID)
|
|
if err == portainer.ErrEndpointNotFound {
|
|
httperror.WriteErrorResponse(w, err, http.StatusNotFound, handler.Logger)
|
|
return
|
|
} else if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
|
return
|
|
}
|
|
|
|
extType, err := strconv.Atoi(vars["extensionType"])
|
|
if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusBadRequest, handler.Logger)
|
|
return
|
|
}
|
|
extensionType := portainer.EndpointExtensionType(extType)
|
|
|
|
for idx, ext := range endpoint.Extensions {
|
|
if ext.Type == extensionType {
|
|
endpoint.Extensions = append(endpoint.Extensions[:idx], endpoint.Extensions[idx+1:]...)
|
|
}
|
|
}
|
|
|
|
err = handler.EndpointService.UpdateEndpoint(endpoint.ID, endpoint)
|
|
if err != nil {
|
|
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
|
return
|
|
}
|
|
}
|