diff --git a/api/http/proxy/factory/kubernetes/secrets.go b/api/http/proxy/factory/kubernetes/secrets.go deleted file mode 100644 index dc03007d9..000000000 --- a/api/http/proxy/factory/kubernetes/secrets.go +++ /dev/null @@ -1,170 +0,0 @@ -package kubernetes - -import ( - "net/http" - "path" - - "github.com/portainer/portainer/api/http/proxy/factory/utils" - "github.com/portainer/portainer/api/http/security" - "github.com/portainer/portainer/api/kubernetes/privateregistries" - v1 "k8s.io/api/core/v1" -) - -func (transport *baseTransport) proxySecretRequest(request *http.Request, namespace, requestPath string) (*http.Response, error) { - switch request.Method { - case "POST": - return transport.proxySecretCreationOperation(request) - case "GET": - if path.Base(requestPath) == "secrets" { - return transport.proxySecretListOperation(request) - } - return transport.proxySecretInspectOperation(request) - case "PUT": - return transport.proxySecretUpdateOperation(request) - case "DELETE": - return transport.proxySecretDeleteOperation(request, namespace) - default: - return transport.executeKubernetesRequest(request) - } -} - -func (transport *baseTransport) proxySecretCreationOperation(request *http.Request) (*http.Response, error) { - body, err := utils.GetRequestAsMap(request) - if err != nil { - return nil, err - } - - if isSecretRepresentPrivateRegistry(body) { - return utils.WriteAccessDeniedResponse() - } - - err = utils.RewriteRequest(request, body) - if err != nil { - return nil, err - } - - return transport.executeKubernetesRequest(request) -} - -func (transport *baseTransport) proxySecretListOperation(request *http.Request) (*http.Response, error) { - response, err := transport.executeKubernetesRequest(request) - if err != nil { - return nil, err - } - - isAdmin, err := security.IsAdmin(request) - if err != nil { - return nil, err - } - - if isAdmin { - return response, nil - } - - body, err := utils.GetResponseAsJSONObject(response) - if err != nil { - return nil, err - } - - items := utils.GetArrayObject(body, "items") - - if items == nil { - utils.RewriteResponse(response, body, response.StatusCode) - return response, nil - } - - filteredItems := []interface{}{} - for _, item := range items { - itemObj := item.(map[string]interface{}) - if !isSecretRepresentPrivateRegistry(itemObj) { - filteredItems = append(filteredItems, item) - } - } - - body["items"] = filteredItems - - utils.RewriteResponse(response, body, response.StatusCode) - return response, nil -} - -func (transport *baseTransport) proxySecretInspectOperation(request *http.Request) (*http.Response, error) { - response, err := transport.executeKubernetesRequest(request) - if err != nil { - return nil, err - } - - isAdmin, err := security.IsAdmin(request) - if err != nil { - return nil, err - } - - if isAdmin { - return response, nil - } - - body, err := utils.GetResponseAsJSONObject(response) - if err != nil { - return nil, err - } - - if isSecretRepresentPrivateRegistry(body) { - return utils.WriteAccessDeniedResponse() - } - - err = utils.RewriteResponse(response, body, response.StatusCode) - if err != nil { - return nil, err - } - - return response, nil -} - -func (transport *baseTransport) proxySecretUpdateOperation(request *http.Request) (*http.Response, error) { - body, err := utils.GetRequestAsMap(request) - if err != nil { - return nil, err - } - - if isSecretRepresentPrivateRegistry(body) { - return utils.WriteAccessDeniedResponse() - } - - err = utils.RewriteRequest(request, body) - if err != nil { - return nil, err - } - - return transport.executeKubernetesRequest(request) -} - -func (transport *baseTransport) proxySecretDeleteOperation(request *http.Request, namespace string) (*http.Response, error) { - kcl, err := transport.k8sClientFactory.GetKubeClient(transport.endpoint) - if err != nil { - return nil, err - } - - secretName := path.Base(request.RequestURI) - - isRegistry, err := kcl.IsRegistrySecret(namespace, secretName) - if err != nil { - return nil, err - } - - if isRegistry { - return utils.WriteAccessDeniedResponse() - } - - return transport.executeKubernetesRequest(request) -} - -func isSecretRepresentPrivateRegistry(secret map[string]interface{}) bool { - if secret["type"] == nil || secret["type"].(string) != string(v1.SecretTypeDockerConfigJson) { - return false - } - - metadata := utils.GetJSONObject(secret, "metadata") - annotations := utils.GetJSONObject(metadata, "annotations") - _, ok := annotations[privateregistries.RegistryIDLabel] - - return ok -} diff --git a/api/http/proxy/factory/kubernetes/transport.go b/api/http/proxy/factory/kubernetes/transport.go index ae7036698..ffb836fc7 100644 --- a/api/http/proxy/factory/kubernetes/transport.go +++ b/api/http/proxy/factory/kubernetes/transport.go @@ -66,8 +66,6 @@ func (transport *baseTransport) proxyNamespacedRequest(request *http.Request, fu } switch { - case strings.HasPrefix(requestPath, "secrets"): - return transport.proxySecretRequest(request, namespace, requestPath) case requestPath == "" && request.Method == "DELETE": return transport.proxyNamespaceDeleteOperation(request, namespace) default: @@ -79,6 +77,18 @@ func (transport *baseTransport) executeKubernetesRequest(request *http.Request) resp, err := transport.httpTransport.RoundTrip(request) + // This fix was made to resolve a k8s e2e test, more detailed investigation should be done later. + if err == nil && resp.StatusCode == http.StatusMovedPermanently { + oldLocation := resp.Header.Get("Location") + if oldLocation != "" { + stripedPrefix := strings.TrimSuffix(request.RequestURI, request.URL.Path) + // local proxy strips "/kubernetes" but agent proxy and edge agent proxy do not + stripedPrefix = strings.TrimSuffix(stripedPrefix, "/kubernetes") + newLocation := stripedPrefix + "/kubernetes" + oldLocation + resp.Header.Set("Location", newLocation) + } + } + return resp, err }