diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index bd255d7b1d6a653d62a2cc184b58cf1a5d98a0fa..c569c769b91979c0f6896888c134c70a06593f5b 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -366,6 +366,8 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error { {Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuildertemplates"}, {Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2iruns"}, {Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuilders"}, + {Group: "devops.kubesphere.io", Version: "v1alpha3", Resource: "devopsprojects"}, + {Group: "devops.kubesphere.io", Version: "v1alpha3", Resource: "pipelines"}, } servicemeshGVRs := []schema.GroupVersionResource{ diff --git a/pkg/kapis/devops/v1alpha3/handler.go b/pkg/kapis/devops/v1alpha3/handler.go index 32573a0306388c18fa0c0b6a21992063e3aa41c7..cf7ab747da7e6e83681a02a01808e7c1839307fd 100644 --- a/pkg/kapis/devops/v1alpha3/handler.go +++ b/pkg/kapis/devops/v1alpha3/handler.go @@ -29,6 +29,7 @@ import ( "kubesphere.io/kubesphere/pkg/client/informers/externalversions" "kubesphere.io/kubesphere/pkg/models/devops" servererr "kubesphere.io/kubesphere/pkg/server/errors" + "kubesphere.io/kubesphere/pkg/server/params" devopsClient "kubesphere.io/kubesphere/pkg/simple/client/devops" ) @@ -67,8 +68,9 @@ func (h *devopsHandler) GetDevOpsProject(request *restful.Request, response *res func (h *devopsHandler) ListDevOpsProject(request *restful.Request, response *restful.Response) { workspace := request.PathParameter("workspace") + limit, offset := params.ParsePaging(request) - projectList, err := h.devops.ListDevOpsProject(workspace) + projectList, err := h.devops.ListDevOpsProject(workspace, limit, offset) if err != nil { klog.Error(err) @@ -176,8 +178,9 @@ func (h *devopsHandler) GetPipeline(request *restful.Request, response *restful. func (h *devopsHandler) ListPipeline(request *restful.Request, response *restful.Response) { devops := request.PathParameter("devops") - objs, err := h.devops.ListPipelineObj(devops) + limit, offset := params.ParsePaging(request) + objs, err := h.devops.ListPipelineObj(devops, limit, offset) if err != nil { klog.Error(err) if errors.IsNotFound(err) { @@ -285,8 +288,9 @@ func (h *devopsHandler) GetCredential(request *restful.Request, response *restfu func (h *devopsHandler) ListCredential(request *restful.Request, response *restful.Response) { devops := request.PathParameter("devops") + limit, offset := params.ParsePaging(request) - objs, err := h.devops.ListCredentialObj(devops) + objs, err := h.devops.ListCredentialObj(devops, limit, offset) if err != nil { klog.Error(err) diff --git a/pkg/kapis/devops/v1alpha3/register.go b/pkg/kapis/devops/v1alpha3/register.go index 9431482d97f4d366f1aa949e7d59666e318144a7..8bc4cea94fc23a7c6d8461a47c3dad23dd3888cf 100644 --- a/pkg/kapis/devops/v1alpha3/register.go +++ b/pkg/kapis/devops/v1alpha3/register.go @@ -31,6 +31,7 @@ import ( kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned" "kubesphere.io/kubesphere/pkg/client/informers/externalversions" "kubesphere.io/kubesphere/pkg/constants" + "kubesphere.io/kubesphere/pkg/server/params" devopsClient "kubesphere.io/kubesphere/pkg/simple/client/devops" "net/http" ) @@ -54,8 +55,12 @@ func AddToContainer(container *restful.Container, devopsClient devopsClient.Inte ws.Route(ws.GET("/devops/{devops}/credentials"). To(handler.ListCredential). Param(ws.PathParameter("devops", "devops name")). + Param(ws.QueryParameter(params.PagingParam, "paging query, e.g. limit=100,page=1"). + Required(false). + DataFormat("limit=%d,page=%d"). + DefaultValue("limit=10,page=1")). Doc("list the credentials of the specified devops for the current user"). - Returns(http.StatusOK, api.StatusOK, []v1alpha3.PipelineList{}). + Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag})) ws.Route(ws.POST("/devops/{devops}/credentials"). @@ -95,8 +100,12 @@ func AddToContainer(container *restful.Container, devopsClient devopsClient.Inte ws.Route(ws.GET("/devops/{devops}/pipelines"). To(handler.ListPipeline). Param(ws.PathParameter("devops", "devops name")). + Param(ws.QueryParameter(params.PagingParam, "paging query, e.g. limit=100,page=1"). + Required(false). + DataFormat("limit=%d,page=%d"). + DefaultValue("limit=10,page=1")). Doc("list the pipelines of the specified devops for the current user"). - Returns(http.StatusOK, api.StatusOK, []v1alpha3.PipelineList{}). + Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag})) ws.Route(ws.POST("/devops/{devops}/pipelines"). @@ -134,8 +143,11 @@ func AddToContainer(container *restful.Container, devopsClient devopsClient.Inte ws.Route(ws.GET("/workspaces/{workspace}/devops"). To(handler.ListDevOpsProject). Param(ws.PathParameter("workspace", "workspace name")). - Doc("List the devopsproject of the specified workspace for the current user"). - Returns(http.StatusOK, api.StatusOK, []v1alpha3.DevOpsProjectList{}). + Param(ws.QueryParameter(params.PagingParam, "paging query, e.g. limit=100,page=1"). + Required(false). + DataFormat("limit=%d,page=%d"). + DefaultValue("limit=10,page=1")).Doc("List the devopsproject of the specified workspace for the current user"). + Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag})) ws.Route(ws.POST("/workspaces/{workspace}/devops"). diff --git a/pkg/models/devops/devops.go b/pkg/models/devops/devops.go index 3531bca3fd40629596d17663e3f96a33ded90f67..06b49a204d3b6bdbc388b38de42770b858ca86dc 100644 --- a/pkg/models/devops/devops.go +++ b/pkg/models/devops/devops.go @@ -24,9 +24,11 @@ import ( "io/ioutil" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/klog" + "kubesphere.io/kubesphere/pkg/api" "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned" @@ -45,19 +47,19 @@ type DevopsOperator interface { GetDevOpsProject(workspace string, projectName string) (*v1alpha3.DevOpsProject, error) DeleteDevOpsProject(workspace string, projectName string) error UpdateDevOpsProject(workspace string, project *v1alpha3.DevOpsProject) (*v1alpha3.DevOpsProject, error) - ListDevOpsProject(workspace string) (*v1alpha3.DevOpsProjectList, error) + ListDevOpsProject(workspace string, limit, offset int) (api.ListResult, error) CreatePipelineObj(projectName string, pipeline *v1alpha3.Pipeline) (*v1alpha3.Pipeline, error) 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) (*v1alpha3.PipelineList, error) + ListPipelineObj(projectName string, limit, offset int) (api.ListResult, error) CreateCredentialObj(projectName string, s *v1.Secret) (*v1.Secret, error) GetCredentialObj(projectName string, secretName string) (*v1.Secret, error) DeleteCredentialObj(projectName string, secretName string) error UpdateCredentialObj(projectName string, secret *v1.Secret) (*v1.Secret, error) - ListCredentialObj(projectName string) (*v1.SecretList, error) + ListCredentialObj(projectName string, limit, offset int) (api.ListResult, error) GetPipeline(projectName, pipelineName string, req *http.Request) (*devops.Pipeline, error) ListPipelines(req *http.Request) (*devops.PipelineList, error) @@ -146,7 +148,7 @@ func (d devopsOperator) CreateDevOpsProject(workspace string, project *v1alpha3. } func (d devopsOperator) GetDevOpsProject(workspace string, projectName string) (*v1alpha3.DevOpsProject, error) { - return d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + return d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) } func (d devopsOperator) DeleteDevOpsProject(workspace string, projectName string) error { @@ -158,13 +160,27 @@ func (d devopsOperator) UpdateDevOpsProject(workspace string, project *v1alpha3. return d.ksclient.DevopsV1alpha3().DevOpsProjects().Update(project) } -func (d devopsOperator) ListDevOpsProject(workspace string) (*v1alpha3.DevOpsProjectList, error) { - return d.ksclient.DevopsV1alpha3().DevOpsProjects().List(metav1.ListOptions{}) +func (d devopsOperator) ListDevOpsProject(workspace string, limit, offset int) (api.ListResult, error) { + data, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().List(labels.SelectorFromValidatedSet(labels.Set{tenantv1alpha1.WorkspaceLabel: workspace})) + if err != nil { + return api.ListResult{}, nil + } + items := make([]interface{}, 0) + var result []interface{} + for _, item := range data { + result = append(result, *item) + } + + if limit == -1 || limit+offset > len(result) { + limit = len(result) - offset + } + items = result[offset : offset+limit] + return api.ListResult{TotalItems: len(result), Items: items}, nil } // pipelineobj in crd func (d devopsOperator) CreatePipelineObj(projectName string, pipeline *v1alpha3.Pipeline) (*v1alpha3.Pipeline, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return nil, err } @@ -172,15 +188,15 @@ func (d devopsOperator) CreatePipelineObj(projectName string, pipeline *v1alpha3 } func (d devopsOperator) GetPipelineObj(projectName string, pipelineName string) (*v1alpha3.Pipeline, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return nil, err } - return d.ksclient.DevopsV1alpha3().Pipelines(projectObj.Status.AdminNamespace).Get(pipelineName, metav1.GetOptions{}) + return d.ksInformers.Devops().V1alpha3().Pipelines().Lister().Pipelines(projectObj.Status.AdminNamespace).Get(pipelineName) } func (d devopsOperator) DeletePipelineObj(projectName string, pipelineName string) error { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return err } @@ -188,24 +204,38 @@ func (d devopsOperator) DeletePipelineObj(projectName string, pipelineName strin } func (d devopsOperator) UpdatePipelineObj(projectName string, pipeline *v1alpha3.Pipeline) (*v1alpha3.Pipeline, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return nil, err } return d.ksclient.DevopsV1alpha3().Pipelines(projectObj.Status.AdminNamespace).Update(pipeline) } -func (d devopsOperator) ListPipelineObj(projectName string) (*v1alpha3.PipelineList, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) +func (d devopsOperator) ListPipelineObj(projectName string, limit, offset int) (api.ListResult, error) { + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { - return nil, err + return api.ListResult{}, err } - return d.ksclient.DevopsV1alpha3().Pipelines(projectObj.Status.AdminNamespace).List(metav1.ListOptions{}) + data, err := d.ksInformers.Devops().V1alpha3().Pipelines().Lister().Pipelines(projectObj.Status.AdminNamespace).List(labels.Everything()) + if err != nil { + return api.ListResult{}, nil + } + items := make([]interface{}, 0) + var result []interface{} + for _, item := range data { + result = append(result, *item) + } + + if limit == -1 || limit+offset > len(result) { + limit = len(result) - offset + } + items = result[offset : offset+limit] + return api.ListResult{TotalItems: len(result), Items: items}, nil } //credentialobj in crd func (d devopsOperator) CreateCredentialObj(projectName string, secret *v1.Secret) (*v1.Secret, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return nil, err } @@ -213,15 +243,15 @@ func (d devopsOperator) CreateCredentialObj(projectName string, secret *v1.Secre } func (d devopsOperator) GetCredentialObj(projectName string, secretName string) (*v1.Secret, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return nil, err } - return d.k8sclient.CoreV1().Secrets(projectObj.Status.AdminNamespace).Get(secretName, metav1.GetOptions{}) + return d.k8sInformers.Core().V1().Secrets().Lister().Secrets(projectObj.Status.AdminNamespace).Get(secretName) } func (d devopsOperator) DeleteCredentialObj(projectName string, secret string) error { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return err } @@ -229,19 +259,46 @@ func (d devopsOperator) DeleteCredentialObj(projectName string, secret string) e } func (d devopsOperator) UpdateCredentialObj(projectName string, secret *v1.Secret) (*v1.Secret, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { return nil, err } return d.k8sclient.CoreV1().Secrets(projectObj.Status.AdminNamespace).Update(secret) } -func (d devopsOperator) ListCredentialObj(projectName string) (*v1.SecretList, error) { - projectObj, err := d.ksclient.DevopsV1alpha3().DevOpsProjects().Get(projectName, metav1.GetOptions{}) +func (d devopsOperator) ListCredentialObj(projectName string, limit, offset int) (api.ListResult, error) { + projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) if err != nil { - return nil, err + return api.ListResult{}, err + } + + credentialList, err := d.k8sInformers.Core().V1().Secrets().Lister().Secrets(projectObj.Status.AdminNamespace).List(labels.Everything()) + if err != nil { + return api.ListResult{}, err + } + + items := make([]interface{}, 0) + var result []interface{} + + credentialTypeList := []v1.SecretType{ + v1alpha3.SecretTypeBasicAuth, + v1alpha3.SecretTypeSSHAuth, + v1alpha3.SecretTypeSecretText, + v1alpha3.SecretTypeKubeConfig, + } + for _, credential := range credentialList { + for _, credentialType := range credentialTypeList { + if credential.Type == credentialType { + result = append(result, *credential) + } + } + } + + if limit == -1 || limit+offset > len(result) { + limit = len(result) - offset } - return d.k8sclient.CoreV1().Secrets(projectObj.Status.AdminNamespace).List(metav1.ListOptions{}) + items = result[offset : offset+limit] + return api.ListResult{TotalItems: len(result), Items: items}, nil } // others