mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
feat(registry) EE-806 add support for AWS ECR (#6165)
* feat(ecr) EE-806 add support for aws ecr * feat(ecr) EE-806 fix wrong doc for Ecr Region Co-authored-by: Simon Meng <simon.meng@portainer.io>
This commit is contained in:
parent
ff6185cc81
commit
a86c7046df
29 changed files with 694 additions and 51 deletions
|
@ -3,6 +3,7 @@ package docker
|
|||
import (
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/registryutils"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -25,13 +26,13 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func createRegistryAuthenticationHeader(registryId portainer.RegistryID, accessContext *registryAccessContext) *registryAuthenticationHeader {
|
||||
var authenticationHeader *registryAuthenticationHeader
|
||||
|
||||
func createRegistryAuthenticationHeader(
|
||||
dataStore portainer.DataStore,
|
||||
registryId portainer.RegistryID,
|
||||
accessContext *registryAccessContext,
|
||||
) (authenticationHeader registryAuthenticationHeader, err error) {
|
||||
if registryId == 0 { // dockerhub (anonymous)
|
||||
authenticationHeader = ®istryAuthenticationHeader{
|
||||
Serveraddress: "docker.io",
|
||||
}
|
||||
authenticationHeader.Serveraddress = "docker.io"
|
||||
} else { // any "custom" registry
|
||||
var matchingRegistry *portainer.Registry
|
||||
for _, registry := range accessContext.registries {
|
||||
|
@ -44,13 +45,14 @@ func createRegistryAuthenticationHeader(registryId portainer.RegistryID, accessC
|
|||
}
|
||||
|
||||
if matchingRegistry != nil {
|
||||
authenticationHeader = ®istryAuthenticationHeader{
|
||||
Username: matchingRegistry.Username,
|
||||
Password: matchingRegistry.Password,
|
||||
Serveraddress: matchingRegistry.URL,
|
||||
err = registryutils.EnsureRegTokenValid(dataStore, matchingRegistry)
|
||||
if (err != nil) {
|
||||
return
|
||||
}
|
||||
authenticationHeader.Serveraddress = matchingRegistry.URL
|
||||
authenticationHeader.Username, authenticationHeader.Password, err = registryutils.GetRegEffectiveCredential(matchingRegistry)
|
||||
}
|
||||
}
|
||||
|
||||
return authenticationHeader
|
||||
return
|
||||
}
|
||||
|
|
|
@ -414,7 +414,10 @@ func (transport *Transport) replaceRegistryAuthenticationHeader(request *http.Re
|
|||
return nil, err
|
||||
}
|
||||
|
||||
authenticationHeader := createRegistryAuthenticationHeader(originalHeaderData.RegistryId, accessContext)
|
||||
authenticationHeader, err := createRegistryAuthenticationHeader(transport.dataStore, originalHeaderData.RegistryId, accessContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headerData, err := json.Marshal(authenticationHeader)
|
||||
if err != nil {
|
||||
|
|
15
api/http/proxy/factory/kubernetes/deployments.go
Normal file
15
api/http/proxy/factory/kubernetes/deployments.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (transport *baseTransport) proxyDeploymentsRequest(request *http.Request, namespace, requestPath string) (*http.Response, error) {
|
||||
switch request.Method {
|
||||
case http.MethodPost, http.MethodPatch:
|
||||
transport.refreshRegistry(request, namespace)
|
||||
return transport.executeKubernetesRequest(request)
|
||||
default:
|
||||
return transport.executeKubernetesRequest(request)
|
||||
}
|
||||
}
|
15
api/http/proxy/factory/kubernetes/pods.go
Normal file
15
api/http/proxy/factory/kubernetes/pods.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (transport *baseTransport) proxyPodsRequest(request *http.Request, namespace, requestPath string) (*http.Response, error) {
|
||||
switch request.Method {
|
||||
case "DELETE":
|
||||
transport.refreshRegistry(request, namespace)
|
||||
return transport.executeKubernetesRequest(request)
|
||||
default:
|
||||
return transport.executeKubernetesRequest(request)
|
||||
}
|
||||
}
|
17
api/http/proxy/factory/kubernetes/refresh_registry.go
Normal file
17
api/http/proxy/factory/kubernetes/refresh_registry.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"github.com/portainer/portainer/api/internal/registryutils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (transport *baseTransport) refreshRegistry(request *http.Request, namespace string) (err error) {
|
||||
cli, err := transport.k8sClientFactory.GetKubeClient(transport.endpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = registryutils.RefreshEcrSecret(cli, transport.endpoint, transport.dataStore, namespace)
|
||||
|
||||
return
|
||||
}
|
|
@ -42,7 +42,10 @@ func newBaseTransport(httpTransport *http.Transport, tokenManager *tokenManager,
|
|||
// proxyKubernetesRequest intercepts a Kubernetes API request and apply logic based
|
||||
// on the requested operation.
|
||||
func (transport *baseTransport) proxyKubernetesRequest(request *http.Request) (*http.Response, error) {
|
||||
apiVersionRe := regexp.MustCompile(`^(/kubernetes)?/api/v[0-9](\.[0-9])?`)
|
||||
// URL path examples:
|
||||
// http://localhost:9000/api/endpoints/3/kubernetes/api/v1/namespaces
|
||||
// http://localhost:9000/api/endpoints/3/kubernetes/apis/apps/v1/namespaces/default/deployments
|
||||
apiVersionRe := regexp.MustCompile(`^(/kubernetes)?/(api|apis/apps)/v[0-9](\.[0-9])?`)
|
||||
requestPath := apiVersionRe.ReplaceAllString(request.URL.Path, "")
|
||||
|
||||
switch {
|
||||
|
@ -66,6 +69,10 @@ func (transport *baseTransport) proxyNamespacedRequest(request *http.Request, fu
|
|||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(requestPath, "pods"):
|
||||
return transport.proxyPodsRequest(request, namespace, requestPath)
|
||||
case strings.HasPrefix(requestPath, "deployments"):
|
||||
return transport.proxyDeploymentsRequest(request, namespace, requestPath)
|
||||
case requestPath == "" && request.Method == "DELETE":
|
||||
return transport.proxyNamespaceDeleteOperation(request, namespace)
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue