Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a new API to download artifacts from a PipelineRun #479

Merged
merged 11 commits into from
Mar 18, 2022
Next Next commit
create a new API to download artifacts from a PipelineRun
  • Loading branch information
mzmuer committed Mar 17, 2022
commit 2f4c6f47ee02c836d3e2f021edc3a62d3bb5d70d
30 changes: 30 additions & 0 deletions pkg/kapis/devops/v1alpha2/devops.go
Original file line number Diff line number Diff line change
Expand Up @@ -907,3 +907,33 @@ func parseErr(err error, resp *restful.Response) {
}
return
}

// downloadArtifact API to download artifacts from Jenkins
func (h *ProjectPipelineHandler) downloadArtifact(request *restful.Request, response *restful.Response) {
projectName := request.PathParameter("devops")
pipelineName := request.PathParameter("pipeline")
runId := request.PathParameter("run")
fileName := request.QueryParameter("filename")

artifactUrl := fmt.Sprintf("/job/%s/job/%s/%s/artifact/%s", projectName, pipelineName, runId, fileName)
statusCode, body, err := h.jenkinsClient.Request(http.MethodGet, artifactUrl, nil, nil)
if err != nil {
kapis.HandleError(request, response, err)
return
}

if statusCode != http.StatusOK {
err := fmt.Errorf("failed to get artifact. The HTTP status code is %d", statusCode)
kapis.HandleError(request, response, err)
return
}

// add download header
response.AddHeader("Content-Type", "application/octet-stream")
response.AddHeader("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName))
_, err = response.Write(body)
LinuxSuRen marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
kapis.HandleError(request, response, err)
return
}
}
5 changes: 4 additions & 1 deletion pkg/kapis/devops/v1alpha2/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha2

import (
"github.com/jenkins-zh/jenkins-client/pkg/core"
"kubesphere.io/devops/pkg/client/clientset/versioned"
devopsClient "kubesphere.io/devops/pkg/client/devops"
"kubesphere.io/devops/pkg/client/informers/externalversions"
Expand All @@ -30,18 +31,20 @@ type ProjectPipelineHandler struct {
k8sClient k8s.Client
devopsOperator devops.DevopsOperator
projectCredentialGetter devops.ProjectCredentialGetter
jenkinsClient core.JenkinsCore
}

type PipelineSonarHandler struct {
k8sClient k8s.Client
pipelineSonarGetter devops.PipelineSonarGetter
}

func NewProjectPipelineHandler(devopsClient devopsClient.Interface, k8sClient k8s.Client) ProjectPipelineHandler {
func NewProjectPipelineHandler(devopsClient devopsClient.Interface, k8sClient k8s.Client, jenkinsClient core.JenkinsCore) ProjectPipelineHandler {
return ProjectPipelineHandler{
devopsOperator: devops.NewDevopsOperator(devopsClient, k8sClient.Kubernetes(), k8sClient.KubeSphere()),
projectCredentialGetter: devops.NewProjectCredentialOperator(devopsClient),
k8sClient: k8sClient,
jenkinsClient: jenkinsClient,
}
}

Expand Down
27 changes: 24 additions & 3 deletions pkg/kapis/devops/v1alpha2/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func AddToContainer(container *restful.Container, ksInformers externalversions.S
func addToContainerWithWebService(container *restful.Container, ksInformers externalversions.SharedInformerFactory,
devopsClient devops.Interface, sonarqubeClient sonarqube.SonarInterface, ksClient versioned.Interface,
s3Client s3.Interface, endpoint string, k8sClient k8s.Client, jenkinsClient core.JenkinsCore, ws *restful.WebService) error {
err := AddPipelineToWebService(ws, devopsClient, k8sClient)
err := AddPipelineToWebService(ws, devopsClient, k8sClient, jenkinsClient)
if err != nil {
return err
}
Expand All @@ -94,11 +94,11 @@ func addToContainerWithWebService(container *restful.Container, ksInformers exte
return nil
}

func AddPipelineToWebService(webservice *restful.WebService, devopsClient devops.Interface, k8sClient k8s.Client) error {
func AddPipelineToWebService(webservice *restful.WebService, devopsClient devops.Interface, k8sClient k8s.Client, jenkinsClient core.JenkinsCore) error {
projectPipelineEnable := devopsClient != nil

if projectPipelineEnable {
projectPipelineHandler := NewProjectPipelineHandler(devopsClient, k8sClient)
projectPipelineHandler := NewProjectPipelineHandler(devopsClient, k8sClient, jenkinsClient)

webservice.Route(webservice.GET("/devops/{devops}/credentials/{credential}/usage").
To(projectPipelineHandler.GetProjectCredentialUsage).
Expand Down Expand Up @@ -653,6 +653,26 @@ func AddPipelineToWebService(webservice *restful.WebService, devopsClient devops
Reads(devops.ReqJenkinsfile{}).
Returns(http.StatusOK, api.StatusOK, map[string]interface{}{}).
Writes(map[string]interface{}{}))

webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}").
To(projectPipelineHandler.GetPipelineRun).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Get details in the specified pipeline activity.").
Param(webservice.PathParameter("devops", "the name of devops project")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
Returns(http.StatusOK, api.StatusOK, devops.PipelineRun{}).
Writes(devops.PipelineRun{}))

// download PipelineRun artifact
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/artifact/runs/{run}").
mzmuer marked this conversation as resolved.
Show resolved Hide resolved
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
Param(webservice.QueryParameter("filename", "artifact filename. e.g. artifact:v1.0.1")).
To(projectPipelineHandler.downloadArtifact).
Returns(http.StatusOK, api.StatusOK, nil).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}))
}
return nil
}
Expand Down Expand Up @@ -725,6 +745,7 @@ func addJenkinsToContainer(webservice *restful.WebService, devopsClient devops.I
To(jenkinsProxy.proxyWithDevOps).
Returns(http.StatusOK, api.StatusOK, nil).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsJenkinsTag}))

return nil
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/kapis/devops/v1alpha2/register_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ func TestAPIsExist(t *testing.T) {
method: http.MethodPost,
uri: "/tojenkinsfile",
},
}, {
name: "artifact download",
args: args{
method: http.MethodGet,
uri: "/devops/fake/pipelines/fake/artifact/runs/fake",
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down