From 0d1f8e3f09fbaa07c4cb0018dd9e21ec1776fc57 Mon Sep 17 00:00:00 2001 From: Claudio Netto Date: Tue, 26 Jul 2022 17:58:04 -0300 Subject: [PATCH] feat(web): accept certificates urleconded too --- go.mod | 2 +- internal/pkg/rpaas/errors.go | 27 +++++- internal/pkg/rpaas/k8s.go | 9 +- internal/purge/cache.go | 3 +- pkg/web/autoscale_test.go | 15 ++-- pkg/web/certificate.go | 46 +++++++--- pkg/web/certificate_test.go | 167 ++++++++++++++++++++--------------- pkg/web/errors.go | 52 ++++++----- pkg/web/extra_files_test.go | 2 +- pkg/web/handlers.go | 18 ---- 10 files changed, 193 insertions(+), 148 deletions(-) diff --git a/go.mod b/go.mod index f9d70d4de..4704174df 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( github.com/olekukonko/tablewriter v0.0.5 github.com/opentracing-contrib/go-stdlib v1.0.0 github.com/opentracing/opentracing-go v1.2.0 - github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.1 github.com/sirupsen/logrus v1.8.1 github.com/spf13/pflag v1.0.5 @@ -107,6 +106,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect diff --git a/internal/pkg/rpaas/errors.go b/internal/pkg/rpaas/errors.go index 3c9663a22..ee9877108 100644 --- a/internal/pkg/rpaas/errors.go +++ b/internal/pkg/rpaas/errors.go @@ -5,7 +5,8 @@ package rpaas import ( - "github.com/pkg/errors" + "errors" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" ) @@ -14,38 +15,56 @@ var ( ) type ValidationError struct { - Msg string + Msg string `json:"message"` + Internal error `json:"-"` } func (ValidationError) IsValidation() bool { return true } + func (e ValidationError) Error() string { return e.Msg } +func (e ValidationError) Unwrap() error { + return e.Internal +} + type ConflictError struct { - Msg string + Msg string `json:"message"` + Internal error `json:"-"` } func (ConflictError) IsConflict() bool { return true } + func (e ConflictError) Error() string { return e.Msg } +func (e ConflictError) Unwrap() error { + return e.Internal +} + type NotFoundError struct { - Msg string + Msg string `json:"message"` + Internal error `json:"-"` } func (NotFoundError) IsNotFound() bool { return true } + func (e NotFoundError) Error() string { return e.Msg } +func (e NotFoundError) Unwrap() error { + return e.Internal +} + func IsValidationError(err error) bool { if vErr, ok := err.(interface { IsValidation() bool diff --git a/internal/pkg/rpaas/k8s.go b/internal/pkg/rpaas/k8s.go index 776848827..ddda5c069 100644 --- a/internal/pkg/rpaas/k8s.go +++ b/internal/pkg/rpaas/k8s.go @@ -14,6 +14,7 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "errors" "fmt" "net" "net/url" @@ -26,7 +27,6 @@ import ( "github.com/cert-manager/cert-manager/pkg/util/pki" jsonpatch "github.com/evanphx/json-patch/v5" "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "github.com/sirupsen/logrus" nginxv1alpha1 "github.com/tsuru/nginx-operator/api/v1alpha1" nginxk8s "github.com/tsuru/nginx-operator/pkg/k8s" @@ -1005,7 +1005,7 @@ func (m *k8sRpaasManager) PurgeCache(ctx context.Context, instanceName string, a } status, err = m.cacheManager.PurgeCache(podStatus.Address, args.Path, port, args.PreservePath, args.ExtraHeaders) if err != nil { - purgeErrors = multierror.Append(purgeErrors, errors.Wrapf(err, "pod %s failed", podStatus.Address)) + purgeErrors = multierror.Append(purgeErrors, fmt.Errorf("pod %s failed: %w", podStatus.Address, err)) continue } if status { @@ -1727,14 +1727,13 @@ func (m *k8sRpaasManager) GetInstanceInfo(ctx context.Context, instanceName stri if dashboardTemplate != "" { tpl, tplErr := template.New("dashboard").Parse(dashboardTemplate) if tplErr != nil { - return nil, errors.Wrap(tplErr, "could not parse dashboard template") + return nil, fmt.Errorf("could not parse dashboard template: %w", tplErr) } var buf bytes.Buffer tplErr = tpl.Execute(&buf, info) - if tplErr != nil { - return nil, errors.Wrap(tplErr, "could not execute dashboard template") + return nil, fmt.Errorf("could not execute dashboard template: %w", tplErr) } info.Dashboard = strings.TrimSpace(buf.String()) } diff --git a/internal/purge/cache.go b/internal/purge/cache.go index 74a7c13a9..9e5c885cf 100644 --- a/internal/purge/cache.go +++ b/internal/purge/cache.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/go-multierror" "github.com/labstack/echo/v4" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/tsuru/rpaas-operator/internal/pkg/rpaas" @@ -90,7 +89,7 @@ func (p *PurgeAPI) PurgeCache(ctx context.Context, name string, args rpaas.Purge continue } if status, err = p.cacheManager.PurgeCache(pod.Address, args.Path, port, args.PreservePath, args.ExtraHeaders); err != nil { - purgeErrors = multierror.Append(purgeErrors, errors.Wrapf(err, "pod %s:%d failed", pod.Address, port)) + purgeErrors = multierror.Append(purgeErrors, fmt.Errorf("pod %s:%d failed: %w", pod.Address, port, err)) continue } if status { diff --git a/pkg/web/autoscale_test.go b/pkg/web/autoscale_test.go index cb7510dab..0e103f01d 100644 --- a/pkg/web/autoscale_test.go +++ b/pkg/web/autoscale_test.go @@ -34,7 +34,7 @@ func Test_getAutoscale(t *testing.T) { name: "when instance does not exists", instance: "invalid-instance", expectedCode: http.StatusNotFound, - expectedBody: `{"Msg":"rpaas instance \\"invalid-instance\\" not found"}`, + expectedBody: `{"message":"rpaas instance \\"invalid-instance\\" not found"}`, manager: &fake.RpaasManager{ FakeGetAutoscale: func(instance string) (*clientTypes.Autoscale, error) { assert.Equal(t, "invalid-instance", instance) @@ -103,7 +103,7 @@ func Test_createAutoscale(t *testing.T) { instance: "invalid-instance", requestBody: "max=10", expectedCode: http.StatusNotFound, - expectedBody: `{"Msg":"rpaas instance \\"invalid-instance\\" not found"}`, + expectedBody: `{"message":"rpaas instance \\"invalid-instance\\" not found"}`, manager: &fake.RpaasManager{ FakeCreateAutoscale: func(instance string, autoscale *clientTypes.Autoscale) error { assert.Equal(t, "invalid-instance", instance) @@ -117,7 +117,7 @@ func Test_createAutoscale(t *testing.T) { instance: "my-instance", requestBody: "min=10", expectedCode: http.StatusBadRequest, - expectedBody: `{"Msg":"max replicas is required"}`, + expectedBody: `{"message":"max replicas is required"}`, manager: &fake.RpaasManager{ FakeCreateAutoscale: func(instance string, autoscale *clientTypes.Autoscale) error { assert.Equal(t, "my-instance", instance) @@ -131,7 +131,6 @@ func Test_createAutoscale(t *testing.T) { instance: "my-instance", requestBody: "max=10&min=3&cpu=60&memory=512", expectedCode: http.StatusOK, - expectedBody: ``, manager: &fake.RpaasManager{ FakeCreateAutoscale: func(instance string, autoscale *clientTypes.Autoscale) error { assert.Equal(t, "my-instance", instance) @@ -178,7 +177,7 @@ func Test_updateAutoscale(t *testing.T) { instance: "invalid-instance", requestBody: "max=10", expectedCode: http.StatusNotFound, - expectedBody: `{"Msg":"rpaas instance \\"invalid-instance\\" not found"}`, + expectedBody: `{"message":"rpaas instance \\"invalid-instance\\" not found"}`, manager: &fake.RpaasManager{ FakeGetAutoscale: func(instance string) (*clientTypes.Autoscale, error) { assert.Equal(t, "invalid-instance", instance) @@ -195,7 +194,7 @@ func Test_updateAutoscale(t *testing.T) { instance: "my-instance", requestBody: "min=10", expectedCode: http.StatusBadRequest, - expectedBody: `{"Msg":"max replicas is required"}`, + expectedBody: `{"message":"max replicas is required"}`, manager: &fake.RpaasManager{ FakeGetAutoscale: func(instance string) (*clientTypes.Autoscale, error) { assert.Equal(t, "my-instance", instance) @@ -213,7 +212,6 @@ func Test_updateAutoscale(t *testing.T) { instance: "my-instance", requestBody: "min=5&memory=512", expectedCode: http.StatusCreated, - expectedBody: ``, manager: &fake.RpaasManager{ FakeGetAutoscale: func(instance string) (*clientTypes.Autoscale, error) { assert.Equal(t, "my-instance", instance) @@ -268,7 +266,7 @@ func Test_deleteAutoscale(t *testing.T) { name: "when instance does not exists", instance: "invalid-instance", expectedCode: http.StatusNotFound, - expectedBody: `{"Msg":"rpaas instance \\"invalid-instance\\" not found"}`, + expectedBody: `{"message":"rpaas instance \\"invalid-instance\\" not found"}`, manager: &fake.RpaasManager{ FakeDeleteAutoscale: func(instance string) error { assert.Equal(t, "invalid-instance", instance) @@ -280,7 +278,6 @@ func Test_deleteAutoscale(t *testing.T) { name: "when successfully getting autoscale settings", instance: "my-instance", expectedCode: http.StatusOK, - expectedBody: ``, manager: &fake.RpaasManager{ FakeDeleteAutoscale: func(instance string) error { assert.Equal(t, "my-instance", instance) diff --git a/pkg/web/certificate.go b/pkg/web/certificate.go index ad765671b..ee7d0064c 100644 --- a/pkg/web/certificate.go +++ b/pkg/web/certificate.go @@ -6,7 +6,10 @@ package web import ( "crypto/tls" + "errors" "fmt" + "io/ioutil" + "mime" "net/http" "net/url" @@ -40,25 +43,19 @@ func deleteCertificate(c echo.Context) error { func updateCertificate(c echo.Context) error { ctx := c.Request().Context() - rawCertificate, err := getFormFileContent(c, "cert") + rawCertificate, err := getValueFromFormOrMultipart(c.Request(), "cert") if err != nil { - if err == http.ErrMissingFile { - return c.String(http.StatusBadRequest, "cert file is either not provided or not valid") - } - return err + return &rpaas.ValidationError{Msg: "cannot read the certificate from request", Internal: err} } - rawKey, err := getFormFileContent(c, "key") + rawKey, err := getValueFromFormOrMultipart(c.Request(), "key") if err != nil { - if err == http.ErrMissingFile { - return c.String(http.StatusBadRequest, "key file is either not provided or not valid") - } - return err + return &rpaas.ValidationError{Msg: "cannot read the key from request", Internal: err} } certificate, err := tls.X509KeyPair(rawCertificate, rawKey) if err != nil { - return c.String(http.StatusBadRequest, fmt.Sprintf("could not load the given certicate and key: %s", err)) + return &rpaas.ValidationError{Msg: "could not load the given certificate and key", Internal: err} } manager, err := getManager(ctx) @@ -154,3 +151,30 @@ func deleteCertManagerRequest(c echo.Context) error { return c.NoContent(http.StatusOK) } + +func getValueFromFormOrMultipart(r *http.Request, key string) ([]byte, error) { + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return nil, fmt.Errorf("failed to parse content-type header: %w", err) + } + + switch ct { + case "application/x-www-form-urlencoded": + if value := r.FormValue(key); len(value) > 0 { + return []byte(value), nil + } + + return nil, errors.New("http: no such field") + + case "multipart/form-data": + f, _, err := r.FormFile(key) + if err != nil { + return nil, err + } + defer f.Close() + + return ioutil.ReadAll(f) + } + + return nil, nil +} diff --git a/pkg/web/certificate_test.go b/pkg/web/certificate_test.go index 1e3873fe1..1764b4971 100644 --- a/pkg/web/certificate_test.go +++ b/pkg/web/certificate_test.go @@ -7,6 +7,7 @@ package web import ( "bytes" "crypto/tls" + "errors" "fmt" "mime/multipart" "net/http" @@ -25,9 +26,6 @@ import ( ) func Test_updateCertificate(t *testing.T) { - instanceName := "my-instance-name" - boundary := "XXXXXXXXXXXXXXX" - certPem := `-----BEGIN CERTIFICATE----- MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow @@ -49,102 +47,95 @@ EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== certificate, err := tls.X509KeyPair([]byte(certPem), []byte(keyPem)) require.NoError(t, err) - makeBodyRequest := func(cert, key, name string) string { - b := &bytes.Buffer{} - w := multipart.NewWriter(b) - w.SetBoundary(boundary) - if cert != "" { - writer, err := w.CreateFormFile("cert", "cert.pem") - require.NoError(t, err) - writer.Write([]byte(cert)) - } - if key != "" { - writer, err := w.CreateFormFile("key", "key.pem") - require.NoError(t, err) - writer.Write([]byte(key)) - } - if name != "" { - err := w.WriteField("name", name) - require.NoError(t, err) - } - w.Close() - return b.String() - } - - testCases := []struct { + testCases := map[string]struct { name string - requestBody string + certificate string + key string expectedCode int expectedBody string manager rpaas.RpaasManager }{ - { - name: "when no private key is sent", - requestBody: makeBodyRequest("some certificate", "", ""), - expectedCode: 400, - expectedBody: "key file is either not provided or not valid", - manager: &fake.RpaasManager{}, + "when no private key is sent": { + certificate: "some certificate", + expectedCode: http.StatusBadRequest, + expectedBody: `{"message":"cannot read the key from request"}`, }, - { - name: "when no certificate is sent", - requestBody: makeBodyRequest("", "some private key", ""), - expectedCode: 400, - expectedBody: "cert file is either not provided or not valid", - manager: &fake.RpaasManager{}, + + "when no certificate is sent": { + key: "some private key", + expectedCode: http.StatusBadRequest, + expectedBody: `{"message":"cannot read the certificate from request"}`, }, - { - name: "when successfully adding a default certificate", - requestBody: makeBodyRequest(certPem, keyPem, ""), - expectedCode: 200, - expectedBody: "", + + "when successfully adding a default certificate": { + certificate: certPem, + key: keyPem, + expectedCode: http.StatusOK, manager: &fake.RpaasManager{ FakeUpdateCertificate: func(instance, name string, c tls.Certificate) error { assert.Equal(t, "", name) - assert.Equal(t, instance, instanceName) + assert.Equal(t, "my-instance", instance) assert.Equal(t, c, certificate) return nil }, }, }, - { - name: "when successfully adding a named certificate", - requestBody: makeBodyRequest(certPem, keyPem, "mycert"), - expectedCode: 200, - expectedBody: "", + + "when successfully adding a certificate with custom name": { + name: "mycert", + certificate: certPem, + key: keyPem, + expectedCode: http.StatusOK, manager: &fake.RpaasManager{ FakeUpdateCertificate: func(instance, name string, c tls.Certificate) error { assert.Equal(t, "mycert", name) - assert.Equal(t, instance, instanceName) + assert.Equal(t, "my-instance", instance) assert.Equal(t, c, certificate) return nil }, }, }, - { - name: "when UpdateCertificate method returns ", - requestBody: makeBodyRequest(certPem, keyPem, ""), - expectedCode: 400, - expectedBody: "{\"Msg\":\"some error\"}", + + "when cannot update the certificate due to an error": { + certificate: certPem, + key: keyPem, + expectedCode: http.StatusInternalServerError, + expectedBody: `{"message":"some error"}`, manager: &fake.RpaasManager{ FakeUpdateCertificate: func(instance, name string, c tls.Certificate) error { - return &rpaas.ValidationError{Msg: "some error"} + return errors.New("some error") }, }, }, } - for _, tt := range testCases { - t.Run(tt.name, func(t *testing.T) { + for name, tt := range testCases { + t.Run(name, func(t *testing.T) { srv := newTestingServer(t, tt.manager) defer srv.Close() - path := fmt.Sprintf("%s/resources/%s/certificate", srv.URL, instanceName) - request, err := http.NewRequest(http.MethodPost, path, strings.NewReader(tt.requestBody)) - require.NoError(t, err) - request.Header.Set(echo.HeaderContentType, fmt.Sprintf(`%s; boundary=%s`, echo.MIMEMultipartForm, boundary)) - rsp, err := srv.Client().Do(request) - require.NoError(t, err) - assert.Equal(t, tt.expectedCode, rsp.StatusCode) - assert.Equal(t, tt.expectedBody, bodyContent(rsp)) + path := fmt.Sprintf("%s/resources/%s/certificate", srv.URL, "my-instance") + + t.Run("Content-Type: multipart/form-data", func(t *testing.T) { + body, boundary := makeMultipartFormForCertificate(t, tt.certificate, tt.key, tt.name) + r, err := http.NewRequest(http.MethodPost, path, strings.NewReader(body)) + require.NoError(t, err) + r.Header.Set(echo.HeaderContentType, fmt.Sprintf(`%s; boundary=%s`, echo.MIMEMultipartForm, boundary)) + rsp, err := srv.Client().Do(r) + require.NoError(t, err) + assert.Equal(t, tt.expectedCode, rsp.StatusCode) + assert.Equal(t, tt.expectedBody, bodyContent(rsp)) + }) + + t.Run("Content-Type: application/x-www-form-urlencoded", func(t *testing.T) { + body := makeFormBodyForCertificate(tt.certificate, tt.key, tt.name) + r, err := http.NewRequest(http.MethodPost, path, strings.NewReader(body)) + require.NoError(t, err) + r.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm) + rsp, err := srv.Client().Do(r) + require.NoError(t, err) + assert.Equal(t, tt.expectedCode, rsp.StatusCode) + assert.Equal(t, tt.expectedBody, bodyContent(rsp)) + }) }) } } @@ -167,7 +158,7 @@ func Test_deleteCertificate(t *testing.T) { }, instance: "my-instance", expectedCode: http.StatusNotFound, - expectedBody: "{\"Msg\":\"\"}", + expectedBody: `{"message":""}`, }, { name: "when the certificate exists", @@ -178,7 +169,6 @@ func Test_deleteCertificate(t *testing.T) { }, instance: "real-instance", expectedCode: http.StatusOK, - expectedBody: "", }, { name: "when the certificate does not exist", @@ -189,7 +179,7 @@ func Test_deleteCertificate(t *testing.T) { }, }, expectedCode: http.StatusNotFound, - expectedBody: "{\"Msg\":\"no certificate bound to instance \\\"real-instance\\\"\"}", + expectedBody: `{"message":"no certificate bound to instance \"real-instance\""}`, }, { name: "passing a certificate name and asserting it", @@ -358,7 +348,7 @@ func Test_GetCertManagerRequests(t *testing.T) { }, }, expectedCode: http.StatusBadRequest, - expectedBody: `{"Msg":"some error"}`, + expectedBody: `{"message":"some error"}`, }, } @@ -407,7 +397,7 @@ func Test_UpdateCertManagerRequest(t *testing.T) { }, }, expectedCode: http.StatusBadRequest, - expectedBody: `{"Msg":"some error"}`, + expectedBody: `{"message":"some error"}`, }, } @@ -467,7 +457,7 @@ func Test_DeleteCertManagerRequest(t *testing.T) { }, }, expectedCode: http.StatusBadRequest, - expectedBody: `{"Msg":"some error"}`, + expectedBody: `{"message":"some error"}`, }, } @@ -485,3 +475,34 @@ func Test_DeleteCertManagerRequest(t *testing.T) { }) } } + +func makeMultipartFormForCertificate(t *testing.T, cert, key, name string) (string, string) { + b := &bytes.Buffer{} + w := multipart.NewWriter(b) + if cert != "" { + writer, err := w.CreateFormFile("cert", "cert.pem") + require.NoError(t, err) + writer.Write([]byte(cert)) + } + + if key != "" { + writer, err := w.CreateFormFile("key", "key.pem") + require.NoError(t, err) + writer.Write([]byte(key)) + } + + if name != "" { + err := w.WriteField("name", name) + require.NoError(t, err) + } + w.Close() + return b.String(), w.Boundary() +} + +func makeFormBodyForCertificate(cert, key, name string) string { + u := make(url.Values) + u.Set("cert", cert) + u.Set("key", key) + u.Set("name", name) + return u.Encode() +} diff --git a/pkg/web/errors.go b/pkg/web/errors.go index 2495f9a79..c3b4c2de2 100644 --- a/pkg/web/errors.go +++ b/pkg/web/errors.go @@ -1,7 +1,7 @@ package web import ( - "fmt" + "errors" "net/http" "github.com/labstack/echo/v4" @@ -14,48 +14,52 @@ func ErrorMiddleware(next echo.HandlerFunc) echo.HandlerFunc { if err == nil { return nil } + + internal := errors.Unwrap(err) + if rpaas.IsValidationError(err) { - return &echo.HTTPError{Code: http.StatusBadRequest, Message: err} + return &echo.HTTPError{Code: http.StatusBadRequest, Message: err, Internal: internal} } + if rpaas.IsConflictError(err) { - return &echo.HTTPError{Code: http.StatusConflict, Message: err} + return &echo.HTTPError{Code: http.StatusConflict, Message: err, Internal: internal} } + if rpaas.IsNotFoundError(err) { - return &echo.HTTPError{Code: http.StatusNotFound, Message: err} + return &echo.HTTPError{Code: http.StatusNotFound, Message: err, Internal: internal} } + return err } } func HTTPErrorHandler(err error, c echo.Context) { var ( - code = http.StatusInternalServerError - msg interface{} + code int = http.StatusInternalServerError + msg interface{} = err.Error() + internal error = errors.Unwrap(err) ) - if he, ok := err.(*echo.HTTPError); ok { - code = he.Code - msg = he.Message - if he.Internal != nil { - msg = fmt.Sprintf("%v, %v", err, he.Internal) - } - } else { - msg = err.Error() + var he *echo.HTTPError + if errors.As(err, &he) { + code, msg = he.Code, he.Message } + if _, ok := msg.(string); ok { msg = echo.Map{"message": msg} } - c.Logger().Error(err) + if c.Response().Committed { + return + } - if !c.Response().Committed { - if c.Request().Method == http.MethodHead { - err = c.NoContent(code) - } else { - err = c.JSON(code, msg) - } - if err != nil { - c.Logger().Error(err) - } + if c.Request().Method == http.MethodHead { + err = c.NoContent(code) + } else { + err = c.JSON(code, msg) + } + + if err != nil { + c.Logger().Error("Final error: %s; Wrapped error: %s", err, internal) } } diff --git a/pkg/web/extra_files_test.go b/pkg/web/extra_files_test.go index 1c8b965f4..7ae5c7b56 100644 --- a/pkg/web/extra_files_test.go +++ b/pkg/web/extra_files_test.go @@ -301,7 +301,7 @@ func Test_deleteExtraFiles(t *testing.T) { instance: "my-instance", files: []string{"not-found.cnf"}, expectedCode: http.StatusNotFound, - expectedBody: "{\"Msg\":\"not found\"}", + expectedBody: `{"message":"not found"}`, manager: &fake.RpaasManager{ FakeDeleteExtraFiles: func(string, ...string) error { return &rpaas.NotFoundError{ diff --git a/pkg/web/handlers.go b/pkg/web/handlers.go index b59eb39b6..aeb479cb6 100644 --- a/pkg/web/handlers.go +++ b/pkg/web/handlers.go @@ -5,7 +5,6 @@ package web import ( - "io/ioutil" "net/http" "github.com/labstack/echo/v4" @@ -31,23 +30,6 @@ func scale(c echo.Context) error { return c.NoContent(http.StatusOK) } -func getFormFileContent(c echo.Context, key string) ([]byte, error) { - fileHeader, err := c.FormFile(key) - if err != nil { - return []byte{}, err - } - file, err := fileHeader.Open() - if err != nil { - return []byte{}, err - } - defer file.Close() - rawContent, err := ioutil.ReadAll(file) - if err != nil { - return []byte{}, err - } - return rawContent, nil -} - func serviceNodeStatus(c echo.Context) error { ctx := c.Request().Context() manager, err := getManager(ctx)