Skip to content

Commit

Permalink
feat(web): accept certificates urleconded too
Browse files Browse the repository at this point in the history
  • Loading branch information
nettoclaudio committed Jul 26, 2022
1 parent 40fec2a commit 0d1f8e3
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 148 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
27 changes: 23 additions & 4 deletions internal/pkg/rpaas/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
package rpaas

import (
"github.com/pkg/errors"
"errors"

k8sErrors "k8s.io/apimachinery/pkg/api/errors"
)

Expand All @@ -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
Expand Down
9 changes: 4 additions & 5 deletions internal/pkg/rpaas/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"net"
"net/url"
Expand All @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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())
}
Expand Down
3 changes: 1 addition & 2 deletions internal/purge/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
15 changes: 6 additions & 9 deletions pkg/web/autoscale_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
46 changes: 35 additions & 11 deletions pkg/web/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ package web

import (
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"mime"
"net/http"
"net/url"

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}
Loading

0 comments on commit 0d1f8e3

Please sign in to comment.