forked from jenkins-x/jx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.go
171 lines (149 loc) · 5.1 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package jenkins
import (
"crypto/tls"
"errors"
"fmt"
"io"
"net/http"
"os"
"github.com/jenkins-x/golang-jenkins"
jenkauth "github.com/jenkins-x/jx/pkg/auth"
"github.com/jenkins-x/jx/pkg/log"
"github.com/jenkins-x/jx/pkg/util"
"gopkg.in/AlecAivazis/survey.v1/terminal"
)
func GetJenkinsClient(url string, batch bool, configService *jenkauth.AuthConfigService, in terminal.FileReader, out terminal.FileWriter, outErr io.Writer) (gojenkins.JenkinsClient, error) {
if url == "" {
return nil, errors.New("no external Jenkins URL found in the development namespace!\nAre you sure you installed Jenkins X? Try: https://jenkins-x.io/getting-started/")
}
tokenUrl := JenkinsTokenURL(url)
auth := jenkauth.CreateAuthUserFromEnvironment("JENKINS")
username := auth.Username
var err error
config := configService.Config()
showForm := false
if auth.IsInvalid() {
// lets try load the current auth
config, err = configService.LoadConfig()
if err != nil {
return nil, err
}
auths := config.FindUserAuths(url)
if len(auths) > 1 {
// TODO choose an auth
}
showForm = true
a := config.FindUserAuth(url, username)
if a != nil {
if a.IsInvalid() {
auth, err = EditUserAuth(url, configService, config, a, tokenUrl, batch, in, out, outErr)
if err != nil {
return nil, err
}
} else {
auth = *a
}
} else {
// lets create a new Auth
auth, err = EditUserAuth(url, configService, config, &auth, tokenUrl, batch, in, out, outErr)
if err != nil {
return nil, err
}
}
}
if auth.IsInvalid() {
if showForm {
return nil, fmt.Errorf("No valid Username and API Token specified for Jenkins server: %s\n", url)
} else {
log.Warnf("No $JENKINS_USERNAME and $JENKINS_TOKEN environment variables defined!\n")
PrintGetTokenFromURL(os.Stdout, tokenUrl)
if batch {
log.Infof("Then run this command on your terminal and try again:\n\n")
log.Infof("export JENKINS_TOKEN=myApiToken\n\n")
return nil, errors.New("No environment variables (JENKINS_USERNAME and JENKINS_TOKEN) or JENKINS_BEARER_TOKEN defined")
}
}
}
jauth := &gojenkins.Auth{
Username: auth.Username,
ApiToken: auth.ApiToken,
BearerToken: auth.BearerToken,
}
jenkins := gojenkins.NewJenkins(jauth, url)
// handle insecure TLS for minishift
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}}
jenkins.SetHTTPClient(httpClient)
return jenkins, nil
}
func PrintGetTokenFromURL(out io.Writer, tokenUrl string) (int, error) {
return fmt.Fprintf(out, "Please go to %s and click %s to get your API Token\n", util.ColorInfo(tokenUrl), util.ColorInfo("Show API Token"))
}
func JenkinsTokenURL(url string) string {
tokenUrl := util.UrlJoin(url, "/me/configure")
return tokenUrl
}
func JenkinsNewTokenURL(url string) string {
return util.UrlJoin(url, "/me/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken")
}
func JenkinsApiURL(url string) string {
return util.UrlJoin(url, "/api")
}
func EditUserAuth(url string, configService *jenkauth.AuthConfigService, config *jenkauth.AuthConfig, auth *jenkauth.UserAuth, tokenUrl string, batchMode bool, in terminal.FileReader, out terminal.FileWriter, outErr io.Writer) (jenkauth.UserAuth, error) {
log.Infof("\nTo be able to connect to the Jenkins server we need a username and API Token\n\n")
f := func(username string) error {
log.Infof("\nPlease go to %s and click %s to get your API Token\n", util.ColorInfo(tokenUrl), util.ColorInfo("Show API Token"))
log.Infof("Then COPY the API token so that you can paste it into the form below:\n\n")
return nil
}
defaultUsername := "admin"
err := config.EditUserAuth("Jenkins", auth, defaultUsername, true, batchMode, f, in, out, outErr)
if err != nil {
return *auth, err
}
err = configService.SaveUserAuth(url, auth)
return *auth, err
}
// IsMultiBranchProject returns true if this job is a multi branch project
func IsMultiBranchProject(job *gojenkins.Job) bool {
return job != nil && job.Class == "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"
}
// LoadAllJenkinsJobs Loads all the jobs in full from the Jenkins client
func LoadAllJenkinsJobs(jenkinsClient gojenkins.JenkinsClient) ([]*gojenkins.Job, error) {
answer := []*gojenkins.Job{}
jobs, err := jenkinsClient.GetJobs()
if err != nil {
return answer, err
}
for _, j := range jobs {
childJobs, err := loadChildJobs(jenkinsClient, j.Name)
if err != nil {
return answer, err
}
answer = append(answer, childJobs...)
}
return answer, nil
}
func loadChildJobs(jenkinsClient gojenkins.JenkinsClient, name string) ([]*gojenkins.Job, error) {
answer := []*gojenkins.Job{}
job, err := jenkinsClient.GetJob(name)
if err != nil {
return answer, err
}
answer = append(answer, &job)
if job.Jobs != nil {
for _, child := range job.Jobs {
childJobs, err := loadChildJobs(jenkinsClient, job.FullName+"/"+child.Name)
if err != nil {
return answer, err
}
answer = append(answer, childJobs...)
}
}
return answer, nil
}