mirror of
https://github.com/portainer/portainer.git
synced 2025-07-23 15:29:42 +02:00
feat(stacks): support compose v2.0 stack (#1963)
This commit is contained in:
parent
ef15cd30eb
commit
e3d564325b
174 changed files with 7898 additions and 5849 deletions
|
@ -10,7 +10,7 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
// applyResourceAccessControl returns an optionally decorated object as the first return value and the
|
||||
// applyResourceAccessControlFromLabel returns an optionally decorated object as the first return value and the
|
||||
// access level for the user (granted or denied) as the second return value.
|
||||
// It will retrieve an identifier from the labels object. If an identifier exists, it will check for
|
||||
// an existing resource control associated to it.
|
||||
|
|
|
@ -8,10 +8,11 @@ import (
|
|||
|
||||
const (
|
||||
// ErrDockerContainerIdentifierNotFound defines an error raised when Portainer is unable to find a container identifier
|
||||
ErrDockerContainerIdentifierNotFound = portainer.Error("Docker container identifier not found")
|
||||
containerIdentifier = "Id"
|
||||
containerLabelForServiceIdentifier = "com.docker.swarm.service.id"
|
||||
containerLabelForStackIdentifier = "com.docker.stack.namespace"
|
||||
ErrDockerContainerIdentifierNotFound = portainer.Error("Docker container identifier not found")
|
||||
containerIdentifier = "Id"
|
||||
containerLabelForServiceIdentifier = "com.docker.swarm.service.id"
|
||||
containerLabelForSwarmStackIdentifier = "com.docker.stack.namespace"
|
||||
containerLabelForComposeStackIdentifier = "com.docker.compose.project"
|
||||
)
|
||||
|
||||
// containerListOperation extracts the response as a JSON object, loop through the containers array
|
||||
|
@ -71,7 +72,12 @@ func containerInspectOperation(response *http.Response, executor *operationExecu
|
|||
return rewriteAccessDeniedResponse(response)
|
||||
}
|
||||
|
||||
responseObject, access = applyResourceAccessControlFromLabel(containerLabels, responseObject, containerLabelForStackIdentifier, executor.operationContext)
|
||||
responseObject, access = applyResourceAccessControlFromLabel(containerLabels, responseObject, containerLabelForSwarmStackIdentifier, executor.operationContext)
|
||||
if !access {
|
||||
return rewriteAccessDeniedResponse(response)
|
||||
}
|
||||
|
||||
responseObject, access = applyResourceAccessControlFromLabel(containerLabels, responseObject, containerLabelForComposeStackIdentifier, executor.operationContext)
|
||||
if !access {
|
||||
return rewriteAccessDeniedResponse(response)
|
||||
}
|
||||
|
@ -117,7 +123,8 @@ func decorateContainerList(containerData []interface{}, resourceControls []porta
|
|||
|
||||
containerLabels := extractContainerLabelsFromContainerListObject(containerObject)
|
||||
containerObject = decorateResourceWithAccessControlFromLabel(containerLabels, containerObject, containerLabelForServiceIdentifier, resourceControls)
|
||||
containerObject = decorateResourceWithAccessControlFromLabel(containerLabels, containerObject, containerLabelForStackIdentifier, resourceControls)
|
||||
containerObject = decorateResourceWithAccessControlFromLabel(containerLabels, containerObject, containerLabelForSwarmStackIdentifier, resourceControls)
|
||||
containerObject = decorateResourceWithAccessControlFromLabel(containerLabels, containerObject, containerLabelForComposeStackIdentifier, resourceControls)
|
||||
|
||||
decoratedContainerData = append(decoratedContainerData, containerObject)
|
||||
}
|
||||
|
@ -143,11 +150,14 @@ func filterContainerList(containerData []interface{}, context *restrictedOperati
|
|||
containerObject, access := applyResourceAccessControl(containerObject, containerID, context)
|
||||
if access {
|
||||
containerLabels := extractContainerLabelsFromContainerListObject(containerObject)
|
||||
containerObject, access = applyResourceAccessControlFromLabel(containerLabels, containerObject, containerLabelForServiceIdentifier, context)
|
||||
containerObject, access = applyResourceAccessControlFromLabel(containerLabels, containerObject, containerLabelForComposeStackIdentifier, context)
|
||||
if access {
|
||||
containerObject, access = applyResourceAccessControlFromLabel(containerLabels, containerObject, containerLabelForStackIdentifier, context)
|
||||
containerObject, access = applyResourceAccessControlFromLabel(containerLabels, containerObject, containerLabelForServiceIdentifier, context)
|
||||
if access {
|
||||
filteredContainerData = append(filteredContainerData, containerObject)
|
||||
containerObject, access = applyResourceAccessControlFromLabel(containerLabels, containerObject, containerLabelForSwarmStackIdentifier, context)
|
||||
if access {
|
||||
filteredContainerData = append(filteredContainerData, containerObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package proxy
|
|||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
|
@ -303,6 +304,7 @@ func (p *proxyTransport) replaceRegistryAuthenticationHeader(request *http.Reque
|
|||
}
|
||||
|
||||
authenticationHeader := createRegistryAuthenticationHeader(originalHeaderData.Serveraddress, accessContext)
|
||||
log.Printf("Header: %+v", authenticationHeader)
|
||||
|
||||
headerData, err := json.Marshal(authenticationHeader)
|
||||
if err != nil {
|
||||
|
|
|
@ -99,7 +99,6 @@ func (manager *Manager) DeleteProxy(key string) {
|
|||
|
||||
// CreateAndRegisterExtensionProxy creates a new HTTP reverse proxy for an extension and adds it to the registered proxies.
|
||||
func (manager *Manager) CreateAndRegisterExtensionProxy(key, extensionAPIURL string) (http.Handler, error) {
|
||||
|
||||
extensionURL, err := url.Parse(extensionAPIURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -3,6 +3,7 @@ package proxy
|
|||
// unixSocketHandler represents a handler to proxy HTTP requests via a unix:// socket
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/portainer/http/error"
|
||||
|
@ -24,7 +25,7 @@ func (proxy *socketProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
if res != nil && res.StatusCode != 0 {
|
||||
code = res.StatusCode
|
||||
}
|
||||
httperror.WriteErrorResponse(w, err, code, nil)
|
||||
httperror.WriteError(w, code, "Unable to proxy the request via the Docker socket", err)
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
@ -38,6 +39,6 @@ func (proxy *socketProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(res.StatusCode)
|
||||
|
||||
if _, err := io.Copy(w, res.Body); err != nil {
|
||||
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, nil)
|
||||
log.Printf("proxy error: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue