From 3d71b0f17521f9205c1e03110015f9975ef9a237 Mon Sep 17 00:00:00 2001 From: "xu.zhu" Date: Mon, 16 Oct 2023 20:17:10 +0800 Subject: [PATCH 1/4] fix: getDiff returns 500 Signed-off-by: xu.zhu --- core/http/api/v1/pipelinerun/apis.go | 7 +++++++ core/http/api/v2/pipelinerun/apis.go | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/core/http/api/v1/pipelinerun/apis.go b/core/http/api/v1/pipelinerun/apis.go index 11817618..601e5095 100644 --- a/core/http/api/v1/pipelinerun/apis.go +++ b/core/http/api/v1/pipelinerun/apis.go @@ -20,10 +20,13 @@ import ( "github.com/horizoncd/horizon/core/common" prctl "github.com/horizoncd/horizon/core/controller/pipelinerun" + herrors "github.com/horizoncd/horizon/core/errors" "github.com/horizoncd/horizon/lib/q" "github.com/horizoncd/horizon/pkg/cluster/tekton/collector" + perror "github.com/horizoncd/horizon/pkg/errors" "github.com/horizoncd/horizon/pkg/server/request" "github.com/horizoncd/horizon/pkg/server/response" + "github.com/horizoncd/horizon/pkg/server/rpcerror" "github.com/horizoncd/horizon/pkg/util/errors" "github.com/gin-gonic/gin" @@ -119,6 +122,10 @@ func (a *API) GetDiff(c *gin.Context) { } diff, err := a.prCtl.GetDiff(c, uint(pipelinerunID)) if err != nil { + if _, ok := perror.Cause(err).(*herrors.HorizonErrNotFound); ok { + response.AbortWithRPCError(c, rpcerror.NotFoundError.WithErrMsg(err.Error())) + return + } response.AbortWithError(c, err) return } diff --git a/core/http/api/v2/pipelinerun/apis.go b/core/http/api/v2/pipelinerun/apis.go index 37cb3ee8..4c776469 100644 --- a/core/http/api/v2/pipelinerun/apis.go +++ b/core/http/api/v2/pipelinerun/apis.go @@ -99,6 +99,10 @@ func (a *API) GetDiff(c *gin.Context) { a.withPipelinerunID(c, func(pipelinerunID uint) { diff, err := a.prCtl.GetDiff(c, uint(pipelinerunID)) if err != nil { + if _, ok := perror.Cause(err).(*herrors.HorizonErrNotFound); ok { + response.AbortWithRPCError(c, rpcerror.NotFoundError.WithErrMsg(err.Error())) + return + } response.AbortWithError(c, err) return } From c66cfd2d276a87d33dd7bbdd905de2853cac4728 Mon Sep 17 00:00:00 2001 From: "xu.zhu" Date: Wed, 18 Oct 2023 11:20:15 +0800 Subject: [PATCH 2/4] fix: openapi docs Signed-off-by: xu.zhu --- openapi/v2/restful/cluster.yaml | 80 +++---- openapi/v2/restful/common.yaml | 360 +++++++++++++++------------- openapi/v2/restful/pipelinerun.yaml | 253 ++++++++++++------- 3 files changed, 399 insertions(+), 294 deletions(-) diff --git a/openapi/v2/restful/cluster.yaml b/openapi/v2/restful/cluster.yaml index 65cc6ad8..dfd2ae0d 100644 --- a/openapi/v2/restful/cluster.yaml +++ b/openapi/v2/restful/cluster.yaml @@ -206,7 +206,7 @@ paths: content: application/json: schema: - properties: + properties: data: $ref: "#/components/schemas/PipelinerunIDResponse" default: @@ -1121,7 +1121,7 @@ paths: description: OK content: application/json: - schema: {} + schema: { } delete: summary: Remove cluster from favorites operationId: removeFavoriteCluster @@ -1130,7 +1130,7 @@ paths: description: OK content: application/json: - schema: {} + schema: { } /apis/core/v2/clusters/{clusterId}/pipelineruns: parameters: - name: clusterId @@ -1141,41 +1141,41 @@ paths: type: integer example: 60517 post: - summary: Create a pipelinerun for a cluster - operationId: createPipelinerun - tags: [cluster] - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - action: - type: string - enum: [builddeploy, deploy, rollback] - description: type of pipelinerun - title: - type: string - description: title of pipelinerun - description: - type: string - description: description of pipelinerun - git: - type: object - properties: - branch: - type: string - description: branch of git repository - imageTag: - type: string - description: image tag of a image - pipelinerunID: - type: number - description: id of pipelinerun - responses: - '200': - description: OK + summary: Create a pipelinerun for a cluster + operationId: createPipelinerun + tags: [ cluster ] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + action: + type: string + enum: [ builddeploy, deploy, rollback ] + description: type of pipelinerun + title: + type: string + description: title of pipelinerun + description: + type: string + description: description of pipelinerun + git: + type: object + properties: + branch: + type: string + description: branch of git repository + imageTag: + type: string + description: image tag of a image + pipelinerunID: + type: number + description: id of pipelinerun + responses: + '200': + description: OK components: @@ -1339,7 +1339,7 @@ components: $ref: "#/components/schemas/GitResponse" type: type: string - enum: [workload, database, middleware, other, v1] + enum: [ workload, database, middleware, other, v1 ] description: type of template related to cluster tags: $ref: "#/components/schemas/Tags" @@ -1497,7 +1497,7 @@ components: properties: pipelinerunID: $ref: "#/components/schemas/PipelinerunID" - + DeployRequest: type: object properties: diff --git a/openapi/v2/restful/common.yaml b/openapi/v2/restful/common.yaml index 546cc8e8..d1064dc9 100644 --- a/openapi/v2/restful/common.yaml +++ b/openapi/v2/restful/common.yaml @@ -1,169 +1,193 @@ -# Copyright © 2023 Horizoncd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -components: - parameters: - pageNumber: - name: pageNumber - in: query - pageSize: - name: pageSize - in: query - paramResourceType: - name: resourceType - in: path - paramResourceID: - name: resourceID - in: path - paramApplicationID: - name: applicationID - in: path - description: application id - required: true - paramClusterID: - name: clusterID - in: path - description: cluster id - required: true - paramPipelinerunID: - name: pipelinerunID - in: path - description: pipelinerun id - required: true - paramGroupID: - name: groupID - in: path - description: group id - schema: - type: integer - format: int64 - required: true - queryEnvironment: - name: environment - in: query - queryFilter: - name: filter - in: query - queryGroupID: - name: groupID - in: query - description: group id - schema: - type: integer - format: int64 - - schemas: - PageParams: - type: object - properties: - current: - type: number - pageSize: - type: number - - Error: - type: object - required: - - code - - message - properties: - code: - type: string - message: - type: string - requestID: - type: string - - resourceType: - type: string - enum: - - group - - application - - applicationInstance - - Date: - type: string - format: date - pattern: full-date - - - URL: - type: string - format: uri - - Description: - type: string - maxLength: 1024 - description: the description - - ID: - type: integer - format: uint64 - - GroupID: - type: integer - format: int64 - description: the parent id of the subgroup, if not provided, a root group - - User: - type: object - properties: - name: - type: string - description: the name of user - email: - type: string - description: the e-mail address of user - id: - type: integer - description: the id of user - - userList: - type: object - properties: - total: - type: integer - description: The total number of users that match the filter. - items: - type: array - items: - $ref: '#/components/schemas/user' - - user: - type: object - properties: - id: - type: integer - description: The unique ID of the user. - name: - type: string - description: The unique name of the user. - fullName: - type: string - description: The full name of the user. - email: - type: string - description: The email address of the user. - isAdmin: - type: boolean - description: Whether the user is an administrator. - isBanned: - type: boolean - description: Whether the user is banned. - updatedAt: - type: string - description: The date and time at which the user was last updated. - createdAt: - type: string +# Copyright © 2023 Horizoncd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +components: + parameters: + pageNumber: + name: pageNumber + in: query + schema: + type: integer + format: int64 + pageSize: + name: pageSize + in: query + schema: + type: integer + format: int64 + paramResourceType: + name: resourceType + in: path + schema: + type: string + enum: + - groups + - applications + - clusters + description: resource type + paramResourceID: + name: resourceID + in: path + schema: + type: string + paramApplicationID: + name: applicationID + in: path + description: application id + required: true + paramClusterID: + name: clusterID + in: path + description: cluster id + required: true + paramPipelinerunID: + name: pipelinerunID + in: path + schema: + type: string + description: pipelinerun id + required: true + paramCheckrunID: + name: checkrunID + in: path + schema: + type: string + description: checkrun id + required: true + paramGroupID: + name: groupID + in: path + description: group id + schema: + type: integer + format: int64 + required: true + queryEnvironment: + name: environment + in: query + queryFilter: + name: filter + in: query + queryGroupID: + name: groupID + in: query + description: group id + schema: + type: integer + format: int64 + + schemas: + PageParams: + type: object + properties: + current: + type: number + pageSize: + type: number + + Error: + type: object + required: + - code + - message + properties: + code: + type: string + message: + type: string + requestID: + type: string + + resourceType: + type: string + enum: + - group + - application + - applicationInstance + + Date: + type: string + format: date + pattern: full-date + + + URL: + type: string + format: uri + + Description: + type: string + maxLength: 1024 + description: the description + + ID: + type: integer + format: uint64 + + GroupID: + type: integer + format: int64 + description: the parent id of the subgroup, if not provided, a root group + + User: + type: object + properties: + name: + type: string + description: the name of user + email: + type: string + description: the e-mail address of user + id: + type: integer + description: the id of user + + userList: + type: object + properties: + total: + type: integer + description: The total number of users that match the filter. + items: + type: array + items: + $ref: '#/components/schemas/user' + + user: + type: object + properties: + id: + type: integer + description: The unique ID of the user. + name: + type: string + description: The unique name of the user. + fullName: + type: string + description: The full name of the user. + email: + type: string + description: The email address of the user. + isAdmin: + type: boolean + description: Whether the user is an administrator. + isBanned: + type: boolean + description: Whether the user is banned. + updatedAt: + type: string + description: The date and time at which the user was last updated. + createdAt: + type: string description: The date and time at which the user was created. \ No newline at end of file diff --git a/openapi/v2/restful/pipelinerun.yaml b/openapi/v2/restful/pipelinerun.yaml index c82c7a93..4ba26b9f 100644 --- a/openapi/v2/restful/pipelinerun.yaml +++ b/openapi/v2/restful/pipelinerun.yaml @@ -161,7 +161,7 @@ paths: schema: $ref: "common.yaml#/components/schemas/Error" - /apis/core/v2/clusters/:%v/pipelineruns: + /apis/core/v2/clusters/{clusterID}/pipelineruns: parameters: - $ref: "common.yaml#/components/parameters/paramClusterID" - $ref: "common.yaml#/components/parameters/pageNumber" @@ -171,12 +171,18 @@ paths: schema: type: boolean description: whether the pipelinerun can rollback + - name: status + in: query + schema: + type: string + enum: [ pending, ready, ok, canceled, failed ] + description: status of pipelinerun get: tags: - pipelinerun operationId: getClusterPipelineRuns summary: | - Get pipelineruns of a cluster. + list pipelineruns of a cluster. responses: "200": description: Success @@ -268,10 +274,10 @@ paths: - $ref: "common.yaml#/components/parameters/paramPipelinerunID" post: tags: - - pipelinerun - operationId: createCheckRun + - checkrun + operationId: createCheckrun summary: | - Create a check run for the specified pipelinerun. + Create a check run for the specified pipelinerun. requestBody: content: application/json: @@ -295,55 +301,130 @@ paths: description: "detail url of check run" responses: "200": - description: Success + description: Success get: tags: - - pipelinerun - operationId: listCheckRuns + - checkrun + operationId: listCheckruns summary: | List check runs of the specified pipelinerun. responses: - "200": - description: Success - content: - application/json: - schema: - type: object - properties: - total: - type: integer - description: "total number of check runs" - data: - type: object - properties: - items: - type: array - properties: - id: - type: integer - description: "id of check run" - name: - type: string - description: "name of check run" - checkId: - type: integer - description: "check id of check run" - status: - type: string - description: "status of check run" - pipilineRunId: - type: integer - description: "pipelinerun id of check run" - detailUrl: - type: string - description: "detail url of check run" - message: - type: string - description: "message of check run" - createdAt: - type: string - updatedAt: - type: string + "200": + description: Success + content: + application/json: + schema: + type: object + properties: + total: + type: integer + description: "total number of check runs" + data: + type: object + properties: + items: + type: array + properties: + id: + type: integer + description: "id of check run" + name: + type: string + description: "name of check run" + checkId: + type: integer + description: "check id of check run" + status: + type: string + description: "status of check run" + pipilineRunId: + type: integer + description: "pipelinerun id of check run" + detailUrl: + type: string + description: "detail url of check run" + message: + type: string + description: "message of check run" + createdAt: + type: string + updatedAt: + type: string + /apis/core/v2/checkruns/{checkrunID}: + parameters: + - $ref: "common.yaml#/components/parameters/paramCheckrunID" + get: + tags: + - checkrun + operationId: getCheckrun + summary: | + get the specified check run. + responses: + "200": + description: Success + content: + application/json: + schema: + type: object + properties: + items: + type: array + properties: + id: + type: integer + description: "id of check run" + name: + type: string + description: "name of check run" + checkId: + type: integer + description: "check id of check run" + status: + type: string + description: "status of check run" + pipilineRunId: + type: integer + description: "pipelinerun id of check run" + detailUrl: + type: string + description: "detail url of check run" + message: + type: string + description: "message of check run" + createdAt: + type: string + updatedAt: + type: string + put: + tags: + - checkrun + operationId: updateCheckrun + summary: | + update the specified check run. + requestBody: + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: "name of check run" + checkId: + type: integer + description: "check id of check run" + status: + type: string + description: "status of check run" + message: + type: string + description: "message of check run" + detailUrl: + type: string + description: "detail url of check run" + responses: + "200": + description: Success /apis/core/v2/pipelineruns/{pipelinerunID}/message: parameters: - $ref: "common.yaml#/components/parameters/paramPipelinerunID" @@ -367,39 +448,39 @@ paths: description: "Success" get: tags: - - pipelinerun + - pipelinerun operationId: listMessage summary: | List message of the specified pipelinerun. responses: - "200": - description: Success - content: - application/json: - schema: - type: object - properties: - total: - type: integer - description: "total number of message" - data: - type: array - properties: - id: - type: integer - description: "id of message" - pipilineRunId: - type: integer - description: "pipelinerun id of message" - content: - type: string - description: "content of message" - createdAt: - type: string - createdBy: - $ref: "#/components/schemas/MessageUser" - updatedBy: - $ref: "#/components/schemas/MessageUser" + "200": + description: Success + content: + application/json: + schema: + type: object + properties: + total: + type: integer + description: "total number of message" + data: + type: array + properties: + id: + type: integer + description: "id of message" + pipilineRunId: + type: integer + description: "pipelinerun id of message" + content: + type: string + description: "content of message" + createdAt: + type: string + createdBy: + $ref: "#/components/schemas/MessageUser" + updatedBy: + $ref: "#/components/schemas/MessageUser" @@ -408,19 +489,19 @@ components: MessageUser: type: object properties: - id: - type: integer - name: - type: string - userType: - type: string + id: + type: integer + name: + type: string + userType: + type: string PipelineRun: type: object properties: action: type: string description: "action of pipelinerun" - enum: ["builddeploy", "deploy", "restart", "rollback"] + enum: [ "builddeploy", "deploy", "restart", "rollback" ] canRollback: type: boolean description: "whether this pipelinerun can be specified to rollback" @@ -457,7 +538,7 @@ components: description: "start time of pipelinerun" status: type: string - enum: ["ok", "waiting", "failed", "canceled"] + enum: [ "ok", "waiting", "failed", "canceled" ] title: type: string description: "title of pipelinerun" From c7189451c6cd1d98e78d2a0ae21515360a741afd Mon Sep 17 00:00:00 2001 From: "xu.zhu" Date: Wed, 18 Oct 2023 14:00:12 +0800 Subject: [PATCH 3/4] fix: 500 Signed-off-by: xu.zhu --- core/http/api/v2/tag/apis.go | 6 ++ openapi/v2/restful/pipelinerun.yaml | 91 +++++++++++------------------ 2 files changed, 39 insertions(+), 58 deletions(-) diff --git a/core/http/api/v2/tag/apis.go b/core/http/api/v2/tag/apis.go index 75710bdb..31036aee 100644 --- a/core/http/api/v2/tag/apis.go +++ b/core/http/api/v2/tag/apis.go @@ -99,6 +99,12 @@ func (a *API) Update(c *gin.Context) { response.AbortWithRPCError(c, rpcerror.ParamError.WithErrMsg(err.Error())) return } + if e, ok := perror.Cause(err).(*herrors.HorizonErrNotFound); ok { + if e.Source == herrors.ClusterInDB || e.Source == herrors.ApplicationInDB { + response.AbortWithRPCError(c, rpcerror.NotFoundError.WithErrMsg(err.Error())) + return + } + } log.WithFiled(c, "op", op).Errorf("%+v", err) response.AbortWithRPCError(c, rpcerror.InternalError.WithErrMsg(err.Error())) return diff --git a/openapi/v2/restful/pipelinerun.yaml b/openapi/v2/restful/pipelinerun.yaml index 4ba26b9f..fd0b47f1 100644 --- a/openapi/v2/restful/pipelinerun.yaml +++ b/openapi/v2/restful/pipelinerun.yaml @@ -320,36 +320,9 @@ paths: type: integer description: "total number of check runs" data: - type: object - properties: - items: - type: array - properties: - id: - type: integer - description: "id of check run" - name: - type: string - description: "name of check run" - checkId: - type: integer - description: "check id of check run" - status: - type: string - description: "status of check run" - pipilineRunId: - type: integer - description: "pipelinerun id of check run" - detailUrl: - type: string - description: "detail url of check run" - message: - type: string - description: "message of check run" - createdAt: - type: string - updatedAt: - type: string + type: array + items: + $ref: "#/components/schemas/Checkrun" /apis/core/v2/checkruns/{checkrunID}: parameters: - $ref: "common.yaml#/components/parameters/paramCheckrunID" @@ -367,34 +340,8 @@ paths: schema: type: object properties: - items: - type: array - properties: - id: - type: integer - description: "id of check run" - name: - type: string - description: "name of check run" - checkId: - type: integer - description: "check id of check run" - status: - type: string - description: "status of check run" - pipilineRunId: - type: integer - description: "pipelinerun id of check run" - detailUrl: - type: string - description: "detail url of check run" - message: - type: string - description: "message of check run" - createdAt: - type: string - updatedAt: - type: string + data: + $ref: "#/components/schemas/Checkrun" put: tags: - checkrun @@ -575,3 +522,31 @@ components: to: type: string description: "the last commit after the change" + Checkrun: + type: object + properties: + id: + type: integer + description: "id of check run" + name: + type: string + description: "name of check run" + checkId: + type: integer + description: "check id of check run" + status: + type: string + description: "status of check run" + pipilineRunId: + type: integer + description: "pipelinerun id of check run" + detailUrl: + type: string + description: "detail url of check run" + message: + type: string + description: "message of check run" + createdAt: + type: string + updatedAt: + type: string \ No newline at end of file From 4f2b1ad8fa2001f1526431a7390e25e52a7e2d3a Mon Sep 17 00:00:00 2001 From: "xu.zhu" Date: Thu, 19 Oct 2023 11:32:42 +0800 Subject: [PATCH 4/4] fix: add event for pr cancelled Signed-off-by: xu.zhu --- core/controller/pipelinerun/controller.go | 12 +++++++++++- pkg/event/manager/manager.go | 1 + pkg/event/models/event.go | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/controller/pipelinerun/controller.go b/core/controller/pipelinerun/controller.go index 51fc0d60..257da76d 100644 --- a/core/controller/pipelinerun/controller.go +++ b/core/controller/pipelinerun/controller.go @@ -36,6 +36,8 @@ import ( "github.com/horizoncd/horizon/pkg/config/token" envmanager "github.com/horizoncd/horizon/pkg/environment/manager" perror "github.com/horizoncd/horizon/pkg/errors" + eventmodels "github.com/horizoncd/horizon/pkg/event/models" + eventservice "github.com/horizoncd/horizon/pkg/event/service" membermanager "github.com/horizoncd/horizon/pkg/member" "github.com/horizoncd/horizon/pkg/param" prmanager "github.com/horizoncd/horizon/pkg/pr/manager" @@ -93,6 +95,7 @@ type controller struct { commitGetter code.GitGetter clusterGitRepo gitrepo.ClusterGitRepo userMgr usermanager.Manager + eventSvc eventservice.Service } var _ Controller = (*controller)(nil) @@ -113,6 +116,7 @@ func NewController(config *config.Config, param *param.Param) Controller { clusterGitRepo: param.ClusterGitRepo, userMgr: param.UserMgr, templateReleaseMgr: param.TemplateReleaseMgr, + eventSvc: param.EventSvc, } } @@ -496,7 +500,13 @@ func (c *controller) Cancel(ctx context.Context, pipelinerunID uint) error { if pr.Status != string(prmodels.StatusPending) && pr.Status != string(prmodels.StatusReady) { return perror.Wrapf(herrors.ErrParamInvalid, "pipelinerun is not pending or ready to cancel") } - return c.prMgr.PipelineRun.UpdateStatusByID(ctx, pipelinerunID, prmodels.StatusCancelled) + err = c.prMgr.PipelineRun.UpdateStatusByID(ctx, pipelinerunID, prmodels.StatusCancelled) + if err != nil { + return err + } + c.eventSvc.CreateEventIgnoreError(ctx, common.ResourcePipelinerun, pipelinerunID, + eventmodels.PipelinerunCancelled, nil) + return nil } func (c *controller) ListCheckRuns(ctx context.Context, pipelinerunID uint) ([]*prmodels.CheckRun, error) { diff --git a/pkg/event/manager/manager.go b/pkg/event/manager/manager.go index 2a456d5c..0d39e4b5 100644 --- a/pkg/event/manager/manager.go +++ b/pkg/event/manager/manager.go @@ -141,6 +141,7 @@ var supportedEvents = map[string]string{ models.MemberUpdated: "Member has been updated", models.MemberDeleted: "Member has been deleted", models.PipelinerunCreated: "New pipelinerun has been created", + models.PipelinerunCancelled: "Pipelinerun has been cancelled", } func (m *manager) ListSupportEvents() map[string]string { diff --git a/pkg/event/models/event.go b/pkg/event/models/event.go index 13e2389b..d9d0cfda 100644 --- a/pkg/event/models/event.go +++ b/pkg/event/models/event.go @@ -42,6 +42,7 @@ const ( MemberUpdated string = "members_updated" MemberDeleted string = "members_deleted" PipelinerunCreated string = "pipelineruns_created" + PipelinerunCancelled string = "pipelineruns_cancelled" // TODO: add group events )