diff --git a/.github/workflows/bifrost-lint.yaml b/.github/workflows/bifrost-lint.yaml index 0df6a42..83e738b 100644 --- a/.github/workflows/bifrost-lint.yaml +++ b/.github/workflows/bifrost-lint.yaml @@ -42,7 +42,7 @@ jobs: # # Note: By default, the `.golangci.yml` file should be at the root of the repository. # The location of the configuration file can be changed by using `--config=` - # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 + args: --timeout=30m # Optional: show only new issues if it's a pull request. The default value is `false`. # only-new-issues: true diff --git a/api/docs.go b/api/docs.go new file mode 100644 index 0000000..9b8eeb7 --- /dev/null +++ b/api/docs.go @@ -0,0 +1,133 @@ +// Code generated by swaggo/swag. DO NOT EDIT. + +package api + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "termsOfService": "http://swagger.io/terms/", + "contact": {}, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/steps": { + "get": { + "description": "List all supported bifrost steps", + "produces": [ + "application/json" + ], + "tags": [ + "Steps" + ], + "summary": "List all bifrost steps", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.StepInfoList" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "opennaslab_io_bifrost_pkg_customapi.Documentation": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.Documentation" + } + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string" + } + } + }, + "opennaslab_io_bifrost_pkg_customapi.StepInfo": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parameters": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.StepParameter" + } + } + }, + "opennaslab_io_bifrost_pkg_customapi.StepInfoList": { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.StepInfo" + } + } + } + }, + "opennaslab_io_bifrost_pkg_customapi.StepParameter": { + "type": "object", + "properties": { + "in": { + "type": "array", + "items": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.Documentation" + } + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "0.1", + Host: "", + BasePath: "/api/v1", + Schemes: []string{}, + Title: "bifrost API", + Description: "Take you to the land of light, the city of freedom(A unified external service management system for NAS).", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/api/swagger.json b/api/swagger.json new file mode 100644 index 0000000..64193b2 --- /dev/null +++ b/api/swagger.json @@ -0,0 +1,107 @@ +{ + "swagger": "2.0", + "info": { + "description": "Take you to the land of light, the city of freedom(A unified external service management system for NAS).", + "title": "bifrost API", + "termsOfService": "http://swagger.io/terms/", + "contact": {}, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "0.1" + }, + "basePath": "/api/v1", + "paths": { + "/steps": { + "get": { + "description": "List all supported bifrost steps", + "produces": [ + "application/json" + ], + "tags": [ + "Steps" + ], + "summary": "List all bifrost steps", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.StepInfoList" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "opennaslab_io_bifrost_pkg_customapi.Documentation": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.Documentation" + } + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string" + } + } + }, + "opennaslab_io_bifrost_pkg_customapi.StepInfo": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parameters": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.StepParameter" + } + } + }, + "opennaslab_io_bifrost_pkg_customapi.StepInfoList": { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.StepInfo" + } + } + } + }, + "opennaslab_io_bifrost_pkg_customapi.StepParameter": { + "type": "object", + "properties": { + "in": { + "type": "array", + "items": { + "$ref": "#/definitions/opennaslab_io_bifrost_pkg_customapi.Documentation" + } + } + } + } + } +} \ No newline at end of file diff --git a/api/swagger.yaml b/api/swagger.yaml new file mode 100644 index 0000000..527101e --- /dev/null +++ b/api/swagger.yaml @@ -0,0 +1,71 @@ +basePath: /api/v1 +definitions: + opennaslab_io_bifrost_pkg_customapi.Documentation: + properties: + description: + type: string + items: + items: + $ref: '#/definitions/opennaslab_io_bifrost_pkg_customapi.Documentation' + type: array + name: + type: string + required: + type: boolean + type: + type: string + type: object + opennaslab_io_bifrost_pkg_customapi.StepInfo: + properties: + description: + type: string + image: + type: string + name: + type: string + parameters: + $ref: '#/definitions/opennaslab_io_bifrost_pkg_customapi.StepParameter' + type: object + opennaslab_io_bifrost_pkg_customapi.StepInfoList: + properties: + steps: + items: + $ref: '#/definitions/opennaslab_io_bifrost_pkg_customapi.StepInfo' + type: array + type: object + opennaslab_io_bifrost_pkg_customapi.StepParameter: + properties: + in: + items: + $ref: '#/definitions/opennaslab_io_bifrost_pkg_customapi.Documentation' + type: array + type: object +info: + contact: {} + description: Take you to the land of light, the city of freedom(A unified external + service management system for NAS). + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: bifrost API + version: "0.1" +paths: + /steps: + get: + description: List all supported bifrost steps + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/opennaslab_io_bifrost_pkg_customapi.StepInfoList' + "500": + description: Internal Server Error + schema: + type: string + summary: List all bifrost steps + tags: + - Steps +swagger: "2.0" diff --git a/cmd/main.go b/cmd/main.go index 71cbf82..0ef37aa 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -24,6 +24,15 @@ import ( "opennaslab.io/bifrost/pkg/server" ) +// @title bifrost API +// @version 0.1 +// @description Take you to the land of light, the city of freedom(A unified external service management system for NAS). +// @termsOfService http://swagger.io/terms/ + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @BasePath /api/v1 func main() { opt := options.NewBifrostDBOptions() if err := opt.Validate(); err != nil { diff --git a/go.mod b/go.mod index 2dff2ec..13fb493 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,19 @@ require ( github.com/docker/docker v24.0.6+incompatible github.com/gin-contrib/cors v1.4.0 github.com/gin-gonic/gin v1.9.1 + github.com/swaggo/files v1.0.1 + github.com/swaggo/gin-swagger v1.6.0 + github.com/swaggo/swag v1.16.2 gorm.io/driver/mysql v1.5.1 gorm.io/gorm v1.25.4 k8s.io/klog v1.0.0 ) require ( + github.com/KyleBanks/depth v1.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect @@ -20,6 +26,10 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/swag v0.19.15 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect @@ -29,10 +39,12 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -54,6 +66,7 @@ require ( golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index e1bac9b..337b43c 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,12 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/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/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -23,12 +29,23 @@ github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g= github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs= +github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= 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.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= @@ -56,6 +73,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -75,6 +94,10 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -87,6 +110,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -116,6 +140,12 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= +github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= +github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= +github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= @@ -124,6 +154,7 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -131,10 +162,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -142,27 +175,39 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -171,6 +216,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -183,11 +229,15 @@ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cn google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main b/main new file mode 100755 index 0000000..116c934 Binary files /dev/null and b/main differ diff --git a/pkg/api/types.go b/pkg/api/types.go index b654894..bc33657 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -59,13 +59,19 @@ type ConfigurationStep struct { type ConfigurationWorkflowState string const ( - ConfigurationWorkflowStatePending ConfigurationWorkflowState = "pending" - ConfigurationWorkflowStateRunning ConfigurationWorkflowState = "running" - ConfigurationWorkflowStateRunningSuccess ConfigurationWorkflowState = "runningSuccess" - ConfigurationWorkflowStateRunningFailed ConfigurationWorkflowState = "runningFailed" - ConfigurationWorkflowStateDeleting ConfigurationWorkflowState = "deleting" - ConfigurationWorkflowStateDeletingFailed ConfigurationWorkflowState = "deletingFailed" - ConfigurationWorkflowStateDeletingSuccess ConfigurationWorkflowState = "Deletingsuccess" + ConfigurationWorkflowStateSubmitted ConfigurationWorkflowState = "submitted" + ConfigurationWorkflowStateRunning ConfigurationWorkflowState = "running" + ConfigurationWorkflowStateRunningSuccess ConfigurationWorkflowState = "runningSuccess" + ConfigurationWorkflowStateRunningFailed ConfigurationWorkflowState = "runningFailed" + ConfigurationWorkflowStateStopping ConfigurationWorkflowState = "stopping" + ConfigurationWorkflowStateStoppingdSuccess ConfigurationWorkflowState = "stoppingSuccess" + ConfigurationWorkflowStateStoppingFailed ConfigurationWorkflowState = "stoppingFailed" + ConfigurationWorkflowStateRestarting ConfigurationWorkflowState = "restarting" + ConfigurationWorkflowStateRestartingSuccess ConfigurationWorkflowState = "restartingSuccess" + ConfigurationWorkflowStateRestartingFailed ConfigurationWorkflowState = "restartingFailed" + ConfigurationWorkflowStateDeleting ConfigurationWorkflowState = "deleting" + ConfigurationWorkflowStateDeletingFailed ConfigurationWorkflowState = "deletingFailed" + ConfigurationWorkflowStateDeletingSuccess ConfigurationWorkflowState = "deletingsuccess" ) type ConfigurationWorkflowStatus struct { diff --git a/pkg/container/create.go b/pkg/container/create.go index 0be26e6..fab5bf1 100644 --- a/pkg/container/create.go +++ b/pkg/container/create.go @@ -26,7 +26,7 @@ func CreateContainer(workflowName, stepName, image string) (string, error) { err = cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}) if err != nil { // Ignore the error, we can't do anything - cli.ContainerRemove(context.Background(), resp.ID, types.ContainerRemoveOptions{Force: true}) + _ = cli.ContainerRemove(context.Background(), resp.ID, types.ContainerRemoveOptions{Force: true}) return "", err } return resp.ID, nil diff --git a/pkg/controller/workflow.go b/pkg/controller/workflow.go index 8354ef6..fa99238 100644 --- a/pkg/controller/workflow.go +++ b/pkg/controller/workflow.go @@ -31,7 +31,7 @@ import ( ) type WorkflowQueue struct { - Workflow map[string]interface{} + Workflow map[string]api.ConfigurationWorkflowState mutex sync.Mutex } @@ -39,68 +39,83 @@ var WFQueue *WorkflowQueue func InitWorkflowQueue() { WFQueue = &WorkflowQueue{ - Workflow: make(map[string]interface{}), + Workflow: make(map[string]api.ConfigurationWorkflowState), mutex: sync.Mutex{}, } } -func (w *WorkflowQueue) AddWorkflow(name string) { +func (w *WorkflowQueue) Add(name string, op api.ConfigurationWorkflowState) { + w.mutex.Lock() + defer w.mutex.Unlock() w.mutex.Lock() defer w.mutex.Unlock() - w.Workflow[name] = nil + w.Workflow[name] = op } func (w *WorkflowQueue) Run() { for { - w.mutex.Lock() - defer w.mutex.Unlock() - for name := range w.Workflow { - requeue, err := w.Reconcile(name) + for name, op := range w.Workflow { + w.mutex.Lock() + delete(w.Workflow, name) + w.mutex.Unlock() + + requeue, err := w.Reconcile(name, op) if err == nil && !requeue { - delete(w.Workflow, name) + if _, ok := w.Workflow[name]; ok { + w.Add(name, op) + } } } - time.Sleep(time.Second * 3) + if len(w.Workflow) == 0 { + time.Sleep(time.Second * 3) + } } } -func (w *WorkflowQueue) Reconcile(name string) (requeue bool, err error) { +func (w *WorkflowQueue) Reconcile(name string, op api.ConfigurationWorkflowState) (requeue bool, err error) { db := database.GetWorkflowMode() wf, err := db.GetWorkflow(name) if errors.Is(err, gorm.ErrRecordNotFound) { return false, nil } - if wf.Status.State == api.ConfigurationWorkflowStateDeleting { - requeue, err := w.DeleteWorkflow(wf) - if !requeue && err != nil { - err := db.DeleteWorkflow(name) - if err != nil { - return false, err - } - } + + defer func() { + _ = database.GetWorkflowMode().UpdateWorkflow(wf) + }() + switch op { + case api.ConfigurationWorkflowStateDeleting: + return w.DeleteWorkflow(wf) + case api.ConfigurationWorkflowStateRunning: + return false, nil + case api.ConfigurationWorkflowStateStopping: + return false, nil + case api.ConfigurationWorkflowStateRestarting: + return false, nil } + return false, nil } func (w *WorkflowQueue) DeleteWorkflow(wf *api.ConfigurationWorkflow) (requeue bool, err error) { - for index, step := range wf.ConfigurationSteps { - stepState := wf.Status.ConfigurationSteps[index] + for index := len(wf.ConfigurationSteps) - 1; index >= 0; index-- { + stepState := &(wf.Status.ConfigurationSteps[index]) - if stepState.State == api.ConfigurationWorkflowStateRunning || stepState.State == api.ConfigurationWorkflowStateRunningSuccess { + switch stepState.State { + case api.ConfigurationWorkflowStateSubmitted, api.ConfigurationWorkflowStateDeletingSuccess: + continue + case api.ConfigurationWorkflowStateRunning, api.ConfigurationWorkflowStateRunningSuccess: err := container.DeleteContainer(stepState.ContainerId) if err != nil { + wf.Status.State = api.ConfigurationWorkflowStateDeletingFailed return false, err } - } - - if stepState.State == api.ConfigurationWorkflowStateDeletingSuccess { + stepState.State = api.ConfigurationWorkflowStateDeletingSuccess continue - } - - if stepState.State == api.ConfigurationWorkflowStateDeleting { + case api.ConfigurationWorkflowStateDeleting: containerState, exitCode, err := container.GetContainer(stepState.ContainerId) if err != nil { + wf.Status.State = api.ConfigurationWorkflowStateDeletingFailed return false, err } if containerState == "exited" && exitCode == 0 { @@ -108,22 +123,25 @@ func (w *WorkflowQueue) DeleteWorkflow(wf *api.ConfigurationWorkflow) (requeue b continue } } - - stepDef := customapi.GetStepDefinition(step.Use) + stepDef := customapi.GetStepDefinition(wf.ConfigurationSteps[index].Use) if stepDef == nil { - return false, fmt.Errorf("dns step definition %s not found", step.Use) + return false, fmt.Errorf("dns step definition %s not found", wf.ConfigurationSteps[index].Use) } - id, err := container.CreateContainer(wf.Name, step.Name, stepDef.Image) + id, err := container.CreateContainer(wf.Name, wf.ConfigurationSteps[index].Name, stepDef.Image) if err != nil { return false, err } stepState.ContainerId = id stepState.State = api.ConfigurationWorkflowStateDeleting } + wf.Status.State = api.ConfigurationWorkflowStateDeletingSuccess return false, nil } -func (w *WorkflowQueue) UpdateWorkflow(name string) (*api.ConfigurationWorkflow, error) { - return nil, nil +func (w *WorkflowQueue) StopWorkflow(wf *api.ConfigurationWorkflow) (requeue bool, err error) { + for index := len(wf.ConfigurationSteps) - 1; index >= 0; index-- { + return false, nil + } + return false, nil } diff --git a/pkg/customapi/interface.go b/pkg/customapi/interface.go index b219a48..c6cfe71 100644 --- a/pkg/customapi/interface.go +++ b/pkg/customapi/interface.go @@ -8,7 +8,7 @@ import ( "opennaslab.io/bifrost/pkg/api" ) -var StepsInfoMap = map[string]StepsInfo{ +var StepsInfoMap = map[string]StepInfo{ "frpc-config": { Name: "frpc-config", Image: "opennaslab/frpc-config:latest", @@ -78,7 +78,7 @@ func GenerateDocumentation(obj interface{}) []Documentation { return doc } -type StepsInfo struct { +type StepInfo struct { Name string `json:"name"` Description string `json:"description"` Image string `json:"image"` @@ -89,7 +89,11 @@ type StepParameter struct { In []Documentation `json:"in"` } -func GetStepDefinition(name string) *StepsInfo { +type StepInfoList struct { + Steps []StepInfo `json:"steps"` +} + +func GetStepDefinition(name string) *StepInfo { if _, ok := StepsInfoMap[name]; !ok { return nil } @@ -99,13 +103,13 @@ func GetStepDefinition(name string) *StepsInfo { return &ret } -func ListStepDefinitions() []StepsInfo { - ret := []StepsInfo{} +func ListStepDefinitions() StepInfoList { + ret := StepInfoList{} for name := range StepsInfoMap { paraInDoc := GenerateDocumentation(StepsStruct[name]) ele := StepsInfoMap[name] ele.Parameters.In = paraInDoc - ret = append(ret, ele) + ret.Steps = append(ret.Steps, ele) } return ret } diff --git a/pkg/server/handler.go b/pkg/server/handler.go index a554eaf..b147f97 100644 --- a/pkg/server/handler.go +++ b/pkg/server/handler.go @@ -28,12 +28,21 @@ import ( "opennaslab.io/bifrost/pkg/database" ) +// ListStepsHandler godoc +// +// @Summary List all bifrost steps +// @Description List all supported bifrost steps +// @Tags Steps +// @Produce json +// @Success 200 {object} customapi.StepInfoList +// @Failure 500 {object} string +// @Router /steps [get] func ListStepsHandler(ctx *gin.Context) { steps := customapi.ListStepDefinitions() respData, err := json.Marshal(steps) if err != nil { klog.Errorf("Marshal steps failed:%v", err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } ctx.Data(http.StatusOK, "application/json", respData) @@ -56,8 +65,13 @@ func GetStepHandler(ctx *gin.Context) { func CreateOrUpdateWorkflowHandler(ctx *gin.Context) { workflow := &api.ConfigurationWorkflow{} - ctx.BindJSON(workflow) - err := validateSteps(workflow.ConfigurationSteps) + err := ctx.BindJSON(workflow) + if err != nil { + klog.Errorf("Bind workflow failed:%v", err) + ctx.AbortWithError(http.StatusBadRequest, err) + return + } + err = validateSteps(workflow.ConfigurationSteps) if err != nil { klog.Errorf("Validate steps failed:%v", err) ctx.AbortWithError(http.StatusBadRequest, err) @@ -87,13 +101,13 @@ func ListWorkflowsHandler(ctx *gin.Context) { workflows, err := db.ListWorkflows() if err != nil { klog.Errorf("List workflows failed:%v", err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } respData, err := json.Marshal(workflows) if err != nil { klog.Errorf("Marshal workflows failed:%v", err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } ctx.Data(http.StatusOK, "application/json", respData) @@ -104,13 +118,13 @@ func GetWorkflowHandler(ctx *gin.Context) { workflow, err := db.GetWorkflow(ctx.Param("name")) if err != nil { klog.Errorf("Get workflow %s failed:%v", ctx.Param("name"), err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } respData, err := json.Marshal(workflow) if err != nil { klog.Errorf("Marshal workflow %s failed:%v", ctx.Param("name"), err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } ctx.Data(http.StatusOK, "application/json", respData) @@ -121,14 +135,30 @@ func DeleteWorkflowHandler(ctx *gin.Context) { wf, err := db.GetWorkflow(ctx.Param("name")) if err != nil { klog.Errorf("Delete workflow %s failed:%v", ctx.Param("name"), err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } wf.Status.State = api.ConfigurationWorkflowStateDeleting if err := db.UpdateWorkflow(wf); err != nil { klog.Errorf("Update workflow %s failed:%v", ctx.Param("name"), err) - ctx.AbortWithError(http.StatusInternalServerError, err) + _ = ctx.AbortWithError(http.StatusInternalServerError, err) return } ctx.Data(http.StatusOK, "application/json", []byte("OK")) } + +func RunWorkflowHandler(ctx *gin.Context) { + ctx.Data(http.StatusOK, "application/json", []byte("OK")) +} + +func StopWorkflowHandler(ctx *gin.Context) { + ctx.Data(http.StatusOK, "application/json", []byte("OK")) +} + +func RestartWorkflowHandler(ctx *gin.Context) { + ctx.Data(http.StatusOK, "application/json", []byte("OK")) +} + +func LogWorkflowHandler(ctx *gin.Context) { + ctx.Data(http.StatusOK, "application/json", []byte("OK")) +} diff --git a/pkg/server/router.go b/pkg/server/router.go index 5d9765f..1e885d6 100644 --- a/pkg/server/router.go +++ b/pkg/server/router.go @@ -19,6 +19,10 @@ package server import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + swaggerfiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" + + _ "opennaslab.io/bifrost/api" ) func NewServerRouter() *gin.Engine { @@ -29,6 +33,9 @@ func NewServerRouter() *gin.Engine { config.AllowHeaders = []string{"*"} corsHandler := cors.New(config) + router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) + router.Use(corsHandler) + initStepRouter(router, corsHandler) initWorkflowRouter(router, corsHandler) @@ -39,17 +46,25 @@ func initStepRouter(router *gin.Engine, corsHandler gin.HandlerFunc) { localStepGroup := router.Group("/api/v1/steps") localStepGroup.GET("", ListStepsHandler) // Get specific step - localStepGroup.GET("/:name", GetStepHandler) + localStepGroup.GET("/:step_name", GetStepHandler) } func initWorkflowRouter(router *gin.Engine, corsHandler gin.HandlerFunc) { workflowGroup := router.Group("/api/v1/workflows") // List all workflow workflowGroup.GET("", ListWorkflowsHandler) - // Get specific workflow - workflowGroup.GET("/:name", GetWorkflowHandler) // Create/Update workflow - workflowGroup.POST("/:name", CreateOrUpdateWorkflowHandler) + workflowGroup.POST("", CreateOrUpdateWorkflowHandler) + // Get specific workflow + workflowGroup.GET("/:workflow_name", GetWorkflowHandler) // Delete workflow - workflowGroup.DELETE("/:name", DeleteWorkflowHandler) + workflowGroup.DELETE("/:workflow_name", DeleteWorkflowHandler) + // Run workflow + workflowGroup.PUT("/:workflow_name/run", nil) + // Stop workflow + workflowGroup.PUT("/:workflow_name/stop", nil) + // Restart workflow + workflowGroup.PUT("/:workflow_name/restart", nil) + // logs workflow's step + workflowGroup.GET("/:workflow_name/:step_name/logs", nil) }