diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fb69fcb0..382bc286 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,7 @@ variables: DOCKER_HOST: tcp://docker:2375 DOCKER_BASE_IMAGE: $CI_REGISTRY_GO/haproxy-debian BATS_VERSION: v1.4.1 - GO_VERSION: "1.22" + GO_VERSION: "1.23" DOCKER_VERSION: "26.0" diff: diff --git a/.golangci.yml b/.golangci.yml index cbcf2149..1bf737f3 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -22,7 +22,6 @@ linters: disable: - dupl - exhaustive - - exhaustivestruct - funlen - gci - gochecknoglobals @@ -30,8 +29,6 @@ linters: - goconst - gocyclo - godot - - goerr113 - - gomnd - lll - nestif - nlreturn @@ -41,18 +38,9 @@ linters: - paralleltest - testpackage - varnamelen - - nosnakecase - exhaustruct - nonamedreturns - forcetypeassert - - golint #deprecated - - varcheck #deprecated - - ifshort #deprecated - - structcheck #deprecated - - maligned #deprecated - - scopelint #deprecated - - interfacer #deprecated - - deadcode #deprecated - rowserrcheck #rowserrcheck is disabled because of generics - sqlclosecheck #rowserrcheck is disabled because of generics - wastedassign #rowserrcheck is disabled because of generics @@ -71,6 +59,11 @@ linters: - gocritic - tagalign - depguard + - mnd + - gomnd + - err113 + - execinquery + - exportloopref issues: exclude: diff --git a/Makefile b/Makefile index 7083aa79..a6ab96ee 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GIT_MODIFIED=${GIT_MODIFIED1}${GIT_MODIFIED2} SWAGGER_VERSION=${shell curl -s https://raw.githubusercontent.com/haproxytech/client-native/master/Makefile | grep SWAGGER_VERSION -m 1 | awk -F"=" '{print $$2}'} BUILD_DATE=$(shell date -u '+%Y-%m-%dT%H:%M:%SZ') CGO_ENABLED?=0 -GOLANGCI_LINT_VERSION=1.57.1 +GOLANGCI_LINT_VERSION=1.61.0 all: update clean build diff --git a/configuration/dataplane_storage.go b/configuration/dataplane_storage.go index 756725ab..c9db3cd3 100644 --- a/configuration/dataplane_storage.go +++ b/configuration/dataplane_storage.go @@ -130,7 +130,7 @@ func (c *Configuration) copyClusterToConfiguration(dapiStorageCluster *storagety if dapiStorageCluster.ClusterID != nil && !misc.HasOSArg("", "", "") { c.Cluster.ClusterID.Store(*dapiStorageCluster.ClusterID) } - if dapiStorageCluster.ClusterLogTargets != nil && len(dapiStorageCluster.ClusterLogTargets) > 0 { + if len(dapiStorageCluster.ClusterLogTargets) > 0 { c.Cluster.ClusterLogTargets = dapiStorageCluster.ClusterLogTargets } } diff --git a/configuration/map_sync.go b/configuration/map_sync.go index edc9a9f1..10534678 100644 --- a/configuration/map_sync.go +++ b/configuration/map_sync.go @@ -124,7 +124,7 @@ func equalSomeEntries(fEntries, rEntries models.MapEntries, index ...int) bool { return false } - max := 0 + var maximum int switch l := len(rEntries); { case l > 19: for i := l - 20; i < l; i++ { @@ -132,21 +132,21 @@ func equalSomeEntries(fEntries, rEntries models.MapEntries, index ...int) bool { return false } } - max = l - 19 + maximum = l - 19 case l == 0: return true default: - max = l + maximum = l } maxRandom := 10 - if max < 10 { - maxRandom = max + if maximum < 10 { + maxRandom = maximum } for range maxRandom { // There's no need for strong number generation, here, just need for performance - r := rand.Intn(max) + r := rand.Intn(maximum) if len(index) > 0 { r = index[0] } diff --git a/configuration/user.go b/configuration/user.go index d7c9423e..05bff1c8 100644 --- a/configuration/user.go +++ b/configuration/user.go @@ -176,7 +176,7 @@ func AuthenticateUser(user string, pass string) (interface{}, error) { if strings.HasPrefix(u.Password, "\"${") && strings.HasSuffix(u.Password, "}\"") { userPass = os.Getenv(misc.ExtractEnvVar(userPass)) if userPass == "" { - return nil, api_errors.New(401, fmt.Sprintf("%s %s", "can not read password from env variable:", u.Password)) + return nil, api_errors.New(401, "%s %s", "can not read password from env variable:", u.Password) } } @@ -184,12 +184,12 @@ func AuthenticateUser(user string, pass string) (interface{}, error) { if pass == userPass { return user, nil } - return nil, api_errors.New(401, fmt.Sprintf("%s %s", "invalid password:", pass)) + return nil, api_errors.New(401, "%s %s", "invalid password:", pass) } if checkPassword(pass, userPass) { return user, nil } - return nil, api_errors.New(401, fmt.Sprintf("%s %s", "invalid password:", pass)) + return nil, api_errors.New(401, "%s %s", "invalid password:", pass) } func checkPassword(pass, storedPass string) bool { diff --git a/configure_data_plane.go b/configure_data_plane.go index 9c2c1ec3..8699c4b8 100644 --- a/configure_data_plane.go +++ b/configure_data_plane.go @@ -56,7 +56,7 @@ import ( "github.com/haproxytech/dataplaneapi/operations" "github.com/haproxytech/dataplaneapi/operations/discovery" "github.com/haproxytech/dataplaneapi/operations/specification" - "github.com/haproxytech/dataplaneapi/operations/specification_openapiv3" + "github.com/haproxytech/dataplaneapi/operations/version3" "github.com/haproxytech/dataplaneapi/rate" "github.com/haproxytech/dataplaneapi/resilient" socket_runtime "github.com/haproxytech/dataplaneapi/runtime" @@ -868,7 +868,7 @@ func configureAPI(api *operations.DataPlaneAPI) http.Handler { //nolint:cyclop,m data.ID = service_discovery.NewServiceDiscoveryUUID() } if errSD = service_discovery.ValidateConsulData(data, true); errSD != nil { - log.Fatalf("Error validating Consul instance: " + errSD.Error()) + log.Fatal("Error validating Consul instance: " + errSD.Error()) } if errSD = discovery.AddNode("consul", *data.ID, data); errSD != nil { log.Warning("Error creating consul instance: " + errSD.Error()) @@ -884,7 +884,7 @@ func configureAPI(api *operations.DataPlaneAPI) http.Handler { //nolint:cyclop,m data.ID = service_discovery.NewServiceDiscoveryUUID() } if errSD = service_discovery.ValidateAWSData(data, true); errSD != nil { - log.Fatalf("Error validating AWS instance: " + errSD.Error()) + log.Fatal("Error validating AWS instance: " + errSD.Error()) } if errSD = discovery.AddNode("aws", *data.ID, data); errSD != nil { log.Warning("Error creating AWS instance: " + errSD.Error()) @@ -917,12 +917,12 @@ func configureAPI(api *operations.DataPlaneAPI) http.Handler { //nolint:cyclop,m api.StorageReplaceStorageGeneralFileHandler = &handlers.StorageReplaceStorageGeneralFileHandlerImpl{Client: client, ReloadAgent: ra} // setup OpenAPI v3 specification handler - api.SpecificationOpenapiv3GetOpenapiv3SpecificationHandler = specification_openapiv3.GetOpenapiv3SpecificationHandlerFunc(func(params specification_openapiv3.GetOpenapiv3SpecificationParams, principal interface{}) middleware.Responder { + api.Version3GetOpenapiv3SpecificationHandler = version3.GetOpenapiv3SpecificationHandlerFunc(func(params version3.GetOpenapiv3SpecificationParams, principal interface{}) middleware.Responder { v2 := openapi2.T{} err = v2.UnmarshalJSON(SwaggerJSON) if err != nil { e := misc.HandleError(err) - return specification_openapiv3.NewGetOpenapiv3SpecificationDefault(int(*e.Code)).WithPayload(e) + return version3.NewGetOpenapiv3SpecificationDefault(int(*e.Code)).WithPayload(e) } // if host is empty(dynamic hosts), server prop is empty, @@ -936,9 +936,9 @@ func configureAPI(api *operations.DataPlaneAPI) http.Handler { //nolint:cyclop,m v3, err = openapi2conv.ToV3(&v2) if err != nil { e := misc.HandleError(err) - return specification_openapiv3.NewGetOpenapiv3SpecificationDefault(int(*e.Code)).WithPayload(e) + return version3.NewGetOpenapiv3SpecificationDefault(int(*e.Code)).WithPayload(e) } - return specification_openapiv3.NewGetOpenapiv3SpecificationOK().WithPayload(v3) + return version3.NewGetOpenapiv3SpecificationOK().WithPayload(v3) }) // TODO: do we need a ReloadAgent for SPOE @@ -1217,10 +1217,10 @@ func handleSignals(ctx context.Context, cancel context.CancelFunc, sigs chan os. func reloadConfigurationFile(client client_native.HAProxyClient, haproxyOptions dataplaneapi_config.HAProxyConfiguration, users *dataplaneapi_config.Users) { confClient, err := cn.ConfigureConfigurationClient(haproxyOptions, mWorker) if err != nil { - log.Fatalf(err.Error()) + log.Fatal(err.Error()) } if err := users.Init(); err != nil { - log.Fatalf(err.Error()) + log.Fatal(err.Error()) } log.Info("Rereading Configuration Files") clientMutex.Lock() diff --git a/discovery/consul_service_discovery_instance.go b/discovery/consul_service_discovery_instance.go index d28a5ccf..d2066104 100644 --- a/discovery/consul_service_discovery_instance.go +++ b/discovery/consul_service_discovery_instance.go @@ -211,7 +211,7 @@ func (c *consulInstance) validateHealthChecks(node *serviceEntry) bool { } func (c *consulInstance) validateHealthChecksAny(node *serviceEntry) bool { - if node.Checks == nil || len(node.Checks) == 0 { + if len(node.Checks) == 0 { return false } @@ -224,7 +224,7 @@ func (c *consulInstance) validateHealthChecksAny(node *serviceEntry) bool { } func (c *consulInstance) validateHealthChecksAll(node *serviceEntry) bool { - if node.Checks == nil || len(node.Checks) == 0 { + if len(node.Checks) == 0 { return false } @@ -237,7 +237,7 @@ func (c *consulInstance) validateHealthChecksAll(node *serviceEntry) bool { } func (c *consulInstance) validateHealthChecksMin(node *serviceEntry) bool { - if node.Checks == nil || len(node.Checks) == 0 { + if len(node.Checks) == 0 { return false } diff --git a/doc.go b/doc.go index fb34ce22..93389a7b 100644 --- a/doc.go +++ b/doc.go @@ -35,6 +35,7 @@ // Produces: // - application/octet-stream // - application/json +// - text/plain // // swagger:meta package dataplaneapi diff --git a/embedded_spec.go b/embedded_spec.go index 5ded4620..de8f2fd0 100644 --- a/embedded_spec.go +++ b/embedded_spec.go @@ -16655,7 +16655,7 @@ func init() { "get": { "description": "Returns HAProxy configuration file in plain text", "produces": [ - "application/json" + "text/plain" ], "tags": [ "Configuration" @@ -16674,15 +16674,7 @@ func init() { "200": { "description": "Operation successful", "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "string" - } - } + "type": "string" }, "headers": { "Cluster-Version": { @@ -16710,7 +16702,7 @@ func init() { "text/plain" ], "produces": [ - "application/json" + "text/plain" ], "tags": [ "Configuration" @@ -20774,7 +20766,7 @@ func init() { "parameters": [ { "type": "file", - "x-mimetype": "text/plain", + "x-mimetype": "application/octet-stream", "description": "General use file content", "name": "file_upload", "in": "formData" @@ -20837,7 +20829,7 @@ func init() { "put": { "description": "Replaces the contents of a managed general use file on disk", "consumes": [ - "text/plain" + "multipart/form-data" ], "produces": [ "application/json" @@ -20856,12 +20848,11 @@ func init() { "required": true }, { - "name": "data", - "in": "body", - "required": true, - "schema": { - "type": "string" - } + "type": "file", + "x-mimetype": "application/octet-stream", + "description": "General use file content", + "name": "file_upload", + "in": "formData" }, { "$ref": "#/parameters/skip_reload" @@ -26083,6 +26074,9 @@ func init() { "pattern": "^[^\\s]+$", "x-display-name": "Group" }, + "h1_accept_payload_with_any_method": { + "type": "boolean" + }, "h1_case_adjust": { "type": "array", "items": { @@ -26107,6 +26101,9 @@ func init() { "h1_case_adjust_file": { "type": "string" }, + "h1_do_not_close_on_insecure_transfer_encoding": { + "type": "boolean" + }, "h2_workaround_bogus_websocket_clients": { "type": "boolean" }, @@ -31984,6 +31981,11 @@ func init() { "type": "integer", "x-nullable": true }, + "metadata": { + "additionalProperties": { + "type": "object" + } + }, "name": { "type": "string", "pattern": "^[^\\s]+$", @@ -63081,7 +63083,7 @@ func init() { "get": { "description": "Returns HAProxy configuration file in plain text", "produces": [ - "application/json" + "text/plain" ], "tags": [ "Configuration" @@ -63108,15 +63110,7 @@ func init() { "200": { "description": "Operation successful", "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "string" - } - } + "type": "string" }, "headers": { "Cluster-Version": { @@ -63153,7 +63147,7 @@ func init() { "text/plain" ], "produces": [ - "application/json" + "text/plain" ], "tags": [ "Configuration" @@ -69587,7 +69581,7 @@ func init() { "parameters": [ { "type": "file", - "x-mimetype": "text/plain", + "x-mimetype": "application/octet-stream", "description": "General use file content", "name": "file_upload", "in": "formData" @@ -69695,7 +69689,7 @@ func init() { "put": { "description": "Replaces the contents of a managed general use file on disk", "consumes": [ - "text/plain" + "multipart/form-data" ], "produces": [ "application/json" @@ -69714,12 +69708,11 @@ func init() { "required": true }, { - "name": "data", - "in": "body", - "required": true, - "schema": { - "type": "string" - } + "type": "file", + "x-mimetype": "application/octet-stream", + "description": "General use file content", + "name": "file_upload", + "in": "formData" }, { "type": "boolean", @@ -76067,6 +76060,9 @@ func init() { "pattern": "^[^\\s]+$", "x-display-name": "Group" }, + "h1_accept_payload_with_any_method": { + "type": "boolean" + }, "h1_case_adjust": { "type": "array", "items": { @@ -76078,6 +76074,9 @@ func init() { "h1_case_adjust_file": { "type": "string" }, + "h1_do_not_close_on_insecure_transfer_encoding": { + "type": "boolean" + }, "h2_workaround_bogus_websocket_clients": { "type": "boolean" }, @@ -81892,6 +81891,11 @@ func init() { "type": "integer", "x-nullable": true }, + "metadata": { + "additionalProperties": { + "type": "object" + } + }, "name": { "type": "string", "pattern": "^[^\\s]+$", diff --git a/generate/swagger/script.sh b/generate/swagger/script.sh index 815120d3..4e16948a 100755 --- a/generate/swagger/script.sh +++ b/generate/swagger/script.sh @@ -1,6 +1,8 @@ #!/bin/bash set -e +GO_VERSION=$(go version) +echo " ---> go version: $GO_VERSION" SPEC_DIR=$(mktemp -d) echo " ---> source folder: $SPEC_DIR" DST_DIR=$(mktemp -d) diff --git a/go.mod b/go.mod index c2a14fcb..d775dddd 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/haproxytech/dataplaneapi -go 1.22 +go 1.23 require ( github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 @@ -24,7 +24,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/renameio v1.0.1 github.com/google/uuid v1.6.0 - github.com/haproxytech/client-native/v6 v6.0.1 + github.com/haproxytech/client-native/v6 v6.0.3 github.com/jessevdk/go-flags v1.5.0 github.com/joho/godotenv v1.5.1 github.com/json-iterator/go v1.1.12 @@ -39,7 +39,7 @@ require ( github.com/stretchr/testify v1.9.0 go.uber.org/automaxprocs v1.5.3 golang.org/x/net v0.27.0 - golang.org/x/sys v0.24.0 + golang.org/x/sys v0.25.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 376bfbc8..27c24044 100644 --- a/go.sum +++ b/go.sum @@ -98,8 +98,8 @@ github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/haproxytech/client-native/v6 v6.0.1 h1:lVeg4CySqpFlRa4CER/+S4LbhKNBLHV1AK8vvzk1zrA= -github.com/haproxytech/client-native/v6 v6.0.1/go.mod h1:XDu46mnUw7/5Xs8RRgaM0anryVg9t/kMqe/MoEc8JjI= +github.com/haproxytech/client-native/v6 v6.0.3 h1:AFd021MvqABlE/UhHiqFC/eYH9Wx7Tn5WPfVszZlero= +github.com/haproxytech/client-native/v6 v6.0.3/go.mod h1:chE1dxclu+2DCtmc969mDsLXehijaEVXYWoftu+X2nk= github.com/haproxytech/go-logger v1.1.0 h1:HgGtYaI1ApkvbQdsm7f9AzQQoxTB7w37criTflh7IQE= github.com/haproxytech/go-logger v1.1.0/go.mod h1:OekUd8HCb7ubxMplzHUPBTHNxZmddOWfOjWclZsqIeM= github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= @@ -208,8 +208,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/handlers/general_storage.go b/handlers/general_storage.go index e7dfece3..61047e9f 100644 --- a/handlers/general_storage.go +++ b/handlers/general_storage.go @@ -188,7 +188,17 @@ func (h *StorageReplaceStorageGeneralFileHandlerImpl) Handle(params storage.Repl return storage.NewReplaceStorageGeneralFileDefault(int(*e.Code)).WithPayload(e) } - _, err = gs.Replace(params.Name, params.Data) + file, ok := params.FileUpload.(*runtime.File) + if !ok { + return storage.NewReplaceStorageGeneralFileBadRequest() + } + data := []byte{} + if _, err := file.Read(data); err != nil { + e := misc.HandleError(err) + return storage.NewReplaceStorageGeneralFileDefault(int(*e.Code)).WithPayload(e) + } + + _, err = gs.Replace(params.Name, string(data)) if err != nil { e := misc.HandleError(err) return storage.NewReplaceStorageGeneralFileDefault(int(*e.Code)).WithPayload(e) diff --git a/handlers/raw.go b/handlers/raw.go index d2b0b370..a47cfb37 100644 --- a/handlers/raw.go +++ b/handlers/raw.go @@ -67,7 +67,7 @@ func (h *GetRawConfigurationHandlerImpl) Handle(params configuration.GetHAProxyC if clusterVersion != 0 { cVersion = strconv.FormatInt(clusterVersion, 10) } - return configuration.NewGetHAProxyConfigurationOK().WithPayload(&configuration.GetHAProxyConfigurationOKBody{Data: &data}).WithClusterVersion(cVersion).WithConfigurationChecksum(md5Hash) + return configuration.NewGetHAProxyConfigurationOK().WithPayload(data).WithClusterVersion(cVersion).WithConfigurationChecksum(md5Hash) } // Handle executing the request and returning a response diff --git a/operations/configuration/get_h_a_proxy_configuration.go b/operations/configuration/get_h_a_proxy_configuration.go index 13e4369f..725e5fa1 100644 --- a/operations/configuration/get_h_a_proxy_configuration.go +++ b/operations/configuration/get_h_a_proxy_configuration.go @@ -21,14 +21,9 @@ package configuration // Editing this file might prove futile when you re-run the generate command import ( - "context" "net/http" - "github.com/go-openapi/errors" "github.com/go-openapi/runtime/middleware" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" ) // GetHAProxyConfigurationHandlerFunc turns a function with the right signature into a get h a proxy configuration handler @@ -89,59 +84,3 @@ func (o *GetHAProxyConfiguration) ServeHTTP(rw http.ResponseWriter, r *http.Requ o.Context.Respond(rw, r, route.Produces, route, res) } - -// GetHAProxyConfigurationOKBody get h a proxy configuration o k body -// -// swagger:model GetHAProxyConfigurationOKBody -type GetHAProxyConfigurationOKBody struct { - - // data - // Required: true - Data *string `json:"data"` -} - -// Validate validates this get h a proxy configuration o k body -func (o *GetHAProxyConfigurationOKBody) Validate(formats strfmt.Registry) error { - var res []error - - if err := o.validateData(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (o *GetHAProxyConfigurationOKBody) validateData(formats strfmt.Registry) error { - - if err := validate.Required("getHAProxyConfigurationOK"+"."+"data", "body", o.Data); err != nil { - return err - } - - return nil -} - -// ContextValidate validates this get h a proxy configuration o k body based on context it is used -func (o *GetHAProxyConfigurationOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (o *GetHAProxyConfigurationOKBody) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *GetHAProxyConfigurationOKBody) UnmarshalBinary(b []byte) error { - var res GetHAProxyConfigurationOKBody - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} diff --git a/operations/configuration/get_h_a_proxy_configuration_responses.go b/operations/configuration/get_h_a_proxy_configuration_responses.go index 0c115884..1c5d0e54 100644 --- a/operations/configuration/get_h_a_proxy_configuration_responses.go +++ b/operations/configuration/get_h_a_proxy_configuration_responses.go @@ -53,7 +53,7 @@ type GetHAProxyConfigurationOK struct { /* In: Body */ - Payload *GetHAProxyConfigurationOKBody `json:"body,omitempty"` + Payload string `json:"body,omitempty"` } // NewGetHAProxyConfigurationOK creates GetHAProxyConfigurationOK with default headers values @@ -96,13 +96,13 @@ func (o *GetHAProxyConfigurationOK) SetConfigurationVersion(configurationVersion } // WithPayload adds the payload to the get h a proxy configuration o k response -func (o *GetHAProxyConfigurationOK) WithPayload(payload *GetHAProxyConfigurationOKBody) *GetHAProxyConfigurationOK { +func (o *GetHAProxyConfigurationOK) WithPayload(payload string) *GetHAProxyConfigurationOK { o.Payload = payload return o } // SetPayload sets the payload to the get h a proxy configuration o k response -func (o *GetHAProxyConfigurationOK) SetPayload(payload *GetHAProxyConfigurationOKBody) { +func (o *GetHAProxyConfigurationOK) SetPayload(payload string) { o.Payload = payload } @@ -131,11 +131,9 @@ func (o *GetHAProxyConfigurationOK) WriteResponse(rw http.ResponseWriter, produc } rw.WriteHeader(200) - if o.Payload != nil { - payload := o.Payload - if err := producer.Produce(rw, payload); err != nil { - panic(err) // let the recovery middleware deal with this - } + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this } } diff --git a/operations/data_plane_api.go b/operations/data_plane_api.go index d734ec73..2fd27ccc 100644 --- a/operations/data_plane_api.go +++ b/operations/data_plane_api.go @@ -79,7 +79,6 @@ import ( "github.com/haproxytech/dataplaneapi/operations/service_discovery" "github.com/haproxytech/dataplaneapi/operations/sites" "github.com/haproxytech/dataplaneapi/operations/specification" - "github.com/haproxytech/dataplaneapi/operations/specification_openapiv3" "github.com/haproxytech/dataplaneapi/operations/spoe" "github.com/haproxytech/dataplaneapi/operations/spoe_transactions" "github.com/haproxytech/dataplaneapi/operations/stats" @@ -93,6 +92,7 @@ import ( "github.com/haproxytech/dataplaneapi/operations/transactions" "github.com/haproxytech/dataplaneapi/operations/user" "github.com/haproxytech/dataplaneapi/operations/userlist" + "github.com/haproxytech/dataplaneapi/operations/version3" ) // NewDataPlaneAPI creates a new DataPlane instance @@ -119,6 +119,7 @@ func NewDataPlaneAPI(spec *loads.Document) *DataPlaneAPI { BinProducer: runtime.ByteStreamProducer(), JSONProducer: runtime.JSONProducer(), + TxtProducer: runtime.TextProducer(), ACLRuntimeDeleteServicesHaproxyRuntimeAclsParentNameEntriesIDHandler: acl_runtime.DeleteServicesHaproxyRuntimeAclsParentNameEntriesIDHandlerFunc(func(params acl_runtime.DeleteServicesHaproxyRuntimeAclsParentNameEntriesIDParams, principal interface{}) middleware.Responder { return middleware.NotImplemented("operation acl_runtime.DeleteServicesHaproxyRuntimeAclsParentNameEntriesID has not yet been implemented") @@ -969,8 +970,8 @@ func NewDataPlaneAPI(spec *loads.Document) *DataPlaneAPI { StorageGetOneStorageSSLCertificateHandler: storage.GetOneStorageSSLCertificateHandlerFunc(func(params storage.GetOneStorageSSLCertificateParams, principal interface{}) middleware.Responder { return middleware.NotImplemented("operation storage.GetOneStorageSSLCertificate has not yet been implemented") }), - SpecificationOpenapiv3GetOpenapiv3SpecificationHandler: specification_openapiv3.GetOpenapiv3SpecificationHandlerFunc(func(params specification_openapiv3.GetOpenapiv3SpecificationParams, principal interface{}) middleware.Responder { - return middleware.NotImplemented("operation specification_openapiv3.GetOpenapiv3Specification has not yet been implemented") + Version3GetOpenapiv3SpecificationHandler: version3.GetOpenapiv3SpecificationHandlerFunc(func(params version3.GetOpenapiv3SpecificationParams, principal interface{}) middleware.Responder { + return middleware.NotImplemented("operation version3.GetOpenapiv3Specification has not yet been implemented") }), PeerEntryGetPeerEntriesHandler: peer_entry.GetPeerEntriesHandlerFunc(func(params peer_entry.GetPeerEntriesParams, principal interface{}) middleware.Responder { return middleware.NotImplemented("operation peer_entry.GetPeerEntries has not yet been implemented") @@ -1506,6 +1507,9 @@ type DataPlaneAPI struct { // JSONProducer registers a producer for the following mime types: // - application/json JSONProducer runtime.Producer + // TxtProducer registers a producer for the following mime types: + // - text/plain + TxtProducer runtime.Producer // BasicAuthAuth registers a function that takes username and password and returns a principal // it performs authentication with basic auth @@ -2080,8 +2084,8 @@ type DataPlaneAPI struct { StorageGetOneStorageMapHandler storage.GetOneStorageMapHandler // StorageGetOneStorageSSLCertificateHandler sets the operation handler for the get one storage s s l certificate operation StorageGetOneStorageSSLCertificateHandler storage.GetOneStorageSSLCertificateHandler - // SpecificationOpenapiv3GetOpenapiv3SpecificationHandler sets the operation handler for the get openapiv3 specification operation - SpecificationOpenapiv3GetOpenapiv3SpecificationHandler specification_openapiv3.GetOpenapiv3SpecificationHandler + // Version3GetOpenapiv3SpecificationHandler sets the operation handler for the get openapiv3 specification operation + Version3GetOpenapiv3SpecificationHandler version3.GetOpenapiv3SpecificationHandler // PeerEntryGetPeerEntriesHandler sets the operation handler for the get peer entries operation PeerEntryGetPeerEntriesHandler peer_entry.GetPeerEntriesHandler // PeerEntryGetPeerEntryHandler sets the operation handler for the get peer entry operation @@ -2487,6 +2491,9 @@ func (o *DataPlaneAPI) Validate() error { if o.JSONProducer == nil { unregistered = append(unregistered, "JSONProducer") } + if o.TxtProducer == nil { + unregistered = append(unregistered, "TxtProducer") + } if o.BasicAuthAuth == nil { unregistered = append(unregistered, "BasicAuthAuth") @@ -3341,8 +3348,8 @@ func (o *DataPlaneAPI) Validate() error { if o.StorageGetOneStorageSSLCertificateHandler == nil { unregistered = append(unregistered, "storage.GetOneStorageSSLCertificateHandler") } - if o.SpecificationOpenapiv3GetOpenapiv3SpecificationHandler == nil { - unregistered = append(unregistered, "specification_openapiv3.GetOpenapiv3SpecificationHandler") + if o.Version3GetOpenapiv3SpecificationHandler == nil { + unregistered = append(unregistered, "version3.GetOpenapiv3SpecificationHandler") } if o.PeerEntryGetPeerEntriesHandler == nil { unregistered = append(unregistered, "peer_entry.GetPeerEntriesHandler") @@ -3886,6 +3893,8 @@ func (o *DataPlaneAPI) ProducersFor(mediaTypes []string) map[string]runtime.Prod result["application/octet-stream"] = o.BinProducer case "application/json": result["application/json"] = o.JSONProducer + case "text/plain": + result["text/plain"] = o.TxtProducer } if p, ok := o.customProducers[mt]; ok { @@ -5061,7 +5070,7 @@ func (o *DataPlaneAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } - o.handlers["GET"]["/specification_openapiv3"] = specification_openapiv3.NewGetOpenapiv3Specification(o.context, o.SpecificationOpenapiv3GetOpenapiv3SpecificationHandler) + o.handlers["GET"]["/specification_openapiv3"] = version3.NewGetOpenapiv3Specification(o.context, o.Version3GetOpenapiv3SpecificationHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } @@ -5743,6 +5752,6 @@ func (o *DataPlaneAPI) AddMiddlewareFor(method, path string, builder middleware. } o.Init() if h, ok := o.handlers[um][path]; ok { - o.handlers[method][path] = builder(h) + o.handlers[um][path] = builder(h) } } diff --git a/operations/stick_table/set_stick_table_entries.go b/operations/stick_table/set_stick_table_entries.go index 4520a2f2..71d0a195 100644 --- a/operations/stick_table/set_stick_table_entries.go +++ b/operations/stick_table/set_stick_table_entries.go @@ -170,6 +170,7 @@ func (o *SetStickTableEntriesBody) ContextValidate(ctx context.Context, formats func (o *SetStickTableEntriesBody) contextValidateDataType(ctx context.Context, formats strfmt.Registry) error { if o.DataType != nil { + if err := o.DataType.ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { return ve.ValidateName("stick_table_entry" + "." + "data_type") diff --git a/operations/storage/replace_storage_general_file_parameters.go b/operations/storage/replace_storage_general_file_parameters.go index 5235a34f..7d0db4c7 100644 --- a/operations/storage/replace_storage_general_file_parameters.go +++ b/operations/storage/replace_storage_general_file_parameters.go @@ -22,6 +22,7 @@ package storage import ( "io" + "mime/multipart" "net/http" "github.com/go-openapi/errors" @@ -31,6 +32,13 @@ import ( "github.com/go-openapi/swag" ) +// ReplaceStorageGeneralFileMaxParseMemory sets the maximum size in bytes for +// the multipart form parser for this operation. +// +// The default value is 32 MB. +// The multipart parser stores up to this + 10MB. +var ReplaceStorageGeneralFileMaxParseMemory int64 = 32 << 20 + // NewReplaceStorageGeneralFileParams creates a new ReplaceStorageGeneralFileParams object // with the default values initialized. func NewReplaceStorageGeneralFileParams() ReplaceStorageGeneralFileParams { @@ -59,11 +67,10 @@ type ReplaceStorageGeneralFileParams struct { // HTTP Request Object HTTPRequest *http.Request `json:"-"` - /* - Required: true - In: body + /*General use file content + In: formData */ - Data string + FileUpload io.ReadCloser /*If set, do a force reload, do not wait for the configured reload-delay. Cannot be used when transaction is specified, as changes in transaction are not applied directly to configuration. In: query Default: false @@ -92,21 +99,23 @@ func (o *ReplaceStorageGeneralFileParams) BindRequest(r *http.Request, route *mi qs := runtime.Values(r.URL.Query()) - if runtime.HasBody(r) { - defer r.Body.Close() - var body string - if err := route.Consumer.Consume(r.Body, &body); err != nil { - if err == io.EOF { - res = append(res, errors.Required("data", "body", "")) - } else { - res = append(res, errors.NewParseError("data", "body", "", err)) - } - } else { - // no validation required on inline body - o.Data = body + if err := r.ParseMultipartForm(ReplaceStorageGeneralFileMaxParseMemory); err != nil { + if err != http.ErrNotMultipart { + return errors.New(400, "%v", err) + } else if err := r.ParseForm(); err != nil { + return errors.New(400, "%v", err) } + } + + fileUpload, fileUploadHeader, err := r.FormFile("file_upload") + if err != nil && err != http.ErrMissingFile { + res = append(res, errors.New(400, "reading file %q failed: %v", "fileUpload", err)) + } else if err == http.ErrMissingFile { + // no-op for missing but optional file parameter + } else if err := o.bindFileUpload(fileUpload, fileUploadHeader); err != nil { + res = append(res, err) } else { - res = append(res, errors.Required("data", "body", "")) + o.FileUpload = &runtime.File{Data: fileUpload, Header: fileUploadHeader} } qForceReload, qhkForceReload, _ := qs.GetOK("force_reload") @@ -129,6 +138,13 @@ func (o *ReplaceStorageGeneralFileParams) BindRequest(r *http.Request, route *mi return nil } +// bindFileUpload binds file parameter FileUpload. +// +// The only supported validations on files are MinLength and MaxLength +func (o *ReplaceStorageGeneralFileParams) bindFileUpload(file multipart.File, header *multipart.FileHeader) error { + return nil +} + // bindForceReload binds and validates parameter ForceReload from query. func (o *ReplaceStorageGeneralFileParams) bindForceReload(rawData []string, hasKey bool, formats strfmt.Registry) error { var raw string diff --git a/operations/specification_openapiv3/get_openapiv3_specification.go b/operations/version3/get_openapiv3_specification.go similarity index 98% rename from operations/specification_openapiv3/get_openapiv3_specification.go rename to operations/version3/get_openapiv3_specification.go index a230b44c..59793459 100644 --- a/operations/specification_openapiv3/get_openapiv3_specification.go +++ b/operations/version3/get_openapiv3_specification.go @@ -15,7 +15,7 @@ // limitations under the License. // -package specification_openapiv3 +package version3 // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the generate command diff --git a/operations/specification_openapiv3/get_openapiv3_specification_parameters.go b/operations/version3/get_openapiv3_specification_parameters.go similarity index 98% rename from operations/specification_openapiv3/get_openapiv3_specification_parameters.go rename to operations/version3/get_openapiv3_specification_parameters.go index 233ae5a3..8910da91 100644 --- a/operations/specification_openapiv3/get_openapiv3_specification_parameters.go +++ b/operations/version3/get_openapiv3_specification_parameters.go @@ -15,7 +15,7 @@ // limitations under the License. // -package specification_openapiv3 +package version3 // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/operations/specification_openapiv3/get_openapiv3_specification_responses.go b/operations/version3/get_openapiv3_specification_responses.go similarity index 99% rename from operations/specification_openapiv3/get_openapiv3_specification_responses.go rename to operations/version3/get_openapiv3_specification_responses.go index 5dd2ac48..012e597c 100644 --- a/operations/specification_openapiv3/get_openapiv3_specification_responses.go +++ b/operations/version3/get_openapiv3_specification_responses.go @@ -15,7 +15,7 @@ // limitations under the License. // -package specification_openapiv3 +package version3 // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/operations/specification_openapiv3/get_openapiv3_specification_urlbuilder.go b/operations/version3/get_openapiv3_specification_urlbuilder.go similarity index 98% rename from operations/specification_openapiv3/get_openapiv3_specification_urlbuilder.go rename to operations/version3/get_openapiv3_specification_urlbuilder.go index b5ae907f..7cb790f7 100644 --- a/operations/specification_openapiv3/get_openapiv3_specification_urlbuilder.go +++ b/operations/version3/get_openapiv3_specification_urlbuilder.go @@ -15,7 +15,7 @@ // limitations under the License. // -package specification_openapiv3 +package version3 // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the generate command diff --git a/server.go b/server.go index 21d19c3b..011b035c 100644 --- a/server.go +++ b/server.go @@ -96,7 +96,7 @@ type Server struct { ListenLimit int `long:"listen-limit" description:"limit the number of outstanding requests"` KeepAlive time.Duration `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"` ReadTimeout time.Duration `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"` - WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"` + WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"30s"` httpServerL net.Listener TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`