Devops refactor (#1894)

* add devops client interface

Signed-off-by: runzexia <runzexia@yunify.com>

* direct return jenkins

Signed-off-by: runzexia <runzexia@yunify.com>

* add some interface

Signed-off-by: runzexia <runzexia@yunify.com>

* update

Signed-off-by: runzexia <runzexia@yunify.com>

* update interface

Signed-off-by: runzexia <runzexia@yunify.com>

* update

Signed-off-by: runzexia <runzexia@yunify.com>

* credential op structs

Signed-off-by: runzexia <runzexia@yunify.com>

* status

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* update interface

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* credential handler

Signed-off-by: runzexia <runzexia@yunify.com>

* update devopsoperator func

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* get build sonar

Signed-off-by: runzexia <runzexia@yunify.com>

* sonar handler

* mv code to cilent

Signed-off-by: runzexia <runzexia@yunify.com>

* update

Signed-off-by: runzexia <runzexia@yunify.com>

* project member handler

Signed-off-by: runzexia <runzexia@yunify.com>

* update pipeline operator interface

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add tenant devops handler

Signed-off-by: runzexia <runzexia@yunify.com>

* update merge

Signed-off-by: runzexia <runzexia@yunify.com>

* clean

Signed-off-by: runzexia <runzexia@yunify.com>

* fmt

Signed-off-by: runzexia <runzexia@yunify.com>

* update ListPipelineRuns

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* complate pipelineOperator interface

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* update HttpParameters

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add pipeline steps interface

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* update pipeline GetNodesDetail

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add s2i api

Signed-off-by: runzexia <runzexia@yunify.com>

* add branch pipeline interface and update handler

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add scan branch interface and update handler

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add common interface and update handler

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add SCM interface and update handler

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add handler

Signed-off-by: runzexia <runzexia@yunify.com>

* add fake s3

Signed-off-by: runzexia <runzexia@yunify.com>

* add webhook&check interface and update handler

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* clean

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* clean

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* format

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add some func

Signed-off-by: runzexia <runzexia@yunify.com>

* clean code

Signed-off-by: runzexia <runzexia@yunify.com>

* implement interface

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* fix interface GetBranchArtifacts

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add s2ibinary upload test

Signed-off-by: runzexia <runzexia@yunify.com>

* tenant devops

Signed-off-by: runzexia <runzexia@yunify.com>

* update tenant

Signed-off-by: runzexia <runzexia@yunify.com>

* fake

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add some unit test

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* add devops tenant handler

Signed-off-by: runzexia <runzexia@yunify.com>

* status

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* status

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* status

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* update fake test

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* update unit test and fake data

Signed-off-by: zhuxiaoyang <sunzhu@yunify.com>

* update

* enable devops client

Signed-off-by: runzexia <runzexia@yunify.com>

* enable devops client

Signed-off-by: runzexia <runzexia@yunify.com>

Co-authored-by: Xiaoyang Zhu <sunzhu@yunify.com>
This commit is contained in:
runzexia
2020-02-24 15:39:04 +08:00
committed by GitHub
parent c5a340a2b4
commit 96aee0e60b
5 changed files with 705 additions and 690 deletions

View File

@@ -211,7 +211,6 @@ func checkResourceQuotas(wokrspace *v1alpha1.Workspace) error {
return nil
}
func ListNamespaceRules(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
username := req.HeaderParameter(constants.UserNameHeader)

View File

@@ -20,6 +20,7 @@ type ProjectPipelineHandler struct {
type PipelineSonarHandler struct {
pipelineSonarGetter devops.PipelineSonarGetter
projectOperator devops.ProjectOperator
}
func NewProjectPipelineHandler(devopsClient devopsClient.Interface, dbClient *mysql.Database) ProjectPipelineHandler {
@@ -32,12 +33,14 @@ func NewProjectPipelineHandler(devopsClient devopsClient.Interface, dbClient *my
}
}
func NewPipelineSonarHandler(devopsClient devopsClient.Interface, sonarClient sonarqube.SonarInterface) PipelineSonarHandler {
func NewPipelineSonarHandler(devopsClient devopsClient.Interface, dbClient *mysql.Database, sonarClient sonarqube.SonarInterface) PipelineSonarHandler {
return PipelineSonarHandler{
pipelineSonarGetter: devops.NewPipelineSonarGetter(devopsClient, sonarClient),
projectOperator: devops.NewProjectOperator(dbClient),
}
}
func NewS2iBinaryHandler(client versioned.Interface, informers externalversions.SharedInformerFactory, s3Client s3.Interface) S2iBinaryHandler {
return S2iBinaryHandler{devops.NewS2iBinaryUploader(client, informers, s3Client)}
}

View File

@@ -38,9 +38,9 @@ func (h ProjectPipelineHandler) GetDevOpsProjectMembersHandler(request *restful.
return
}
orderBy := request.QueryParameter(params.OrderByParam)
reverse := params.ParseReverse(request)
limit, offset := params.ParsePaging(request.QueryParameter(params.PagingParam))
conditions, err := params.ParseConditions(request.QueryParameter(params.ConditionsParam))
reverse := params.GetBoolValueWithDefault(request, params.ReverseParam, false)
limit, offset := params.ParsePaging(request)
conditions, err := params.ParseConditions(request)
project, err := h.projectMemberOperator.GetProjectMembers(projectId, conditions, orderBy, reverse, limit, offset)

View File

@@ -4,8 +4,8 @@ import (
"github.com/emicklei/go-restful"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/http"
)
@@ -13,7 +13,7 @@ func (h PipelineSonarHandler) GetPipelineSonarStatusHandler(request *restful.Req
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
pipelineId := request.PathParameter("pipeline")
err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
err := h.projectOperator.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
@@ -33,7 +33,7 @@ func (h PipelineSonarHandler) GetMultiBranchesPipelineSonarStatusHandler(request
username := request.HeaderParameter(constants.UserNameHeader)
pipelineId := request.PathParameter("pipeline")
branchId := request.PathParameter("branch")
err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
err := h.projectOperator.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)

View File

@@ -25,7 +25,13 @@ import (
"kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
//"kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
@@ -40,21 +46,40 @@ const (
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
var (
WebServiceBuilder = runtime.NewContainerBuilder(addWebService)
AddToContainer = WebServiceBuilder.AddToContainer
)
func addWebService(c *restful.Container) error {
func addWebService(c *restful.Container, devopsClient devops.Interface,
dbClient *mysql.Database, sonarClient sonarqube.SonarInterface, ksClient versioned.Interface,
ksInformer externalversions.SharedInformerFactory, s3Client s3.Interface) error {
webservice := runtime.NewWebService(GroupVersion)
sonarHandler := NewPipelineSonarHandler()
sonarEnable := devopsClient != nil && dbClient != nil && sonarClient != nil
projectPipleineEnable := devopsClient != nil && dbClient != nil
s2iEnable := ksClient != nil && ksInformer != nil && s3Client != nil
projectPipelineHander := NewProjectPipelineHandler()
if sonarEnable {
sonarHandler := NewPipelineSonarHandler(devopsClient, dbClient, sonarClient)
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/sonarstatus").
To(sonarHandler.GetPipelineSonarStatusHandler).
Doc("Get the sonar quality information for the specified pipeline of the DevOps project. More info: https://docs.sonarqube.org/7.4/user-guide/metric-definitions/").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of pipeline, e.g. sample-pipeline")).
Returns(http.StatusOK, RespOK, []sonarqube.SonarStatus{}).
Writes([]sonarqube.SonarStatus{}))
s2iHandler := NewS2iBinaryHandler()
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/sonarstatus").
To(sonarHandler.GetMultiBranchesPipelineSonarStatusHandler).
Doc("Get the sonar quality check information for the specified pipeline branch of the DevOps project. More info: https://docs.sonarqube.org/7.4/user-guide/metric-definitions/").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of pipeline, e.g. sample-pipeline")).
Param(webservice.PathParameter("branch", "branch name, e.g. master")).
Returns(http.StatusOK, RespOK, []sonarqube.SonarStatus{}).
Writes([]sonarqube.SonarStatus{}))
}
if projectPipleineEnable{
projectPipelineHander := NewProjectPipelineHandler(devopsClient, dbClient)
webservice.Route(webservice.GET("/devops/{devops}").
To(projectPipelineHander.GetDevOpsProjectHandler).
Doc("Get the specified DevOps Project").
@@ -92,8 +117,8 @@ func addWebService(c *restful.Container) error {
Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, support using key-value pairs separated by comma to search, like 'conditions:somekey=somevalue,anotherkey=anothervalue'").
Required(false).
DataFormat("key=%s,key~%s")).
Returns(http.StatusOK, RespOK, []devops.DevOpsProjectMembership{}).
Writes([]devops.DevOpsProjectMembership{}))
Returns(http.StatusOK, RespOK, []devops.ProjectMembership{}).
Writes([]devops.ProjectMembership{}))
webservice.Route(webservice.GET("/devops/{devops}/members/{member}").
To(projectPipelineHander.GetDevOpsProjectMemberHandler).
@@ -101,17 +126,17 @@ func addWebService(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("member", "member's username, e.g. admin")).
Returns(http.StatusOK, RespOK, devops.DevOpsProjectMembership{}).
Writes(devops.DevOpsProjectMembership{}))
Returns(http.StatusOK, RespOK, devops.ProjectMembership{}).
Writes(devops.ProjectMembership{}))
webservice.Route(webservice.POST("/devops/{devops}/members").
To(projectPipelineHander.AddDevOpsProjectMemberHandler).
Doc("Add a member to the specified DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Returns(http.StatusOK, RespOK, devops.DevOpsProjectMembership{}).
Writes(devops.DevOpsProjectMembership{}).
Reads(devops.DevOpsProjectMembership{}))
Returns(http.StatusOK, RespOK, devops.ProjectMembership{}).
Writes(devops.ProjectMembership{}).
Reads(devops.ProjectMembership{}))
webservice.Route(webservice.PATCH("/devops/{devops}/members/{member}").
To(projectPipelineHander.UpdateDevOpsProjectMemberHandler).
@@ -119,9 +144,9 @@ func addWebService(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("member", "member's username, e.g. admin")).
Returns(http.StatusOK, RespOK, devops.DevOpsProjectMembership{}).
Reads(devops.DevOpsProjectMembership{}).
Writes(devops.DevOpsProjectMembership{}))
Returns(http.StatusOK, RespOK, devops.ProjectMembership{}).
Reads(devops.ProjectMembership{}).
Writes(devops.ProjectMembership{}))
webservice.Route(webservice.DELETE("/devops/{devops}/members/{member}").
To(projectPipelineHander.DeleteDevOpsProjectMemberHandler).
@@ -129,7 +154,7 @@ func addWebService(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("member", "member's username, e.g. admin")).
Writes(devops.DevOpsProjectMembership{}))
Writes(devops.ProjectMembership{}))
webservice.Route(webservice.POST("/devops/{devops}/pipelines").
To(projectPipelineHander.CreateDevOpsProjectPipelineHandler).
@@ -165,24 +190,7 @@ func addWebService(c *restful.Container) error {
Returns(http.StatusOK, RespOK, devops.ProjectPipeline{}).
Writes(devops.ProjectPipeline{}))
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/sonarstatus").
To(sonarHandler.GetPipelineSonarStatusHandler).
Doc("Get the sonar quality information for the specified pipeline of the DevOps project. More info: https://docs.sonarqube.org/7.4/user-guide/metric-definitions/").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of pipeline, e.g. sample-pipeline")).
Returns(http.StatusOK, RespOK, []devops.SonarStatus{}).
Writes([]devops.SonarStatus{}))
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/sonarstatus").
To(sonarHandler.GetMultiBranchesPipelineSonarStatusHandler).
Doc("Get the sonar quality check information for the specified pipeline branch of the DevOps project. More info: https://docs.sonarqube.org/7.4/user-guide/metric-definitions/").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of pipeline, e.g. sample-pipeline")).
Param(webservice.PathParameter("branch", "branch name, e.g. master")).
Returns(http.StatusOK, RespOK, []devops.SonarStatus{}).
Writes([]devops.SonarStatus{}))
webservice.Route(webservice.POST("/devops/{devops}/credentials").
To(projectPipelineHander.CreateDevOpsProjectCredentialHandler).
@@ -729,26 +737,6 @@ The last one is encrypted info, such as the password of the username-password ty
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
Doc("Get commit notification. Github webhook will request here."))
webservice.Route(webservice.PUT("/namespaces/{namespace}/s2ibinaries/{s2ibinary}/file").
To(s2iHandler.UploadS2iBinaryHandler).
Consumes("multipart/form-data").
Produces(restful.MIME_JSON).
Doc("Upload S2iBinary file").
Param(webservice.PathParameter("namespace", "the name of namespaces")).
Param(webservice.PathParameter("s2ibinary", "the name of s2ibinary")).
Param(webservice.FormParameter("s2ibinary", "file to upload")).
Param(webservice.FormParameter("md5", "md5 of file")).
Returns(http.StatusOK, RespOK, devopsv1alpha1.S2iBinary{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/s2ibinaries/{s2ibinary}/file/{file}").
To(s2iHandler.DownloadS2iBinaryHandler).
Produces(restful.MIME_OCTET).
Doc("Download S2iBinary file").
Param(webservice.PathParameter("namespace", "the name of namespaces")).
Param(webservice.PathParameter("s2ibinary", "the name of s2ibinary")).
Param(webservice.PathParameter("file", "the name of binary file")).
Returns(http.StatusOK, RespOK, nil))
webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/checkScriptCompile").
To(projectPipelineHander.CheckScriptCompile).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
@@ -795,6 +783,31 @@ The last one is encrypted info, such as the password of the username-password ty
Reads(devops.ReqJenkinsfile{}).
Returns(http.StatusOK, RespOK, devops.ResJson{}).
Writes(devops.ResJson{}))
}
if s2iEnable {
s2iHandler := NewS2iBinaryHandler(ksClient, ksInformer, s3Client)
webservice.Route(webservice.PUT("/namespaces/{namespace}/s2ibinaries/{s2ibinary}/file").
To(s2iHandler.UploadS2iBinaryHandler).
Consumes("multipart/form-data").
Produces(restful.MIME_JSON).
Doc("Upload S2iBinary file").
Param(webservice.PathParameter("namespace", "the name of namespaces")).
Param(webservice.PathParameter("s2ibinary", "the name of s2ibinary")).
Param(webservice.FormParameter("s2ibinary", "file to upload")).
Param(webservice.FormParameter("md5", "md5 of file")).
Returns(http.StatusOK, RespOK, devopsv1alpha1.S2iBinary{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/s2ibinaries/{s2ibinary}/file/{file}").
To(s2iHandler.DownloadS2iBinaryHandler).
Produces(restful.MIME_OCTET).
Doc("Download S2iBinary file").
Param(webservice.PathParameter("namespace", "the name of namespaces")).
Param(webservice.PathParameter("s2ibinary", "the name of s2ibinary")).
Param(webservice.PathParameter("file", "the name of binary file")).
Returns(http.StatusOK, RespOK, nil))
}
c.Add(webservice)