mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
feat(storidge): introduce endpoint extensions and proxy Storidge API (#1661)
This commit is contained in:
parent
b5e256c967
commit
eb43579378
41 changed files with 571 additions and 372 deletions
97
api/http/handler/extensions/storidge.go
Normal file
97
api/http/handler/extensions/storidge.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
package extensions
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// StoridgeHandler represents an HTTP API handler for proxying requests to the Docker API.
|
||||
type StoridgeHandler struct {
|
||||
*mux.Router
|
||||
Logger *log.Logger
|
||||
EndpointService portainer.EndpointService
|
||||
TeamMembershipService portainer.TeamMembershipService
|
||||
ProxyManager *proxy.Manager
|
||||
}
|
||||
|
||||
// NewStoridgeHandler returns a new instance of StoridgeHandler.
|
||||
func NewStoridgeHandler(bouncer *security.RequestBouncer) *StoridgeHandler {
|
||||
h := &StoridgeHandler{
|
||||
Router: mux.NewRouter(),
|
||||
Logger: log.New(os.Stderr, "", log.LstdFlags),
|
||||
}
|
||||
h.PathPrefix("/{id}/extensions/storidge").Handler(
|
||||
bouncer.AuthenticatedAccess(http.HandlerFunc(h.proxyRequestsToStoridgeAPI)))
|
||||
return h
|
||||
}
|
||||
|
||||
func (handler *StoridgeHandler) proxyRequestsToStoridgeAPI(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
|
||||
parsedID, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusBadRequest, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
endpointID := portainer.EndpointID(parsedID)
|
||||
endpoint, err := handler.EndpointService.Endpoint(endpointID)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
tokenData, err := security.RetrieveTokenData(r)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
memberships, err := handler.TeamMembershipService.TeamMembershipsByUserID(tokenData.ID)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
if tokenData.Role != portainer.AdministratorRole && !security.AuthorizedEndpointAccess(endpoint, tokenData.ID, memberships) {
|
||||
httperror.WriteErrorResponse(w, portainer.ErrEndpointAccessDenied, http.StatusForbidden, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
var storidgeExtension *portainer.EndpointExtension
|
||||
for _, extension := range endpoint.Extensions {
|
||||
if extension.Type == portainer.StoridgeEndpointExtension {
|
||||
storidgeExtension = &extension
|
||||
}
|
||||
}
|
||||
|
||||
if storidgeExtension == nil {
|
||||
httperror.WriteErrorResponse(w, portainer.ErrEndpointExtensionNotSupported, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
proxyExtensionKey := string(endpoint.ID) + "_" + string(portainer.StoridgeEndpointExtension)
|
||||
|
||||
var proxy http.Handler
|
||||
proxy = handler.ProxyManager.GetExtensionProxy(proxyExtensionKey)
|
||||
if proxy == nil {
|
||||
proxy, err = handler.ProxyManager.CreateAndRegisterExtensionProxy(proxyExtensionKey, storidgeExtension.URL)
|
||||
if err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, handler.Logger)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
http.StripPrefix("/"+id+"/extensions/storidge", proxy).ServeHTTP(w, r)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue