1
0
Fork 0
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:
cong meng 2021-12-01 13:18:57 +13:00 committed by GitHub
parent ff6185cc81
commit a86c7046df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 694 additions and 51 deletions

View file

@ -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 = &registryAuthenticationHeader{
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 = &registryAuthenticationHeader{
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
}

View file

@ -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 {

View 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)
}
}

View 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)
}
}

View 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
}

View file

@ -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: