From 3d12019e23c5b70884d21d0786887b6f7680677b Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 26 Nov 2020 15:18:49 +0800 Subject: [PATCH] Mix up the pipeline list between ks and Jenkins Technically we should take the Pipeline list from ks or mixup the instead of only taking it from Jenkins. Because we always manipulate Pipeline from ks. Signed-off-by: rick --- pkg/kapis/devops/v1alpha2/devops.go | 72 +++++++++++++++++++++++++++- pkg/kapis/devops/v1alpha3/handler.go | 2 +- pkg/models/devops/devops.go | 13 ++++- pkg/simple/client/devops/pipeline.go | 2 +- 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/pkg/kapis/devops/v1alpha2/devops.go b/pkg/kapis/devops/v1alpha2/devops.go index f9d8ca52c..62c587eed 100644 --- a/pkg/kapis/devops/v1alpha2/devops.go +++ b/pkg/kapis/devops/v1alpha2/devops.go @@ -24,12 +24,14 @@ import ( "k8s.io/apiserver/pkg/authentication/user" log "k8s.io/klog" "kubesphere.io/kubesphere/pkg/api" + "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3" iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" "kubesphere.io/kubesphere/pkg/apiserver/request" "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/models/devops" clientDevOps "kubesphere.io/kubesphere/pkg/simple/client/devops" "net/http" + "strconv" "strings" ) @@ -49,15 +51,81 @@ func (h *ProjectPipelineHandler) GetPipeline(req *restful.Request, resp *restful resp.WriteAsJson(res) } +func (h *ProjectPipelineHandler) getPipelinesByRequest(req *restful.Request) (api.ListResult, error) { + // this is a very trick way, but don't have a better solution for now + var ( + err error + start int + limit int + namespace string + ) + + // parse query from the request + query := req.QueryParameter("q") + req.Request.PostForm.Set("limit", "1000") + for _, val := range strings.Split(query, ";") { + if strings.HasPrefix(val, "pipeline:") { + namespace = strings.TrimLeft(val, "pipeline:") + namespace = strings.Split(namespace, "/")[0] + } + } + + // make sure we have an appropriate value + if start, err = strconv.Atoi(req.QueryParameter("start")); err != nil { + start = 0 + } + if limit, err = strconv.Atoi(req.QueryParameter("limit")); err != nil { + limit = 10 + } + + defer req.Request.Form.Set("limit", "10000") // assume the pipelines no more than 10k + + return h.devopsOperator.ListPipelineObj(namespace, func(list []*v1alpha3.Pipeline, i int, j int) bool { + return strings.Compare(list[i].Name, list[j].Name) < 0 + }, limit, start) +} + func (h *ProjectPipelineHandler) ListPipelines(req *restful.Request, resp *restful.Response) { - res, err := h.devopsOperator.ListPipelines(req.Request) + objs, err := h.getPipelinesByRequest(req) if err != nil { parseErr(err, resp) return } + // get all pipelines which come from ks + pipelineList := &clientDevOps.PipelineList{ + Total: objs.TotalItems, + Items: make([]clientDevOps.Pipeline, objs.TotalItems), + } + pipelineMap := make(map[string]int, objs.TotalItems) + for i, item := range objs.Items { + if pipeline, ok := item.(v1alpha3.Pipeline); !ok { + continue + } else { + pip := clientDevOps.Pipeline{ + Name: pipeline.Name, + } + + pipelineMap[pipeline.Name] = i + pipelineList.Items[i] = pip + } + } + + // get all pipelines which come from Jenkins + // fill out the rest fields + res, err := h.devopsOperator.ListPipelines(req.Request) + if err != nil { + log.Error(err) + } else { + for _, item := range res.Items { + if index, ok := pipelineMap[item.Name]; ok { + pipelineList.Items[index] = item + } + } + } + resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON) - resp.WriteAsJson(res) + resp.WriteAsJson(pipelineList) } func (h *ProjectPipelineHandler) GetPipelineRun(req *restful.Request, resp *restful.Response) { diff --git a/pkg/kapis/devops/v1alpha3/handler.go b/pkg/kapis/devops/v1alpha3/handler.go index 62314b198..52cb29500 100644 --- a/pkg/kapis/devops/v1alpha3/handler.go +++ b/pkg/kapis/devops/v1alpha3/handler.go @@ -184,7 +184,7 @@ func (h *devopsHandler) ListPipeline(request *restful.Request, response *restful devops := request.PathParameter("devops") limit, offset := params.ParsePaging(request) - objs, err := h.devops.ListPipelineObj(devops, limit, offset) + objs, err := h.devops.ListPipelineObj(devops, nil, limit, offset) if err != nil { klog.Error(err) if errors.IsNotFound(err) { diff --git a/pkg/models/devops/devops.go b/pkg/models/devops/devops.go index 550fc3a33..262fe01cd 100644 --- a/pkg/models/devops/devops.go +++ b/pkg/models/devops/devops.go @@ -41,6 +41,7 @@ import ( resourcesV1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3" "kubesphere.io/kubesphere/pkg/simple/client/devops" "net/http" + "sort" "sync" ) @@ -59,7 +60,7 @@ type DevopsOperator interface { GetPipelineObj(projectName string, pipelineName string) (*v1alpha3.Pipeline, error) DeletePipelineObj(projectName string, pipelineName string) error UpdatePipelineObj(projectName string, pipeline *v1alpha3.Pipeline) (*v1alpha3.Pipeline, error) - ListPipelineObj(projectName string, limit, offset int) (api.ListResult, error) + ListPipelineObj(projectName string, sortFunc func([]*v1alpha3.Pipeline, int, int) bool, limit, offset int) (api.ListResult, error) CreateCredentialObj(projectName string, s *v1.Secret) (*v1.Secret, error) GetCredentialObj(projectName string, secretName string) (*v1.Secret, error) @@ -254,7 +255,7 @@ func (d devopsOperator) UpdatePipelineObj(projectName string, pipeline *v1alpha3 return d.ksclient.DevopsV1alpha3().Pipelines(projectObj.Status.AdminNamespace).Update(pipeline) } -func (d devopsOperator) ListPipelineObj(projectName string, limit, offset int) (api.ListResult, error) { +func (d devopsOperator) ListPipelineObj(projectName string, sortFunc func([]*v1alpha3.Pipeline, int, int) bool, limit, offset int) (api.ListResult, error) { projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return api.ListResult{}, err @@ -263,6 +264,14 @@ func (d devopsOperator) ListPipelineObj(projectName string, limit, offset int) ( if err != nil { return api.ListResult{}, err } + + // sort the pipeline list according to the request + if sortFunc != nil { + sort.SliceStable(data, func(i, j int) bool { + return sortFunc(data, i, j) + }) + } + items := make([]interface{}, 0) var result []interface{} for _, item := range data { diff --git a/pkg/simple/client/devops/pipeline.go b/pkg/simple/client/devops/pipeline.go index 0eb78db04..3f0ed64bd 100644 --- a/pkg/simple/client/devops/pipeline.go +++ b/pkg/simple/client/devops/pipeline.go @@ -81,7 +81,7 @@ type Pipeline struct { NumberOfFolders int `json:"numberOfFolders,omitempty" description:"number of folders"` NumberOfPipelines int `json:"numberOfPipelines,omitempty" description:"number of pipelines"` PipelineFolderNames []interface{} `json:"pipelineFolderNames,omitempty" description:"pipeline folder names"` - WeatherScore int `json:"weatherScore,omitempty" description:"the score to description the result of pipeline activity"` + WeatherScore int `json:"weatherScore" description:"the score to description the result of pipeline activity"` BranchNames []string `json:"branchNames,omitempty" description:"branch names"` NumberOfFailingBranches int `json:"numberOfFailingBranches,omitempty" description:"number of failing branches"` NumberOfFailingPullRequests int `json:"numberOfFailingPullRequests,omitempty" description:"number of failing pull requests"`