From b292ddcd70c8d0b5a055122ff5ef8198703a3bdf Mon Sep 17 00:00:00 2001 From: Moritz Reich Date: Tue, 6 May 2025 10:54:53 +0200 Subject: [PATCH 1/4] removed btp-so endpoint --- internal/server/handlerBtpSO.go | 114 -------------------------------- internal/server/server.go | 1 - 2 files changed, 115 deletions(-) delete mode 100644 internal/server/handlerBtpSO.go diff --git a/internal/server/handlerBtpSO.go b/internal/server/handlerBtpSO.go deleted file mode 100644 index 64ee29f..0000000 --- a/internal/server/handlerBtpSO.go +++ /dev/null @@ -1,114 +0,0 @@ -package server - -import ( - "bytes" - "io" - "log/slog" - "net/http" - - "github.com/openmcp-project/ui-backend/internal/utils" - "github.com/openmcp-project/ui-backend/pkg/k8s" - "github.com/openmcp-project/ui-backend/pkg/openmcp" -) - -var ( - btpSOResources = []string{ - "/apis/services.cloud.sap.com/v1/servicebindings", - "/apis/services.cloud.sap.com/v1/serviceinstances", - //"/apis/services.cloud.sap.com/v1alpha1/servicebindings", - //"/apis/services.cloud.sap.com/v1alpha1/serviceinstances", - } -) - -func btpSOHandler(s *shared, req *http.Request, res *response) (*response, *HttpError) { - data, err := extractRequestData(req) - if err != nil { - return nil, NewBadRequestError("invalid request") - } - - DeleteMultiple(data.Headers, prohibitedRequestHeaders) - - crateKubeconfig, ok := utils.GetCrateKubeconfig() - if !ok { - slog.Error("failed to get crate kubeconfig") - return nil, NewInternalServerError("failed to get crate kubeconfig") - } - - var config k8s.KubeConfig - if data.ProjectName != "" && data.WorkspaceName != "" && data.McpName != "" { - config, err = openmcp.GetControlPlaneKubeconfig(s.crateKube, data.ProjectName, data.WorkspaceName, data.McpName, data.CrateAuthorization, crateKubeconfig) - if err != nil { - slog.Error("failed to get control plane api config", "err", err) - return nil, NewInternalServerError("failed to get control plane api config") - } - if data.McpAuthorization != "" { - config.SetUserToken(data.McpAuthorization) - } - } else { - slog.Error("either use %s: true or provide %s, %s and %s headers", useCrateClusterHeader, projectNameHeader, workspaceNameHeader, mcpName) - return nil, NewBadRequestError( - "either use %s: true or provide %s, %s and %s headers", - useCrateClusterHeader, - projectNameHeader, - workspaceNameHeader, - mcpName, - ) - } - - res.AddHeader("X-Response-From-Controlplane", "true") - - resBody := make([][]byte, 0) - headers := data.Headers - headers["Accept"] = []string{"application/json"} - for _, resource := range btpSOResources { - apiReq := k8s.Request{ - Method: data.Method, - Path: resource, - Headers: headers, - } - - k8sResp, err := s.downstreamKube.RequestApiServerRaw(apiReq, config) - if err != nil { - slog.Error("failed to make request to the api server", "err", err) - return nil, NewHttpError(http.StatusBadGateway, "failed to make request to the api server") - } - - defer func(Body io.ReadCloser) { - errC := Body.Close() - if errC != nil { - slog.Error("failed to close api server response body", "err", errC) - } - }(k8sResp.Body) - - data, err := io.ReadAll(k8sResp.Body) - if err != nil { - slog.Error("failed to read api server response body", "err", err) - return nil, NewInternalServerError("failed to read api server response body") - } - - resBody = append(resBody, data) - } - - var result = append([]byte("["), bytes.Join(resBody, []byte(","))[:]...) - result = append(result, []byte("]")[:]...) - - if data.JsonPath != "" { - result, err = ParseJsonPath(result, data.JsonPath) - if err != nil { - slog.Error("failed to parse json path", "err", err) - return nil, NewInternalServerError("failed to parse json path") - } - } else if data.JQ != "" { - resultString, err := ParseJQ(result, data.JQ) - if err != nil { - slog.Error("failed to parse jq", "err", err) - return nil, NewInternalServerError("failed to parse jq") - } - - result = []byte(resultString) - } - - res.body = result - - return res, nil -} diff --git a/internal/server/server.go b/internal/server/server.go index 2d971a7..4497722 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -15,7 +15,6 @@ func NewMiddleware(theCrateKube k8s.Kube, theDownstreamKube k8s.Kube) *http.Serv mux := http.NewServeMux() mux.HandleFunc("/.well-known/openmcp/kubeconfig", defaultHandler(shared, wellKnownKubeconfigHandler)) - mux.HandleFunc("/btp-so", defaultHandler(shared, btpSOHandler)) mux.HandleFunc("/managed", defaultHandler(shared, managedHandler)) mux.HandleFunc("/c/", defaultHandler(shared, categoryHandler)) mux.HandleFunc("/", defaultHandler(shared, mainHandler)) From afe9588f00a91ae08894f3263ea5a4076c84a918 Mon Sep 17 00:00:00 2001 From: Moritz Reich Date: Tue, 6 May 2025 10:55:08 +0200 Subject: [PATCH 2/4] delete json path option --- internal/server/handlerCategory.go | 8 +------- internal/server/handlerMain.go | 27 +-------------------------- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/internal/server/handlerCategory.go b/internal/server/handlerCategory.go index f13bcea..99f6a8a 100644 --- a/internal/server/handlerCategory.go +++ b/internal/server/handlerCategory.go @@ -107,13 +107,7 @@ func _categoryHandler(s *shared, req *http.Request, res *response) (*response, * var result []byte = append([]byte("["), bytes.Join(resultData, []byte(","))[:]...) result = append(result, []byte("]")[:]...) - if data.JsonPath != "" { - result, err = ParseJsonPath(result, data.JsonPath) - if err != nil { - slog.Error("failed to parse json path", "err", err) - return nil, NewInternalServerError("failed to parse json path") - } - } else if data.JQ != "" { + if data.JQ != "" { resultString, err := ParseJQ(result, data.JQ) if err != nil { slog.Error("failed to parse jq", "err", err) diff --git a/internal/server/handlerMain.go b/internal/server/handlerMain.go index 4961c40..24a191b 100644 --- a/internal/server/handlerMain.go +++ b/internal/server/handlerMain.go @@ -25,7 +25,6 @@ const ( contextHeader = "X-context" useCrateClusterHeader = "X-use-crate" authorizationHeader = "Authorization" - jsonPathHeader = "X-jsonpath" jqHeader = "X-jq" categoryHeader = "X-category" ) @@ -40,7 +39,6 @@ var prohibitedRequestHeaders = []string{ mcpAuthHeader, contextHeader, authorizationHeader, - jsonPathHeader, "User-Agent", "Host", } @@ -61,7 +59,6 @@ type ExtractedRequestData struct { UseCrateCluster bool CrateAuthorization string Headers map[string][]string - JsonPath string JQ string Category string } @@ -128,16 +125,11 @@ func mainHandler(s *shared, req *http.Request, res *response) (*response, *HttpE } }(k8sResp.Body) - if (data.JsonPath == "" && data.JQ == "") || k8sResp.StatusCode >= 400 { + if (data.JQ == "") || k8sResp.StatusCode >= 400 { err = CopyResponse(res, k8sResp, nil, nil) if err != nil { return nil, NewInternalServerError("failed to copy response: %v", err) } - } else if data.JsonPath != "" { - err := res.buildJsonPathResponse(k8sResp, err, data) - if err != nil { - return nil, NewInternalServerError("failed to build jsonpath response: %v", err) - } } else { err := res.buildJqResponse(k8sResp, data) if err != nil { @@ -163,7 +155,6 @@ func extractRequestData(r *http.Request) (ExtractedRequestData, error) { McpAuthorization: r.Header.Get(mcpAuthHeader), McpName: r.Header.Get(mcpName), CrateAuthorization: r.Header.Get(authorizationHeader), - JsonPath: r.Header.Get(jsonPathHeader), JQ: r.Header.Get(jqHeader), Category: r.Header.Get(categoryHeader), } @@ -202,19 +193,3 @@ func (r *response) buildJqResponse(k8sResp *http.Response, data ExtractedRequest r.contentType = "application/json" return err } - -func (r *response) buildJsonPathResponse(k8sResp *http.Response, err error, data ExtractedRequestData) error { - body, errR := io.ReadAll(k8sResp.Body) - if errR != nil { - return errors.Join(errors.New("failed to read api server response"), err) - } - - parsedJson, err := ParseJsonPath(body, data.JsonPath) - if err != nil { - return errors.Join(errors.New("failed to parse response with jsonpath"), err) - } - - err = CopyResponse(r, k8sResp, parsedJson, prohibitedResponseHeaders) - r.contentType = "application/json" - return err -} From 535961b99f0e9acf89d1645008f02ab53a361ffa Mon Sep 17 00:00:00 2001 From: Moritz Reich Date: Tue, 6 May 2025 11:04:10 +0200 Subject: [PATCH 3/4] removed kubeconfig endpoint --- internal/server/handlerWellKnownKubeconfig.go | 31 ------------------- internal/server/server.go | 1 - 2 files changed, 32 deletions(-) delete mode 100644 internal/server/handlerWellKnownKubeconfig.go diff --git a/internal/server/handlerWellKnownKubeconfig.go b/internal/server/handlerWellKnownKubeconfig.go deleted file mode 100644 index b0b682f..0000000 --- a/internal/server/handlerWellKnownKubeconfig.go +++ /dev/null @@ -1,31 +0,0 @@ -package server - -import ( - "log/slog" - "net/http" - - "github.com/openmcp-project/ui-backend/internal/utils" - "gopkg.in/yaml.v3" -) - -func wellKnownKubeconfigHandler(_ *shared, _ *http.Request, res *response) (*response, *HttpError) { - crateKubeconfig, ok := utils.GetCrateKubeconfig() - if !ok { - slog.Error("failed to get crate kubeconfig") - return nil, NewInternalServerError("failed to get crate kubeconfig") - } - - // Remove the token from the kubeconfig. - // just to be sure. - crateKubeconfig.SetUserToken("") - - content, err := yaml.Marshal(crateKubeconfig) - if err != nil { - slog.Error("failed to marshal kubeconfig", "err", err) - return nil, NewInternalServerError("failed to marshal kubeconfig") - } - res.body = content - res.contentType = "application/yaml" - - return res, nil -} diff --git a/internal/server/server.go b/internal/server/server.go index 4497722..d3b7c50 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -14,7 +14,6 @@ func NewMiddleware(theCrateKube k8s.Kube, theDownstreamKube k8s.Kube) *http.Serv mux := http.NewServeMux() - mux.HandleFunc("/.well-known/openmcp/kubeconfig", defaultHandler(shared, wellKnownKubeconfigHandler)) mux.HandleFunc("/managed", defaultHandler(shared, managedHandler)) mux.HandleFunc("/c/", defaultHandler(shared, categoryHandler)) mux.HandleFunc("/", defaultHandler(shared, mainHandler)) From 44112109c4330a3e4da4461d2b83a654ccd472c8 Mon Sep 17 00:00:00 2001 From: Moritz Reich Date: Tue, 6 May 2025 11:50:41 +0200 Subject: [PATCH 4/4] fix!: removed second authorization header for MCP and merged it into the default Authorization --- internal/server/handlerCategory.go | 6 +++--- internal/server/handlerMain.go | 18 +++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/internal/server/handlerCategory.go b/internal/server/handlerCategory.go index 99f6a8a..9d0ee88 100644 --- a/internal/server/handlerCategory.go +++ b/internal/server/handlerCategory.go @@ -46,13 +46,13 @@ func _categoryHandler(s *shared, req *http.Request, res *response) (*response, * var config k8s.KubeConfig if data.ProjectName != "" && data.WorkspaceName != "" && data.McpName != "" { - config, err = openmcp.GetControlPlaneKubeconfig(s.crateKube, data.ProjectName, data.WorkspaceName, data.McpName, data.CrateAuthorization, crateKubeconfig) + config, err = openmcp.GetControlPlaneKubeconfig(s.crateKube, data.ProjectName, data.WorkspaceName, data.McpName, data.Authorization, crateKubeconfig) if err != nil { slog.Error("failed to get control plane api config", "err", err) return nil, NewInternalServerError("failed to get control plane api config") } - if data.McpAuthorization != "" { - config.SetUserToken(data.McpAuthorization) + if data.Authorization != "" { + config.SetUserToken(data.Authorization) } } else { slog.Error("either use %s: true or provide %s, %s and %s headers", useCrateClusterHeader, projectNameHeader, workspaceNameHeader, mcpName) diff --git a/internal/server/handlerMain.go b/internal/server/handlerMain.go index 24a191b..675b7be 100644 --- a/internal/server/handlerMain.go +++ b/internal/server/handlerMain.go @@ -21,7 +21,6 @@ const ( projectNameHeader = "X-project" workspaceNameHeader = "X-workspace" mcpName = "X-mcp" - mcpAuthHeader = "X-mcp-authorization" contextHeader = "X-context" useCrateClusterHeader = "X-use-crate" authorizationHeader = "Authorization" @@ -36,7 +35,6 @@ var prohibitedRequestHeaders = []string{ projectNameHeader, workspaceNameHeader, mcpName, - mcpAuthHeader, contextHeader, authorizationHeader, "User-Agent", @@ -54,10 +52,9 @@ type ExtractedRequestData struct { ProjectName string WorkspaceName string McpName string - McpAuthorization string ContextName string UseCrateCluster bool - CrateAuthorization string + Authorization string Headers map[string][]string JQ string Category string @@ -90,15 +87,15 @@ func mainHandler(s *shared, req *http.Request, res *response) (*response, *HttpE var config k8s.KubeConfig if data.UseCrateCluster { config = crateKubeconfig - config.SetUserToken(data.CrateAuthorization) + config.SetUserToken(data.Authorization) } else if data.ProjectName != "" && data.WorkspaceName != "" && data.McpName != "" { - config, err = openmcp.GetControlPlaneKubeconfig(s.crateKube, data.ProjectName, data.WorkspaceName, data.McpName, data.CrateAuthorization, crateKubeconfig) + config, err = openmcp.GetControlPlaneKubeconfig(s.crateKube, data.ProjectName, data.WorkspaceName, data.McpName, data.Authorization, crateKubeconfig) if err != nil { slog.Error("failed to get control plane api config", "err", err) return nil, NewInternalServerError("failed to get control plane api config") } - if data.McpAuthorization != "" { - config.SetUserToken(data.McpAuthorization) + if data.Authorization != "" { + config.SetUserToken(data.Authorization) } } else { slog.Error("either use %s: true or provide %s, %s and %s headers", useCrateClusterHeader, projectNameHeader, workspaceNameHeader, mcpName) @@ -152,9 +149,8 @@ func extractRequestData(r *http.Request) (ExtractedRequestData, error) { ProjectName: r.Header.Get(projectNameHeader), WorkspaceName: r.Header.Get(workspaceNameHeader), ContextName: r.Header.Get(contextHeader), - McpAuthorization: r.Header.Get(mcpAuthHeader), McpName: r.Header.Get(mcpName), - CrateAuthorization: r.Header.Get(authorizationHeader), + Authorization: r.Header.Get(authorizationHeader), JQ: r.Header.Get(jqHeader), Category: r.Header.Get(categoryHeader), } @@ -170,7 +166,7 @@ func extractRequestData(r *http.Request) (ExtractedRequestData, error) { rd.UseCrateCluster = useCrateCluster } - if rd.CrateAuthorization == "" { + if rd.Authorization == "" { return ExtractedRequestData{}, fmt.Errorf("%s header is required", authorizationHeader) }