diff --git a/cache/cache.go b/cache/cache.go index d422497..0f61eed 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -17,7 +17,7 @@ package cache import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/spf13/viper" ) diff --git a/cmd/main.go b/cmd/main.go index 9c0cdb9..7549555 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,6 +1,6 @@ package main -import "github.com/pufferpanel/apufferi/v3/logging" +import "github.com/pufferpanel/apufferi/v4/logging" func main() { defer logging.Close() diff --git a/cmd/migrate.go b/cmd/migrate.go index 409923f..2812d38 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -3,7 +3,7 @@ package main import ( "encoding/json" "fmt" - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/programs" "github.com/spf13/cobra" diff --git a/cmd/reload.go b/cmd/reload.go index 250a814..2dbf952 100644 --- a/cmd/reload.go +++ b/cmd/reload.go @@ -18,7 +18,7 @@ package main import ( "errors" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/spf13/cobra" "os" "syscall" diff --git a/cmd/root.go b/cmd/root.go index 2f22d8e..6233f66 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,7 +15,7 @@ package main import ( "fmt" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2" "github.com/spf13/cobra" "os" diff --git a/cmd/run.go b/cmd/run.go index 201b8e4..0bd197e 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -19,8 +19,8 @@ package main import ( "fmt" "github.com/braintree/manners" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments" "github.com/pufferpanel/pufferd/v2/programs" diff --git a/cmd/shutdown.go b/cmd/shutdown.go index 17f7d63..68d2038 100644 --- a/cmd/shutdown.go +++ b/cmd/shutdown.go @@ -18,7 +18,7 @@ package main import ( "errors" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/spf13/cobra" "os" "syscall" diff --git a/commons/close.go b/commons/close.go index 46c0832..d8fba03 100644 --- a/commons/close.go +++ b/commons/close.go @@ -17,7 +17,7 @@ package commons import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "net/http" ) diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..caa1add --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,141 @@ +// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// This file was generated by swaggo/swag at +// 2019-10-22 13:48:36.6271935 -0500 CDT m=+3.760001801 + +package docs + +import ( + "bytes" + "encoding/json" + "strings" + + "github.com/alecthomas/template" + "github.com/swaggo/swag" +) + +var doc = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{.Description}}", + "title": "{{.Title}}", + "contact": { + "name": "PufferPanel", + "url": "https://pufferpanel.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/server/{id}": { + "post": { + "description": "Starts the given server", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Starts server", + "parameters": [ + { + "type": "string", + "description": "Server Identifier", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": {}, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/response.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Error" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Error" + } + } + } + } + } + }, + "definitions": { + "response.Error": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } +}` + +type swaggerInfo struct { + Version string + Host string + BasePath string + Schemes []string + Title string + Description string +} + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = swaggerInfo{ + Version: "2.0", + Host: "", + BasePath: "", + Schemes: []string{}, + Title: "Pufferd API", + Description: "PufferPanel daemon service", +} + +type s struct{} + +func (s *s) ReadDoc() string { + sInfo := SwaggerInfo + sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1) + + t, err := template.New("swagger_info").Funcs(template.FuncMap{ + "marshal": func(v interface{}) string { + a, _ := json.Marshal(v) + return string(a) + }, + }).Parse(doc) + if err != nil { + return doc + } + + var tpl bytes.Buffer + if err := t.Execute(&tpl, sInfo); err != nil { + return doc + } + + return tpl.String() +} + +func init() { + swag.Register(swag.Name, &s{}) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..afa3aea --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,76 @@ +{ + "swagger": "2.0", + "info": { + "description": "PufferPanel daemon service", + "title": "Pufferd API", + "contact": { + "name": "PufferPanel", + "url": "https://pufferpanel.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "2.0" + }, + "paths": { + "/server/{id}": { + "post": { + "description": "Starts the given server", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Starts server", + "parameters": [ + { + "type": "string", + "description": "Server Identifier", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": {}, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/response.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Error" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Error" + } + } + } + } + } + }, + "definitions": { + "response.Error": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..bf3140d --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,50 @@ +definitions: + response.Error: + properties: + error: + type: string + type: object +info: + contact: + name: PufferPanel + url: https://pufferpanel.com + description: PufferPanel daemon service + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + title: Pufferd API + version: "2.0" +paths: + /server/{id}: + post: + consumes: + - application/json + description: Starts the given server + parameters: + - description: Server Identifier + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": {} + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.Error' + "403": + description: Forbidden + schema: + $ref: '#/definitions/response.Error' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Error' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Error' + summary: Starts server +swagger: "2.0" diff --git a/environments/download.go b/environments/download.go index dea7c4f..8bd69cb 100644 --- a/environments/download.go +++ b/environments/download.go @@ -19,8 +19,8 @@ package environments import ( "crypto/sha1" "fmt" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/commons" "github.com/pufferpanel/pufferd/v2/environments/envs" "github.com/spf13/viper" diff --git a/environments/environmentloader.go b/environments/environmentloader.go index 037f348..f78fc62 100644 --- a/environments/environmentloader.go +++ b/environments/environmentloader.go @@ -19,7 +19,7 @@ package environments import ( "fmt" "github.com/pkg/errors" - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/cache" "github.com/pufferpanel/pufferd/v2/environments/envs" "github.com/pufferpanel/pufferd/v2/environments/impl/docker" diff --git a/environments/envs/environment.go b/environments/envs/environment.go index 718e334..80512d7 100644 --- a/environments/envs/environment.go +++ b/environments/envs/environment.go @@ -19,7 +19,8 @@ package envs import ( "fmt" "github.com/gorilla/websocket" - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/utils" "github.com/spf13/viper" "io" @@ -62,7 +63,7 @@ type Environment interface { AddListener(ws *websocket.Conn) - GetStats() (map[string]interface{}, error) + GetStats() (*pufferd.ServerStats, error) DisplayToConsole(msg string, data ...interface{}) diff --git a/environments/impl/docker/docker.go b/environments/impl/docker/docker.go index 50046dd..2b5b45d 100644 --- a/environments/impl/docker/docker.go +++ b/environments/impl/docker/docker.go @@ -27,10 +27,10 @@ import ( "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/client" "github.com/docker/go-connections/nat" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments/envs" - "github.com/pufferpanel/pufferd/v2/errors" "io" "io/ioutil" "os" @@ -59,13 +59,13 @@ func (d *docker) dockerExecuteAsync(cmd string, args []string, env map[string]st return err } if running { - return errors.ErrContainerRunning + return pufferd.ErrContainerRunning } d.Wait.Wait() if d.downloadingImage { - return errors.ErrImageDownloading + return pufferd.ErrImageDownloading } dockerClient, err := d.getClient() @@ -131,7 +131,7 @@ func (d *docker) ExecuteInMainProcess(cmd string) (err error) { return } if !running { - err = errors.ErrServerOffline + err = pufferd.ErrServerOffline return } @@ -194,14 +194,14 @@ func (d *docker) IsRunning() (bool, error) { return stats.State.Running, nil } -func (d *docker) GetStats() (map[string]interface{}, error) { +func (d *docker) GetStats() (*pufferd.ServerStats, error) { running, err := d.IsRunning() if err != nil { return nil, err } if !running { - return nil, errors.ErrServerOffline + return nil, pufferd.ErrServerOffline } dockerClient, err := d.getClient() @@ -226,11 +226,11 @@ func (d *docker) GetStats() (map[string]interface{}, error) { if err != nil { return nil, err } - resultMap := make(map[string]interface{}) - resultMap["memory"] = calculateMemoryPercent(data) - resultMap["cpu"] = calculateCPUPercent(data) - return resultMap, nil + return &pufferd.ServerStats{ + Memory: calculateMemoryPercent(data), + Cpu: calculateCPUPercent(data), + }, nil } func (d *docker) WaitForMainProcess() error { diff --git a/environments/impl/docker/factory.go b/environments/impl/docker/factory.go index 7370b22..3fda42d 100644 --- a/environments/impl/docker/factory.go +++ b/environments/impl/docker/factory.go @@ -17,7 +17,7 @@ package docker import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/environments/envs" ) diff --git a/environments/impl/lxd/factory.go b/environments/impl/lxd/factory.go index 304adc8..ea16643 100644 --- a/environments/impl/lxd/factory.go +++ b/environments/impl/lxd/factory.go @@ -17,7 +17,7 @@ package lxd import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/environments/envs" "github.com/pufferpanel/pufferd/v2/utils" "sync" diff --git a/environments/impl/lxd/lxd.go b/environments/impl/lxd/lxd.go index d6beff5..855e174 100644 --- a/environments/impl/lxd/lxd.go +++ b/environments/impl/lxd/lxd.go @@ -20,10 +20,10 @@ import ( "github.com/docker/docker/pkg/ioutils" client "github.com/lxc/lxd/client" "github.com/lxc/lxd/shared/api" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments/envs" - "github.com/pufferpanel/pufferd/v2/errors" "io" "os" "sync" @@ -50,7 +50,7 @@ func (l *lxc) executeAsync(cmd string, args []string, env map[string]string, cal return err } if running { - return errors.ErrContainerRunning + return pufferd.ErrContainerRunning } //send an exec @@ -167,7 +167,7 @@ func (l *lxc) ExecuteInMainProcess(cmd string) (err error) { return } if !running { - err = errors.ErrServerOffline + err = pufferd.ErrServerOffline return } @@ -204,10 +204,10 @@ func (l *lxc) Create() error { return err } -func (l *lxc) GetStats() (map[string]interface{}, error) { - return map[string]interface{}{ - "cpu": 0, - "memory": 0, +func (l *lxc) GetStats() (*pufferd.ServerStats, error) { + return &pufferd.ServerStats{ + Cpu: 0, + Memory: 0, }, nil } diff --git a/environments/impl/standard/standard.go b/environments/impl/standard/standard.go index accaa5d..12a984a 100644 --- a/environments/impl/standard/standard.go +++ b/environments/impl/standard/standard.go @@ -17,7 +17,9 @@ package standard import ( + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments/envs" + "github.com/spf13/cast" "io" "os" "os/exec" @@ -26,8 +28,7 @@ import ( "time" "fmt" - "github.com/pufferpanel/apufferi/v3/logging" - "github.com/pufferpanel/pufferd/v2/errors" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/shirou/gopsutil/process" "strings" ) @@ -44,7 +45,7 @@ func (s *standard) standardExecuteAsync(cmd string, args []string, env map[strin return } if running { - err = errors.ErrProcessRunning + err = pufferd.ErrProcessRunning return } s.Wait.Wait() @@ -81,7 +82,7 @@ func (s *standard) ExecuteInMainProcess(cmd string) (err error) { return err } if !running { - err = errors.ErrServerOffline + err = pufferd.ErrServerOffline return } stdIn := s.stdInWriter @@ -113,24 +114,26 @@ func (s *standard) IsRunning() (isRunning bool, err error) { return } -func (s *standard) GetStats() (map[string]interface{}, error) { +func (s *standard) GetStats() (*pufferd.ServerStats, error) { running, err := s.IsRunning() if err != nil { return nil, err } if !running { - return nil, errors.ErrServerOffline + return nil, pufferd.ErrServerOffline } pr, err := process.NewProcess(int32(s.mainProcess.Process.Pid)) if err != nil { return nil, err } - resultMap := make(map[string]interface{}) + memMap, _ := pr.MemoryInfo() - resultMap["memory"] = memMap.RSS cpu, _ := pr.Percent(time.Second * 1) - resultMap["cpu"] = cpu - return resultMap, nil + + return &pufferd.ServerStats{ + Cpu: cpu, + Memory: cast.ToFloat64(memMap.RSS), + }, nil } func (s *standard) Create() error { diff --git a/environments/impl/standard/standardfactory.go b/environments/impl/standard/standardfactory.go index d12c6ce..b9826a8 100644 --- a/environments/impl/standard/standardfactory.go +++ b/environments/impl/standard/standardfactory.go @@ -17,7 +17,7 @@ package standard import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/environments/envs" ) diff --git a/environments/impl/tty/tty.go b/environments/impl/tty/tty.go index 30d9199..47de72b 100644 --- a/environments/impl/tty/tty.go +++ b/environments/impl/tty/tty.go @@ -21,10 +21,11 @@ package tty import ( "fmt" "github.com/creack/pty" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments/envs" - "github.com/pufferpanel/pufferd/v2/errors" "github.com/shirou/gopsutil/process" + "github.com/spf13/cast" "io" "os" "os/exec" @@ -45,7 +46,7 @@ func (t *tty) ttyExecuteAsync(cmd string, args []string, env map[string]string, return } if running { - err = errors.ErrProcessRunning + err = pufferd.ErrProcessRunning return } t.Wait.Wait() @@ -83,7 +84,7 @@ func (t *tty) ExecuteInMainProcess(cmd string) (err error) { return err } if !running { - err = errors.ErrServerOffline + err = pufferd.ErrServerOffline return } stdIn := t.stdInWriter @@ -115,24 +116,26 @@ func (t *tty) IsRunning() (isRunning bool, err error) { return } -func (t *tty) GetStats() (map[string]interface{}, error) { +func (t *tty) GetStats() (*pufferd.ServerStats, error) { running, err := t.IsRunning() if err != nil { return nil, err } if !running { - return nil, errors.ErrServerOffline + return nil, pufferd.ErrServerOffline } pr, err := process.NewProcess(int32(t.mainProcess.Process.Pid)) if err != nil { return nil, err } - resultMap := make(map[string]interface{}) + memMap, _ := pr.MemoryInfo() - resultMap["memory"] = memMap.RSS - cpu, _ := pr.Percent(time.Millisecond * 50) - resultMap["cpu"] = cpu - return resultMap, nil + cpu, _ := pr.Percent(time.Second * 1) + + return &pufferd.ServerStats{ + Cpu: cpu, + Memory: cast.ToFloat64(memMap.RSS), + }, nil } func (t *tty) Create() error { diff --git a/environments/impl/tty/ttyfactory.go b/environments/impl/tty/ttyfactory.go index 61956b7..90c4450 100644 --- a/environments/impl/tty/ttyfactory.go +++ b/environments/impl/tty/ttyfactory.go @@ -19,7 +19,7 @@ package tty import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/environments/envs" ) diff --git a/errors/errors.go b/errors.go similarity index 51% rename from errors/errors.go rename to errors.go index 288a8c7..4410a56 100644 --- a/errors/errors.go +++ b/errors.go @@ -14,9 +14,12 @@ limitations under the License. */ -package errors +package pufferd -import "github.com/pufferpanel/apufferi/v3" +import ( + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/scope" +) var ErrServerOffline = apufferi.CreateError("server offline", "ErrServerOffline") var ErrIllegalFileAccess = apufferi.CreateError("invalid file access", "ErrIllegalFileAccess") @@ -24,4 +27,16 @@ var ErrServerDisabled = apufferi.CreateError("server is disabled", "ErrServerDis var ErrContainerRunning = apufferi.CreateError("container already running", "ErrContainerRunning") var ErrImageDownloading = apufferi.CreateError("image downloading", "ErrImageDownloading") var ErrProcessRunning = apufferi.CreateError("process already running", "ErrProcessRunning") -var ErrMissingFactory = apufferi.CreateError("missing factory", "ErrMissingFactory") \ No newline at end of file +var ErrMissingFactory = apufferi.CreateError("missing factory", "ErrMissingFactory") +var ErrServerAlreadyExists = apufferi.CreateError("server already exists", "ErrServerAlreadyExists") +var ErrInvalidUnixTime = apufferi.CreateError("time provided is not a valid UNIX time", "ErrInvalidUnixTime") +var ErrKeyNotPEM = apufferi.CreateError("key is not in PEM format", "ErrKeyNotPEM") +var ErrCannotValidateToken = apufferi.CreateError("could not validate access token", "ErrCannotValidateToken") +var ErrMissingAccessToken = apufferi.CreateError("access token not provided", "ErrMissingAccessToken") +var ErrNotBearerToken = apufferi.CreateError("access token must be a Bearer token", "ErrNotBearerToken") +var ErrKeyNotECDSA = apufferi.CreateError("key is not ECDSA key", "ErrKeyNotECDSA") +var ErrMissingScope = apufferi.CreateError("missing scope", "ErrMissingScope") + +func CreateErrMissingScope(scope scope.Scope) *apufferi.Error { + return apufferi.CreateError(ErrMissingScope.Message, ErrMissingScope.Code).Metadata(map[string]interface{}{"scope": scope}) +} diff --git a/go.mod b/go.mod index b81d591..2733055 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.12 require ( github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc github.com/braintree/manners v0.0.0-20150503212558-0b5e6b2c2843 github.com/cavaliercoder/grab v2.0.0+incompatible github.com/containerd/containerd v1.2.9 // indirect @@ -32,13 +33,16 @@ require ( github.com/opencontainers/image-spec v1.0.1 // indirect github.com/pkg/errors v0.8.1 github.com/pkg/sftp v1.10.1 - github.com/pufferpanel/apufferi/v3 v3.0.5 + github.com/pufferpanel/apufferi/v4 v4.0.0 github.com/rogpeppe/fastuuid v1.2.0 // indirect github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada github.com/spf13/cast v1.3.0 github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.3.2 + github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 + github.com/swaggo/gin-swagger v1.2.0 + github.com/swaggo/swag v1.5.1 golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect diff --git a/go.sum b/go.sum index 317a0f1..ab34af3 100644 --- a/go.sum +++ b/go.sum @@ -10,11 +10,16 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -75,9 +80,14 @@ github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHs github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= +github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= +github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= @@ -88,6 +98,15 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk= +github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= +github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -137,6 +156,7 @@ github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -182,8 +202,12 @@ github.com/lxc/lxd v0.0.0-20191002163551-3a5f63bc4959 h1:J51caJCJvL7bo/xc1iqTFAT github.com/lxc/lxd v0.0.0-20191002163551-3a5f63bc4959/go.mod h1:2BaZflfwsv8a3uy3/Vw+de4Avn4DSrAiqaHJjCIXMV4= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= @@ -235,8 +259,7 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/pufferpanel/apufferi/v3 v3.0.5 h1:qqejvBD+QpWnfObijPuMP7vvlfShKJP9H3NImkwbyTw= -github.com/pufferpanel/apufferi/v3 v3.0.5/go.mod h1:/qrb/CZrSynDC4kSXz5CE7i5gXrLIpy6NXwqBm5ApKc= +github.com/pufferpanel/apufferi/v4 v4.0.0/go.mod h1:Od0kznHFPfEh2hV77oTOWHebTvBwdjrnwe6AWjfXMPU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -272,12 +295,22 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= +github.com/swaggo/gin-swagger v1.2.0 h1:YskZXEiv51fjOMTsXrOetAjrMDfFaXD79PEoQBOe2W0= +github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI= +github.com/swaggo/swag v1.5.1 h1:2Agm8I4K5qb00620mHq0VJ05/KT4FtmALPIcQR9lEZM= +github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= @@ -300,13 +333,16 @@ golang.org/x/net v0.0.0-20150829230318-ea47fc708ee3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -324,12 +360,14 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -337,10 +375,13 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -350,6 +391,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b h1:/mJ+GKieZA6hFDQGdWZrjj4AXPl5ylY+5HusG80roy0= +golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/httphandlers/oauth2.go b/httphandlers/oauth2.go index b9171d2..58ba797 100644 --- a/httphandlers/oauth2.go +++ b/httphandlers/oauth2.go @@ -21,42 +21,39 @@ import ( "crypto/ecdsa" "crypto/x509" "encoding/pem" - "errors" - "fmt" "github.com/gin-gonic/gin" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" - "github.com/pufferpanel/apufferi/v3/response" - "github.com/pufferpanel/apufferi/v3/scope" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/response" + "github.com/pufferpanel/apufferi/v4/scope" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/programs" "github.com/spf13/viper" "io" + "net/http" "os" "strings" ) func OAuth2Handler(requiredScope scope.Scope, requireServer bool) gin.HandlerFunc { - return func(gin *gin.Context) { + return func(c *gin.Context) { failure := true defer func() { - if failure && !gin.IsAborted() { - gin.Abort() + if failure && !c.IsAborted() { + c.Abort() } }() - authHeader := gin.Request.Header.Get("Authorization") + authHeader := c.Request.Header.Get("Authorization") var authToken string if authHeader == "" { - authToken = gin.Query("accessToken") + authToken = c.Query("accessToken") if authToken == "" { - response.Respond(gin).Fail().Status(400).Message("no access token provided").Send() - gin.Abort() + response.HandleError(c, pufferd.ErrMissingAccessToken, http.StatusBadRequest) return } } else { authArr := strings.SplitN(authHeader, " ", 2) if len(authArr) < 2 || authArr[0] != "Bearer" { - response.Respond(gin).Fail().Status(400).Message("invalid access token format").Send() - gin.Abort() + response.HandleError(c, pufferd.ErrNotBearerToken, http.StatusBadRequest) return } authToken = authArr[1] @@ -64,9 +61,7 @@ func OAuth2Handler(requiredScope scope.Scope, requireServer bool) gin.HandlerFun f, err := os.OpenFile(viper.GetString("auth.publicKey"), os.O_RDONLY, 660) defer apufferi.Close(f) - if err != nil { - logging.Exception("Error handling oauth2 validation", err) - response.Respond(gin).Fail().Status(500).Message("error validating access token").Send() + if response.HandleError(c, err, http.StatusInternalServerError) { return } @@ -76,32 +71,26 @@ func OAuth2Handler(requiredScope scope.Scope, requireServer bool) gin.HandlerFun block, _ := pem.Decode(buf.Bytes()) if block == nil { - logging.Exception("Error handling oauth2 validation", errors.New("public key is not in PEM format")) - response.Respond(gin).Fail().Status(500).Message("error validating access token").Send() + response.HandleError(c, pufferd.ErrKeyNotPEM, http.StatusInternalServerError) return } pub, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - logging.Exception("Error handling oauth2 validation", err) - response.Respond(gin).Fail().Status(500).Message("error validating access token").Send() + if response.HandleError(c, err, http.StatusInternalServerError) { return } pubKey, ok := pub.(*ecdsa.PublicKey) if !ok { - logging.Exception("Error handling oauth2 validation", err) - response.Respond(gin).Fail().Status(500).Message("error validating access token").Send() + response.HandleError(c, pufferd.ErrKeyNotECDSA, http.StatusInternalServerError) return } token, err := apufferi.ParseToken(pubKey, authToken) - if err != nil { - logging.Exception("Error handling oauth2 validation", err) - response.Respond(gin).Fail().Status(403).Message("invalid access").Send() + if response.HandleError(c, err, http.StatusForbidden) { return } - serverId := gin.Param("id") + serverId := c.Param("id") scopes := make([]scope.Scope, 0) if token.Claims.PanelClaims.Scopes[serverId] != nil { scopes = append(scopes, token.Claims.PanelClaims.Scopes[serverId]...) @@ -111,21 +100,21 @@ func OAuth2Handler(requiredScope scope.Scope, requireServer bool) gin.HandlerFun } if !apufferi.ContainsScope(scopes, requiredScope) { - response.Respond(gin).Fail().Status(403).Message(fmt.Sprintf("missing scope %s", requiredScope)).Send() + response.HandleError(c, pufferd.CreateErrMissingScope(requiredScope), http.StatusForbidden) return } if requireServer { program, _ := programs.Get(serverId) if program == nil { - response.Respond(gin).Fail().Status(404).Message("no server with id " + serverId).Send() + c.AbortWithStatus(http.StatusNotFound) return } - gin.Set("server", program) + c.Set("server", program) } - gin.Set("scopes", scopes) + c.Set("scopes", scopes) failure = false } diff --git a/httpmodels.go b/httpmodels.go new file mode 100644 index 0000000..a021e04 --- /dev/null +++ b/httpmodels.go @@ -0,0 +1,33 @@ +package pufferd + +import "github.com/pufferpanel/apufferi/v4" + +type ServerIdResponse struct { + Id string `json:"id"` +} + +type ServerStats struct { + Cpu float64 `json:"cpu"` + Memory float64 `json:"memory"` +} + +type ServerLogs struct { + Epoch int64 `json:"epoch"` + Logs string `json:"logs"` +} + +type ServerRunning struct { + Running bool `json:"running"` +} + +type ServerData struct { + Variables map[string]apufferi.Variable `json:"data"` +} + +type ServerDataAdmin struct { + *apufferi.Server +} + +type PufferdRunning struct { + Message string `json:"message"` +} diff --git a/oauth2/shared.go b/oauth2/shared.go index 75203a0..eaeeb9f 100644 --- a/oauth2/shared.go +++ b/oauth2/shared.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/json" "errors" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/commons" "github.com/spf13/viper" "net/http" diff --git a/oauth2/ssh.go b/oauth2/ssh.go index 5172cd3..dcbec7f 100644 --- a/oauth2/ssh.go +++ b/oauth2/ssh.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/json" "errors" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/commons" "github.com/spf13/viper" "golang.org/x/crypto/ssh" diff --git a/programs/loader.go b/programs/loader.go index 74c550b..113477d 100644 --- a/programs/loader.go +++ b/programs/loader.go @@ -26,8 +26,8 @@ import ( "path/filepath" "strings" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/environments" "github.com/pufferpanel/pufferd/v2/programs/operations" ) diff --git a/programs/operations/impl/command/command.go b/programs/operations/impl/command/command.go index 5990bd9..e1b1c4c 100644 --- a/programs/operations/impl/command/command.go +++ b/programs/operations/impl/command/command.go @@ -21,7 +21,7 @@ import ( "strings" "fmt" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" ) type Command struct { diff --git a/programs/operations/impl/download/download.go b/programs/operations/impl/download/download.go index dcd4c1c..a32aeaa 100644 --- a/programs/operations/impl/download/download.go +++ b/programs/operations/impl/download/download.go @@ -18,7 +18,7 @@ package download import ( "github.com/cavaliercoder/grab" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/environments/envs" ) diff --git a/programs/operations/impl/forgedl/forgedl.go b/programs/operations/impl/forgedl/forgedl.go index 6cf17af..91ca0d4 100644 --- a/programs/operations/impl/forgedl/forgedl.go +++ b/programs/operations/impl/forgedl/forgedl.go @@ -17,7 +17,7 @@ package forgedl import ( - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/environments" "github.com/pufferpanel/pufferd/v2/environments/envs" "path" diff --git a/programs/operations/impl/mkdir/mkdir.go b/programs/operations/impl/mkdir/mkdir.go index f2dfe5a..ec2d92c 100644 --- a/programs/operations/impl/mkdir/mkdir.go +++ b/programs/operations/impl/mkdir/mkdir.go @@ -20,8 +20,8 @@ import ( "github.com/pufferpanel/pufferd/v2/environments/envs" "os" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" ) type Mkdir struct { diff --git a/programs/operations/impl/mojangdl/mojangdl.go b/programs/operations/impl/mojangdl/mojangdl.go index ef67995..af68235 100644 --- a/programs/operations/impl/mojangdl/mojangdl.go +++ b/programs/operations/impl/mojangdl/mojangdl.go @@ -20,7 +20,7 @@ import ( "encoding/json" "errors" "fmt" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/commons" "github.com/pufferpanel/pufferd/v2/environments" "github.com/pufferpanel/pufferd/v2/environments/envs" diff --git a/programs/operations/impl/move/move.go b/programs/operations/impl/move/move.go index ad04ac8..2c46366 100644 --- a/programs/operations/impl/move/move.go +++ b/programs/operations/impl/move/move.go @@ -21,8 +21,8 @@ import ( "os" "path/filepath" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" ) type Move struct { diff --git a/programs/operations/impl/spongeforgedl/spongeforgedl.go b/programs/operations/impl/spongeforgedl/spongeforgedl.go index 5390d8a..0f62919 100644 --- a/programs/operations/impl/spongeforgedl/spongeforgedl.go +++ b/programs/operations/impl/spongeforgedl/spongeforgedl.go @@ -19,7 +19,7 @@ package spongeforgedl import ( "encoding/json" "errors" - "github.com/pufferpanel/apufferi/v3" + "github.com/pufferpanel/apufferi/v4" "github.com/pufferpanel/pufferd/v2/commons" "github.com/pufferpanel/pufferd/v2/environments" "github.com/pufferpanel/pufferd/v2/environments/envs" diff --git a/programs/operations/impl/writefile/writefile.go b/programs/operations/impl/writefile/writefile.go index d1b2d4d..aa1b78d 100644 --- a/programs/operations/impl/writefile/writefile.go +++ b/programs/operations/impl/writefile/writefile.go @@ -20,8 +20,8 @@ import ( "github.com/pufferpanel/pufferd/v2/environments/envs" "io/ioutil" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" ) type WriteFile struct { diff --git a/programs/operations/operationprocess.go b/programs/operations/operationprocess.go index eb66f05..db97385 100644 --- a/programs/operations/operationprocess.go +++ b/programs/operations/operationprocess.go @@ -17,10 +17,10 @@ package operations import ( - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments/envs" - "github.com/pufferpanel/pufferd/v2/errors" "github.com/pufferpanel/pufferd/v2/programs/operations/impl/command" "github.com/pufferpanel/pufferd/v2/programs/operations/impl/download" "github.com/pufferpanel/pufferd/v2/programs/operations/impl/forgedl" @@ -56,7 +56,7 @@ func GenerateProcess(directions []apufferi.TypeWithMetadata, environment envs.En factory := commandMapping[mapping.Type] if factory == nil { - return OperationProcess{}, errors.ErrMissingFactory + return OperationProcess{}, pufferd.ErrMissingFactory } mapCopy := make(map[string]interface{}, 0) diff --git a/programs/operations/operationprocess_linux.go b/programs/operations/operationprocess_linux.go index 1223eb9..2edf89d 100644 --- a/programs/operations/operationprocess_linux.go +++ b/programs/operations/operationprocess_linux.go @@ -24,7 +24,7 @@ import ( "plugin" "reflect" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/programs/operations/ops" ) diff --git a/programs/program.go b/programs/program.go index 86f60c7..7bce04f 100644 --- a/programs/program.go +++ b/programs/program.go @@ -19,10 +19,10 @@ package programs import ( "container/list" "encoding/json" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/environments/envs" - "github.com/pufferpanel/pufferd/v2/errors" "github.com/pufferpanel/pufferd/v2/messages" "github.com/pufferpanel/pufferd/v2/programs/operations" "github.com/spf13/viper" @@ -138,7 +138,7 @@ func CreateProgram() *Program { func (p *Program) Start() (err error) { if !p.IsEnabled() { logging.Error("Server %s is not enabled, cannot start", p.Id()) - return errors.ErrServerDisabled + return pufferd.ErrServerDisabled } if running, err := p.IsRunning(); running || err != nil { return err @@ -168,7 +168,7 @@ func (p *Program) Start() (err error) { err = p.Environment.ExecuteAsync(p.Execution.ProgramName, apufferi.ReplaceTokensInArr(p.Execution.Arguments, data), apufferi.ReplaceTokensInMap(p.Execution.EnvironmentVariables, data), p.afterExit) if err != nil { - logging.Exception("error starting server " + p.Id(), err) + logging.Exception("error starting server "+p.Id(), err) p.Environment.DisplayToConsole("Failed to start server\n") } @@ -242,7 +242,7 @@ func (p *Program) Destroy() (err error) { func (p *Program) Install() (err error) { if !p.IsEnabled() { logging.Error("Server %s is not enabled, cannot install", p.Id()) - return errors.ErrServerDisabled + return pufferd.ErrServerDisabled } logging.Debug("Installing server %s", p.Id()) @@ -347,20 +347,21 @@ func (p *Program) Save(file string) (err error) { return } -func (p *Program) Edit(data map[string]interface{}, overrideUser bool) (err error) { +func (p *Program) Edit(data map[string]apufferi.Variable, overrideUser bool) (err error) { for k, v := range data { var elem apufferi.Variable if _, ok := p.Variables[k]; ok { elem = p.Variables[k] } else { - elem = apufferi.Variable{} + //copy from provided + elem = v } if !elem.UserEditable && !overrideUser { continue } - elem.Value = v + elem.Value = v.Value p.Variables[k] = elem } @@ -441,7 +442,7 @@ func (p *Program) afterExit(graceful bool) { func (p *Program) GetItem(name string) (*FileData, error) { targetFile := apufferi.JoinPath(p.GetEnvironment().GetRootDirectory(), name) if !apufferi.EnsureAccess(targetFile, p.GetEnvironment().GetRootDirectory()) { - return nil, errors.ErrIllegalFileAccess + return nil, pufferd.ErrIllegalFileAccess } info, err := os.Stat(targetFile) @@ -497,7 +498,7 @@ func (p *Program) CreateFolder(name string) error { folder := apufferi.JoinPath(p.GetEnvironment().GetRootDirectory(), name) if !apufferi.EnsureAccess(folder, p.GetEnvironment().GetRootDirectory()) { - return errors.ErrIllegalFileAccess + return pufferd.ErrIllegalFileAccess } return os.Mkdir(folder, 0755) } @@ -506,7 +507,7 @@ func (p *Program) OpenFile(name string) (io.WriteCloser, error) { targetFile := apufferi.JoinPath(p.GetEnvironment().GetRootDirectory(), name) if !apufferi.EnsureAccess(targetFile, p.GetEnvironment().GetRootDirectory()) { - return nil, errors.ErrIllegalFileAccess + return nil, pufferd.ErrIllegalFileAccess } file, err := os.Create(targetFile) @@ -517,7 +518,7 @@ func (p *Program) DeleteItem(name string) error { targetFile := apufferi.JoinPath(p.GetEnvironment().GetRootDirectory(), name) if !apufferi.EnsureAccess(targetFile, p.GetEnvironment().GetRootDirectory()) { - return errors.ErrIllegalFileAccess + return pufferd.ErrIllegalFileAccess } return os.RemoveAll(targetFile) diff --git a/routing/root.go b/routing/root.go index e28432e..0e52b24 100644 --- a/routing/root.go +++ b/routing/root.go @@ -18,14 +18,25 @@ package routing import ( "github.com/gin-gonic/gin" - "github.com/pufferpanel/apufferi/v3/logging" - "github.com/pufferpanel/apufferi/v3/middleware" - "github.com/pufferpanel/apufferi/v3/response" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/apufferi/v4/middleware" + "github.com/pufferpanel/apufferi/v4/response" + "github.com/pufferpanel/pufferd/v2" + _ "github.com/pufferpanel/pufferd/v2/docs" "github.com/pufferpanel/pufferd/v2/oauth2" "github.com/pufferpanel/pufferd/v2/routing/server" - "github.com/pufferpanel/pufferd/v2/shutdown" + "github.com/swaggo/files" + "github.com/swaggo/gin-swagger" + "strings" ) +// @title Pufferd API +// @version 2.0 +// @description PufferPanel daemon service +// @contact.name PufferPanel +// @contact.url https://pufferpanel.com +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html func ConfigureWeb() *gin.Engine { r := gin.New() { @@ -35,10 +46,14 @@ func ConfigureWeb() *gin.Engine { if c.GetHeader("Connection") == "Upgrade" { return } + if strings.HasPrefix(c.Request.URL.Path, "/swagger/") { + return + } middleware.ResponseAndRecover(c) }) RegisterRoutes(r) server.RegisterRoutes(r) + r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) } oauth2.RefreshToken() @@ -48,15 +63,10 @@ func ConfigureWeb() *gin.Engine { func RegisterRoutes(e *gin.Engine) { e.GET("", func(c *gin.Context) { - response.From(c).Message("pufferd is running") + c.JSON(200, &pufferd.PufferdRunning{Message: "pufferd is running"}) }) e.HEAD("", func(c *gin.Context) { c.Status(200) }) - //e.GET("/_shutdown", httphandlers.OAuth2Handler("node.stop", false), Shutdown) -} - -func Shutdown(c *gin.Context) { - response.From(c).Message("shutting down") - go shutdown.CompleteShutdown() + e.Handle("OPTIONS", "", response.CreateOptions("GET", "HEAD")) } diff --git a/routing/server/server.go b/routing/server/server.go index 51cb3fd..73d97f4 100644 --- a/routing/server/server.go +++ b/routing/server/server.go @@ -18,33 +18,33 @@ package server import ( "encoding/json" + "errors" "fmt" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/itsjamie/gin-cors" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" - "github.com/pufferpanel/apufferi/v3/response" - "github.com/pufferpanel/apufferi/v3/scope" - "github.com/pufferpanel/pufferd/v2/errors" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/apufferi/v4/response" + "github.com/pufferpanel/apufferi/v4/scope" + "github.com/pufferpanel/pufferd/v2" "github.com/pufferpanel/pufferd/v2/httphandlers" + "github.com/pufferpanel/pufferd/v2/messages" "github.com/pufferpanel/pufferd/v2/programs" + "github.com/satori/go.uuid" + "github.com/spf13/cast" "io" "io/ioutil" "mime" - gohttp "net/http" + "net/http" "os" "path/filepath" - "strconv" - - "github.com/pufferpanel/pufferd/v2/messages" - "github.com/satori/go.uuid" ) var wsupgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, - CheckOrigin: func(r *gohttp.Request) bool { + CheckOrigin: func(r *http.Request) bool { return true }, } @@ -99,16 +99,26 @@ func RegisterRoutes(e *gin.Engine) { l.POST("", httphandlers.OAuth2Handler(scope.ServersCreate, false), CreateServer) } +// StartServer godoc +// @Summary Starts server +// @Description Starts the given server +// @Accept json +// @Produce json +// @Success 200 +// @Failure 400 {object} response.Error +// @Failure 403 {object} response.Error +// @Failure 404 {object} response.Error +// @Failure 500 {object} response.Error +// @Param id path string true "Server Identifier" +// @securitydefinitions.oauth2.application OAuth2Application +// @scope.server.start +// @Router /server/{id} [post] func StartServer(c *gin.Context) { item, _ := c.Get("server") server := item.(*programs.Program) err := server.Start() - if err != nil { - response.From(c).Status(500).Data(err).Message("error starting server") - } else { - response.From(c) - } + response.HandleError(c, err, http.StatusInternalServerError) } func StopServer(c *gin.Context) { @@ -152,7 +162,7 @@ func CreateServer(c *gin.Context) { prg, _ := programs.Get(serverId) if prg != nil { - response.From(c).Status(409).Message("server already exists") + response.HandleError(c, pufferd.ErrServerAlreadyExists, http.StatusConflict) return } @@ -161,7 +171,7 @@ func CreateServer(c *gin.Context) { if err != nil { logging.Exception("error decoding JSON body", err) - response.From(c).Status(400).Message("error parsing json").Data(err) + response.HandleError(c, err, http.StatusBadRequest) return } @@ -170,9 +180,7 @@ func CreateServer(c *gin.Context) { if !programs.Create(prg) { errorConnection(c, nil) } else { - data := make(map[string]interface{}) - data["id"] = serverId - response.From(c).Data(data) + c.JSON(200, &pufferd.ServerIdResponse{Id: serverId}) } } @@ -180,9 +188,7 @@ func DeleteServer(c *gin.Context) { item, _ := c.Get("server") prg := item.(*programs.Program) err := programs.Delete(prg.Id()) - if err != nil { - response.From(c).Status(500).Data(err).Message("error deleting server") - } + response.HandleError(c, err, http.StatusInternalServerError) } func InstallServer(c *gin.Context) { @@ -192,42 +198,36 @@ func InstallServer(c *gin.Context) { go func(p *programs.Program) { _ = p.Install() }(prg) + + c.Status(http.StatusAccepted) } func EditServer(c *gin.Context) { item, _ := c.Get("server") prg := item.(*programs.Program) - data := make(map[string]interface{}, 0) + data := &pufferd.ServerData{} err := json.NewDecoder(c.Request.Body).Decode(&data) - if err != nil { - response.From(c).Status(500).Data(err).Message("error editing server") + if response.HandleError(c, err, http.StatusBadRequest) { return } - err = prg.Edit(data, false) - - if err != nil { - response.From(c).Status(500).Data(err).Message("error editing server") - } + err = prg.Edit(data.Variables, false) + response.HandleError(c, err, http.StatusInternalServerError) } func EditServerAdmin(c *gin.Context) { item, _ := c.Get("server") prg := item.(*programs.Program) - data := &admin{} + data := &pufferd.ServerData{} err := json.NewDecoder(c.Request.Body).Decode(&data) - if err != nil { - response.From(c).Status(500).Data(err).Message("error editing server") + if response.HandleError(c, err, http.StatusBadRequest) { return } - err = prg.Edit(data.Data, true) - - if err != nil { - response.From(c).Status(500).Data(err).Message("error editing server") - } + err = prg.Edit(data.Variables, true) + response.HandleError(c, err, http.StatusInternalServerError) } func ReloadServer(c *gin.Context) { @@ -235,9 +235,7 @@ func ReloadServer(c *gin.Context) { prg := item.(*programs.Program) err := programs.Reload(prg.Id()) - if err != nil { - response.From(c).Status(500).Data(err).Message("error reloading server") - } + response.HandleError(c, err, http.StatusInternalServerError) } func GetServer(c *gin.Context) { @@ -245,16 +243,14 @@ func GetServer(c *gin.Context) { server := item.(*programs.Program) data := server.GetData() - result := make(map[string]interface{}, 0) - result["data"] = data - response.From(c).Data(data) + c.JSON(200, &pufferd.ServerData{Variables: data}) } func GetServerAdmin(c *gin.Context) { - item, _ := c.Get("server") + item, _ := c.MustGet("server").(*apufferi.Server) - response.From(c).Data(item) + c.JSON(200, &pufferd.ServerDataAdmin{Server: item}) } func GetFile(c *gin.Context) { @@ -272,19 +268,18 @@ func GetFile(c *gin.Context) { }() if err != nil { - answer := response.From(c).Fail() if os.IsNotExist(err) { - answer.Status(404) - } else if err == errors.ErrIllegalFileAccess { - answer.Status(500).Error(err) + c.AbortWithStatus(404) + } else if err == pufferd.ErrIllegalFileAccess { + response.HandleError(c, err, http.StatusBadRequest) } else { - answer.Status(500).Error(err) + response.HandleError(c, err, http.StatusInternalServerError) } return } if data.FileList != nil { - response.From(c).Data(data.FileList) + c.JSON(200, data.FileList) } else if data.Contents != nil { fileName := filepath.Base(data.Name) @@ -293,11 +288,10 @@ func GetFile(c *gin.Context) { } //discard the built-in response, we cannot use this one at all - response.From(c).Discard() - c.DataFromReader(gohttp.StatusOK, data.ContentLength, "application/octet-stream", data.Contents, extraHeaders) + c.DataFromReader(http.StatusOK, data.ContentLength, "application/octet-stream", data.Contents, extraHeaders) } else { //uhhhhhhhhhhhhh - response.From(c).Fail() + response.HandleError(c, errors.New("no file content or file list"), http.StatusInternalServerError) } } @@ -317,11 +311,7 @@ func PutFile(c *gin.Context) { _, mkFolder := c.GetQuery("folder") if mkFolder { err = server.CreateFolder(targetPath) - if err != nil { - errorConnection(c, err) - } else { - response.From(c) - } + response.HandleError(c, err, http.StatusInternalServerError) return } @@ -385,8 +375,6 @@ func GetConsole(c *gin.Context) { return } - response.From(c).Discard() - console, _ := program.GetEnvironment().GetConsole() _ = messages.Write(conn, messages.ConsoleMessage{Logs: console}) @@ -398,13 +386,9 @@ func GetStats(c *gin.Context) { svr := item.(*programs.Program) results, err := svr.GetEnvironment().GetStats() - if err != nil { - result := make(map[string]interface{}) - result["memory"] = 0 - result["cpu"] = 0 - response.From(c).Data(result) + if response.HandleError(c, err, http.StatusInternalServerError) { } else { - response.From(c).Data(results) + c.JSON(200, results) } } @@ -414,11 +398,9 @@ func GetLogs(c *gin.Context) { time := c.DefaultQuery("time", "0") - castedTime, ok := strconv.ParseInt(time, 10, 64) - + castedTime, ok := cast.ToInt64E(time) if ok != nil { - //c.AbortWithError(400, errors.New("Time provided is not a valid UNIX time")) - response.From(c).Fail().Status(400).Message("time provided is not a valid UNIX time") + response.HandleError(c, pufferd.ErrInvalidUnixTime, http.StatusBadRequest) return } @@ -427,10 +409,11 @@ func GetLogs(c *gin.Context) { for _, k := range console { msg += k } - result := make(map[string]interface{}) - result["epoch"] = epoch - result["logs"] = msg - response.From(c).Data(result) + + c.JSON(200, &pufferd.ServerLogs{ + Epoch: epoch, + Logs: msg, + }) } func GetStatus(c *gin.Context) { @@ -438,14 +421,10 @@ func GetStatus(c *gin.Context) { program := item.(*programs.Program) running, err := program.IsRunning() - result := make(map[string]interface{}) - if err != nil { - result["error"] = err.Error() - response.From(c).Data(result).Status(500) + if response.HandleError(c, err, http.StatusInternalServerError) { } else { - result["running"] = running - response.From(c).Data(result) + c.JSON(200, &pufferd.ServerRunning{Running: running}) } } @@ -473,9 +452,5 @@ func OpenSocket(c *gin.Context) { func errorConnection(c *gin.Context, err error) { logging.Exception("error on API call", err) - response.From(c).Status(500).Data(err).Message("error handling request") -} - -type admin struct { - Data map[string]interface{} `json:"data"` + response.HandleError(c, err, http.StatusInternalServerError) } diff --git a/routing/server/websocket.go b/routing/server/websocket.go index 0cefd93..d953c42 100644 --- a/routing/server/websocket.go +++ b/routing/server/websocket.go @@ -4,9 +4,9 @@ import ( "bytes" "encoding/json" "github.com/gorilla/websocket" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" - "github.com/pufferpanel/apufferi/v3/scope" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" + "github.com/pufferpanel/apufferi/v4/scope" "github.com/pufferpanel/pufferd/v2/messages" "github.com/pufferpanel/pufferd/v2/programs" "github.com/spf13/viper" @@ -46,8 +46,8 @@ func listenOnSocket(conn *websocket.Conn, server *programs.Program, scopes []sco msg.Cpu = 0 msg.Memory = 0 } else { - msg.Cpu, _ = results["cpu"].(float64) - msg.Memory, _ = results["memory"].(float64) + msg.Cpu = results.Cpu + msg.Memory = results.Memory } _ = messages.Write(conn, msg) } diff --git a/sftp/requestprefix.go b/sftp/requestprefix.go index 30a91e4..961d540 100644 --- a/sftp/requestprefix.go +++ b/sftp/requestprefix.go @@ -25,8 +25,8 @@ import ( "strings" "github.com/pkg/sftp" - utils "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + utils "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" ) type requestPrefix struct { diff --git a/sftp/server.go b/sftp/server.go index aa47cd3..476cc21 100644 --- a/sftp/server.go +++ b/sftp/server.go @@ -22,8 +22,8 @@ import ( "crypto/x509" "encoding/pem" "github.com/pkg/sftp" - "github.com/pufferpanel/apufferi/v3" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/oauth2" "github.com/pufferpanel/pufferd/v2/programs" "github.com/spf13/viper" diff --git a/shutdown/shutdown.go b/shutdown/shutdown.go index a35edf6..034d685 100644 --- a/shutdown/shutdown.go +++ b/shutdown/shutdown.go @@ -19,7 +19,7 @@ package shutdown import ( "fmt" "github.com/braintree/manners" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/programs" "os" "runtime/debug" diff --git a/utils/websockettracker.go b/utils/websockettracker.go index c1054a3..cf83458 100644 --- a/utils/websockettracker.go +++ b/utils/websockettracker.go @@ -18,7 +18,7 @@ package utils import ( "encoding/json" - "github.com/pufferpanel/apufferi/v3/logging" + "github.com/pufferpanel/apufferi/v4/logging" "github.com/pufferpanel/pufferd/v2/messages" "sync"