From 69d2b4ba58b5a2b13ba8e695bf89d7fb0d13f6e2 Mon Sep 17 00:00:00 2001 From: Gonzalo Reyero Ferreras <87083379+greyerof@users.noreply.github.com> Date: Thu, 16 Nov 2023 07:30:12 +0100 Subject: [PATCH] Fix for the webserver kubeconfig file handling. (#1625) The kubeconfig sent via web form is now copied to a temporary file. Also, I created a new function in the clientsholder package to recreate the oc clients for each webserver run, using the kubceonfig file sent via web form. --- cnf-certification-test/webserver/webserver.go | 33 +++++++++++++------ internal/clientsholder/clientsholder.go | 9 +++++ main.go | 3 +- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/cnf-certification-test/webserver/webserver.go b/cnf-certification-test/webserver/webserver.go index d7e32ef3eb..591b478e1d 100644 --- a/cnf-certification-test/webserver/webserver.go +++ b/cnf-certification-test/webserver/webserver.go @@ -18,6 +18,7 @@ import ( "github.com/gorilla/websocket" "github.com/robert-nix/ansihtml" "github.com/sirupsen/logrus" + "github.com/test-network-function/cnf-certification-test/internal/clientsholder" "github.com/test-network-function/cnf-certification-test/pkg/certsuite" "github.com/test-network-function/cnf-certification-test/pkg/provider" ) @@ -201,25 +202,33 @@ func runHandler(w http.ResponseWriter, r *http.Request) { } defer file.Close() - // Create a new file on the server to store the uploaded content - uploadedFile, err := os.Create(fileHeader.Filename) + logrus.Infof("Kubeconfig file name received: %s", fileHeader.Filename) + kubeconfigTempFile, err := os.CreateTemp("", "webserver-kubeconfig-*") if err != nil { - http.Error(w, "Unable to create file for writing", http.StatusInternalServerError) + http.Error(w, "Failed to create temp file to store the kubeconfig content.", http.StatusBadRequest) return } - defer uploadedFile.Close() - // Copy the uploaded file's content to the new file - _, err = io.Copy(uploadedFile, file) + defer func() { + logrus.Infof("Removing temporary kubeconfig file %s", kubeconfigTempFile.Name()) + err = os.Remove(kubeconfigTempFile.Name()) + if err != nil { + logrus.Errorf("Failed to remove temp kubeconfig file %s", kubeconfigTempFile.Name()) + } + }() + + _, err = io.Copy(kubeconfigTempFile, file) if err != nil { http.Error(w, "Unable to copy file", http.StatusInternalServerError) return } - // Copy the uploaded file to the server file - os.Setenv("KUBECONFIG", fileHeader.Filename) - logrus.Infof("Web Server KUBECONFIG : %v", fileHeader.Filename) - logrus.Infof("Web Server Labels filter : %v", flattenedOptions) + _ = kubeconfigTempFile.Close() + + logrus.Infof("Web Server kubeconfig file : %v (copied into %v)", fileHeader.Filename, kubeconfigTempFile.Name()) + logrus.Infof("Web Server Labels filter : %v", flattenedOptions) + + _ = clientsholder.GetNewClientsHolder(kubeconfigTempFile.Name()) var env provider.TestEnvironment env.SetNeedsRefresh() @@ -240,14 +249,18 @@ func runHandler(w http.ResponseWriter, r *http.Request) { // Serialize the response data to JSON jsonResponse, err := json.Marshal(response) if err != nil { + logrus.Errorf("Failed to marshal jsonResponse: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } + // Set the Content-Type header to specify that the response is JSON w.Header().Set("Content-Type", "application/json") // Write the JSON response to the client + logrus.Infof("Sending web response: %v", response) _, err = w.Write(jsonResponse) if err != nil { + logrus.Errorf("Failed to write jsonResponse: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } diff --git a/internal/clientsholder/clientsholder.go b/internal/clientsholder/clientsholder.go index 7992d6e675..0aee59c605 100644 --- a/internal/clientsholder/clientsholder.go +++ b/internal/clientsholder/clientsholder.go @@ -157,6 +157,15 @@ func GetClientsHolder(filenames ...string) *ClientsHolder { return clientsHolder } +func GetNewClientsHolder(kubeconfigFile string) *ClientsHolder { + _, err := newClientsHolder(kubeconfigFile) + if err != nil { + logrus.Panic("Failed to create k8s clients holder: ", err) + } + + return &clientsHolder +} + func createByteArrayKubeConfig(kubeConfig *clientcmdapi.Config) ([]byte, error) { yamlBytes, err := clientcmd.Write(*kubeConfig) if err != nil { diff --git a/main.go b/main.go index 8cf245bb10..6411ce4207 100644 --- a/main.go +++ b/main.go @@ -155,14 +155,13 @@ func main() { } // Set clientsholder singleton with the filenames from the env vars. - _ = clientsholder.GetClientsHolder(getK8sClientsConfigFileNames()...) - log.Infof("Output folder for the claim file: %s", *claimPath) if *serverModeFlag { log.Info("Running CNF Certification Suite in web server mode.") webserver.StartServer(*claimPath) } else { log.Info("Running CNF Certification Suite in stand-alone mode.") + _ = clientsholder.GetClientsHolder(getK8sClientsConfigFileNames()...) certsuite.Run(*labelsFlag, *claimPath, timeout) } }