Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/koderover/zadig/v2/pkg/microservice/aslan/config"
commonmodels "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models"
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb"
jenkinsclient "github.com/koderover/zadig/v2/pkg/tool/jenkins"
"github.com/koderover/zadig/v2/pkg/tool/log"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -76,11 +77,20 @@ func (c *JenkinsJobCtl) Run(ctx context.Context) {
return
}

job, err := jenkinsClient.GetJob(context.TODO(), c.jobTaskSpec.Job.JobName)
job := &jenkins.Job{
Jenkins: jenkinsClient,
Raw: new(jenkins.JobResponse),
Base: jenkinsclient.JobPath(c.jobTaskSpec.Job.JobName),
}
status, err := job.Poll(context.TODO())
if err != nil {
logError(c.job, fmt.Sprintf("failed to get jenkins job, error is: %s", err), c.logger)
return
}
if status != http.StatusOK {
logError(c.job, fmt.Sprintf("failed to get jenkins job, error is: %d", status), c.logger)
return
}

params := make(map[string]string)
for _, parameter := range c.jobTaskSpec.Job.Parameters {
Expand All @@ -94,7 +104,7 @@ func (c *JenkinsJobCtl) Run(ctx context.Context) {
return
}

build, err := jenkinsClient.GetBuildFromQueueID(context.TODO(), queueid)
build, err := getJenkinsBuildFromQueueID(context.TODO(), jenkinsClient, job, queueid)
if err != nil {
logError(c.job, fmt.Sprintf("failed to get jenkins build, error is: %s", err), c.logger)
return
Expand Down Expand Up @@ -138,6 +148,21 @@ func (c *JenkinsJobCtl) Run(ctx context.Context) {
return
}

func getJenkinsBuildFromQueueID(ctx context.Context, jenkinsClient *jenkins.Jenkins, job *jenkins.Job, queueID int64) (*jenkins.Build, error) {
task, err := jenkinsClient.GetQueueItem(ctx, queueID)
if err != nil {
return nil, err
}
for task.Raw.Executable.Number == 0 {
time.Sleep(time.Second)
if _, err := task.Poll(ctx); err != nil {
return nil, err
}
}

return job.GetBuild(ctx, task.Raw.Executable.Number)
}

func (c *JenkinsJobCtl) SaveInfo(ctx context.Context) error {
return mongodb.NewJobInfoColl().Create(context.TODO(), &commonmodels.JobInfo{
Type: c.job.JobType,
Expand Down
3 changes: 2 additions & 1 deletion pkg/microservice/aslan/core/system/handler/jenkins.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package handler

import (
"fmt"
"strings"

"github.com/gin-gonic/gin"
"github.com/koderover/zadig/v2/pkg/setting"
Expand Down Expand Up @@ -80,5 +81,5 @@ func ListJobBuildArgs(c *gin.Context) {
ctx := internalhandler.NewContext(c)
defer func() { internalhandler.JSONResponse(c, ctx) }()

ctx.Resp, ctx.RespErr = service.ListJobBuildArgs(c.Param("id"), c.Param("jobName"), ctx.Logger)
ctx.Resp, ctx.RespErr = service.ListJobBuildArgs(c.Param("id"), strings.TrimPrefix(c.Param("jobName"), "/"), ctx.Logger)
}
2 changes: 1 addition & 1 deletion pkg/microservice/aslan/core/system/handler/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (*Router) Inject(router *gin.RouterGroup) {
jenkins.GET("/exist", CheckJenkinsIntegration)
jenkins.POST("/user/connection", TestJenkinsConnection)
jenkins.GET("/jobNames/:id", ListJobNames)
jenkins.GET("/buildArgs/:id/:jobName", ListJobBuildArgs)
jenkins.GET("/buildArgs/:id/*jobName", ListJobBuildArgs)
}

cicd := router.Group("cicdTools")
Expand Down
29 changes: 13 additions & 16 deletions pkg/microservice/aslan/core/system/service/jenkins.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

commonrepo "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb"
e "github.com/koderover/zadig/v2/pkg/tool/errors"
jenkinsclient "github.com/koderover/zadig/v2/pkg/tool/jenkins"
"github.com/koderover/zadig/v2/pkg/types"
)

Expand Down Expand Up @@ -65,42 +66,38 @@ func getJenkinsClient(id string, log *zap.SugaredLogger) (*gojenkins.Jenkins, co
}

func ListJobNames(id string, log *zap.SugaredLogger) ([]string, error) {
jenkinsClient, ctx, err := getJenkinsClient(id, log)
jenkinsIntegration, err := commonrepo.NewCICDToolColl().Get(id)
if err != nil {
return []string{}, e.ErrListJobNames.AddErr(err)
}
innerJobs, err := jenkinsClient.GetAllJobNames(ctx)

jenkinsClient := jenkinsclient.NewClient(jenkinsIntegration.URL, jenkinsIntegration.Username, jenkinsIntegration.Password)
jobNames, err := jenkinsClient.ListJobNames()
if err != nil {
return []string{}, e.ErrListJobNames.AddErr(err)
}
jobNames := make([]string, 0)
for _, innerJob := range innerJobs {
jobNames = append(jobNames, innerJob.Name)
}
return jobNames, nil
}

func ListJobBuildArgs(id, jobName string, log *zap.SugaredLogger) ([]*JenkinsBuildArgs, error) {
jenkinsClient, ctx, err := getJenkinsClient(id, log)
if err != nil {
return []*JenkinsBuildArgs{}, e.ErrListJobBuildArgs.AddErr(err)
}
jenkinsJob, err := jenkinsClient.GetJob(ctx, jobName)
jenkinsIntegration, err := commonrepo.NewCICDToolColl().Get(id)
if err != nil {
return []*JenkinsBuildArgs{}, e.ErrListJobBuildArgs.AddErr(err)
}
paramDefinitions, err := jenkinsJob.GetParameters(ctx)

jenkinsClient := jenkinsclient.NewClient(jenkinsIntegration.URL, jenkinsIntegration.Username, jenkinsIntegration.Password)
jenkinsJob, err := jenkinsClient.GetJob(jobName)
if err != nil {
return []*JenkinsBuildArgs{}, e.ErrListJobBuildArgs.AddErr(err)
}
jenkinsBuildArgsResp := make([]*JenkinsBuildArgs, 0)
for _, paramDefinition := range paramDefinitions {
for _, paramDefinition := range jenkinsJob.GetParameters() {
arg := &JenkinsBuildArgs{
Name: paramDefinition.DefaultParameterValue.Name,
Name: paramDefinition.Name,
Value: paramDefinition.DefaultParameterValue.Value,
Type: paramDefinition.Type,
Type: string(paramDefinition.Type),
}
if paramDefinition.Type == "ChoiceParameterDefinition" {
if paramDefinition.Type == jenkinsclient.Choice {
arg.Type = string(types.Choice)
} else {
arg.Type = string(types.Str)
Expand Down
2 changes: 1 addition & 1 deletion pkg/microservice/aslan/core/workflow/handler/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (*Router) Inject(router *gin.RouterGroup) {
workflowV4.GET("/mse/offline", GetMseOfflineResources)
workflowV4.GET("/mse/:envName/tag", GetMseTagsInEnv)
workflowV4.GET("/bluegreen/:envName/:serviceName", GetBlueGreenServiceK8sServiceYaml)
workflowV4.GET("/jenkins/:id/:jobName", GetJenkinsJobParams)
workflowV4.GET("/jenkins/:id/*jobName", GetJenkinsJobParams)
workflowV4.POST("/sql/validate", ValidateSQL)
workflowV4.POST("/deploy/mergeImage", HelmDeployJobMergeImage)
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/microservice/aslan/core/workflow/handler/workflow_v4.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"io"
"strings"

"github.com/gin-gonic/gin"
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/util"
Expand Down Expand Up @@ -1502,7 +1503,7 @@ func GetJenkinsJobParams(c *gin.Context) {
ctx := internalhandler.NewContext(c)
defer func() { internalhandler.JSONResponse(c, ctx) }()

jobParams, err := workflow.GetJenkinsJobParams(c.Param("id"), c.Param("jobName"))
jobParams, err := workflow.GetJenkinsJobParams(c.Param("id"), strings.TrimPrefix(c.Param("jobName"), "/"))
if err != nil {
ctx.RespErr = err
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,16 @@ func (j JenkinsJobController) Update(useUserInput bool, ticket *commonmodels.App
j.errorPolicy = currJob.ErrorPolicy
j.executePolicy = currJob.ExecutePolicy

if j.jobSpec.ID != "" && currJobSpec.ID != "" && j.jobSpec.ID != currJobSpec.ID {
j.jobSpec.Jobs = make([]*commonmodels.JenkinsJobInfo, 0)
}
j.jobSpec.ID = currJobSpec.ID
j.jobSpec.JobOptions = getJenkinsJobOptions(currJobSpec)

if useUserInput {
newJobs := make([]*commonmodels.JenkinsJobInfo, 0)
configuredJobMap := make(map[string]*commonmodels.JenkinsJobInfo)
for _, option := range currJobSpec.JobOptions {
for _, option := range j.jobSpec.JobOptions {
configuredJobMap[option.JobName] = option
}

Expand All @@ -110,11 +115,12 @@ func (j JenkinsJobController) Update(useUserInput bool, ticket *commonmodels.App
}

func (j JenkinsJobController) SetOptions(ticket *commonmodels.ApprovalTicket) error {
j.jobSpec.JobOptions = getJenkinsJobOptions(j.jobSpec)
return nil
}

func (j JenkinsJobController) ClearOptions() {
return
j.jobSpec.JobOptions = make([]*commonmodels.JenkinsJobInfo, 0)
}

func (j JenkinsJobController) ClearSelection() {
Expand Down Expand Up @@ -186,3 +192,11 @@ func (j JenkinsJobController) RenderDynamicVariableOptions(key string, option *R
func (j JenkinsJobController) IsServiceTypeJob() bool {
return false
}

func getJenkinsJobOptions(spec *commonmodels.JenkinsJobSpec) []*commonmodels.JenkinsJobInfo {
if len(spec.JobOptions) > 0 {
return spec.JobOptions
}

return spec.Jobs
}
88 changes: 83 additions & 5 deletions pkg/tool/jenkins/job.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
package jenkins

import "github.com/koderover/zadig/v2/pkg/microservice/aslan/config"
import (
"fmt"
"net/url"
"sort"
"strings"

"github.com/koderover/zadig/v2/pkg/microservice/aslan/config"
)

const listJobsTree = "jobs[name,fullName,_class]"

type ParameterType string

Expand All @@ -23,15 +32,80 @@ type ListJobsResp struct {
Jobs []Jobs `json:"jobs"`
}
type Jobs struct {
Class string `json:"_class"`
Name string `json:"name"`
Class string `json:"_class"`
Name string `json:"name"`
FullName string `json:"fullName"`
}

func (c *Client) ListJob() (resp *ListJobsResp, err error) {
_, err = c.R().SetSuccessResult(&resp).Get("/api/json?tree=jobs[name]")
return
}

func (c *Client) ListJobNames() ([]string, error) {
jobNames, err := c.listJobNames("")
if err != nil {
return nil, err
}
sort.Strings(jobNames)

return jobNames, nil
}

func (c *Client) listJobNames(parent string) ([]string, error) {
resp := new(ListJobsResp)
jobPath := JobPath(parent)
if parent != "" && jobPath == "" {
return nil, fmt.Errorf("jenkins job name is empty")
}

urlPath := jobPath + "/api/json?tree=" + listJobsTree
_, err := c.R().SetSuccessResult(resp).Get(urlPath)
if err != nil {
return nil, err
}

jobNames := make([]string, 0)
for _, job := range resp.Jobs {
fullName := job.FullName
if fullName == "" {
if parent == "" {
fullName = job.Name
} else {
fullName = parent + "/" + job.Name
}
}

if strings.Contains(job.Class, ".folder.") || strings.Contains(job.Class, "Folder") {
childJobNames, err := c.listJobNames(fullName)
if err != nil {
return nil, err
}
jobNames = append(jobNames, childJobNames...)
continue
}

jobNames = append(jobNames, fullName)
}
return jobNames, nil
}

func JobPath(name string) string {
parts := strings.Split(strings.Trim(name, "/"), "/")
escapedParts := make([]string, 0, len(parts))
for _, part := range parts {
if part == "" {
continue
}
escapedParts = append(escapedParts, url.PathEscape(part))
}
if len(escapedParts) == 0 {
return ""
}

return "/job/" + strings.Join(escapedParts, "/job/")
}

type Job struct {
Class string `json:"_class"`
Actions []Actions `json:"actions"`
Expand Down Expand Up @@ -101,7 +175,11 @@ type Scm struct {
}

func (c *Client) GetJob(name string) (resp *Job, err error) {
_, err = c.R().SetPathParam("job", name).
SetSuccessResult(&resp).Get("/job/{job}/api/json")
jobPath := JobPath(name)
if jobPath == "" {
return nil, fmt.Errorf("jenkins job name is empty")
}

_, err = c.R().SetSuccessResult(&resp).Get(jobPath + "/api/json")
return
}
Loading