1084 lines
31 KiB
Go
1084 lines
31 KiB
Go
// Copyright 2015 Vadim Kravcenko
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
// Gojenkins is a Jenkins Client in Go, that exposes the jenkins REST api in a more developer friendly way.
|
|
package gojenkins
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Basic Authentication
|
|
type BasicAuth struct {
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
type Jenkins struct {
|
|
Server string
|
|
Version string
|
|
Raw *ExecutorResponse
|
|
Requester *Requester
|
|
}
|
|
|
|
// Loggers
|
|
var (
|
|
Info *log.Logger
|
|
Warning *log.Logger
|
|
Error *log.Logger
|
|
)
|
|
|
|
// Init Method. Should be called after creating a Jenkins Instance.
|
|
// e.g jenkins := CreateJenkins("url").Init()
|
|
// HTTP Client is set here, Connection to jenkins is tested here.
|
|
func (j *Jenkins) Init() (*Jenkins, error) {
|
|
j.initLoggers()
|
|
|
|
// Check Connection
|
|
j.Raw = new(ExecutorResponse)
|
|
rsp, err := j.Requester.GetJSON("/", j.Raw, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
j.Version = rsp.Header.Get("X-Jenkins")
|
|
if j.Raw == nil {
|
|
return nil, errors.New("Connection Failed, Please verify that the host and credentials are correct.")
|
|
}
|
|
|
|
return j, nil
|
|
}
|
|
|
|
func (j *Jenkins) initLoggers() {
|
|
Info = log.New(os.Stdout,
|
|
"INFO: ",
|
|
log.Ldate|log.Ltime|log.Lshortfile)
|
|
|
|
Warning = log.New(os.Stdout,
|
|
"WARNING: ",
|
|
log.Ldate|log.Ltime|log.Lshortfile)
|
|
|
|
Error = log.New(os.Stderr,
|
|
"ERROR: ",
|
|
log.Ldate|log.Ltime|log.Lshortfile)
|
|
}
|
|
|
|
// Get Basic Information About Jenkins
|
|
func (j *Jenkins) Info() (*ExecutorResponse, error) {
|
|
_, err := j.Requester.Get("/", j.Raw, nil)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return j.Raw, nil
|
|
}
|
|
|
|
// Create a new Node
|
|
// Can be JNLPLauncher or SSHLauncher
|
|
// Example : jenkins.CreateNode("nodeName", 1, "Description", "/var/lib/jenkins", "jdk8 docker", map[string]string{"method": "JNLPLauncher"})
|
|
// By Default JNLPLauncher is created
|
|
// Multiple labels should be separated by blanks
|
|
func (j *Jenkins) CreateNode(name string, numExecutors int, description string, remoteFS string, label string, options ...interface{}) (*Node, error) {
|
|
params := map[string]string{"method": "JNLPLauncher"}
|
|
|
|
if len(options) > 0 {
|
|
params, _ = options[0].(map[string]string)
|
|
}
|
|
|
|
if _, ok := params["method"]; !ok {
|
|
params["method"] = "JNLPLauncher"
|
|
}
|
|
|
|
method := params["method"]
|
|
var launcher map[string]string
|
|
switch method {
|
|
case "":
|
|
fallthrough
|
|
case "JNLPLauncher":
|
|
launcher = map[string]string{"stapler-class": "hudson.slaves.JNLPLauncher"}
|
|
case "SSHLauncher":
|
|
launcher = map[string]string{
|
|
"stapler-class": "hudson.plugins.sshslaves.SSHLauncher",
|
|
"$class": "hudson.plugins.sshslaves.SSHLauncher",
|
|
"host": params["host"],
|
|
"port": params["port"],
|
|
"credentialsId": params["credentialsId"],
|
|
"jvmOptions": params["jvmOptions"],
|
|
"javaPath": params["javaPath"],
|
|
"prefixStartSlaveCmd": params["prefixStartSlaveCmd"],
|
|
"suffixStartSlaveCmd": params["suffixStartSlaveCmd"],
|
|
"maxNumRetries": params["maxNumRetries"],
|
|
"retryWaitTime": params["retryWaitTime"],
|
|
"lanuchTimeoutSeconds": params["lanuchTimeoutSeconds"],
|
|
"type": "hudson.slaves.DumbSlave",
|
|
"stapler-class-bag": "true"}
|
|
default:
|
|
return nil, errors.New("launcher method not supported")
|
|
}
|
|
|
|
node := &Node{Jenkins: j, Raw: new(NodeResponse), Base: "/computer/" + name}
|
|
NODE_TYPE := "hudson.slaves.DumbSlave$DescriptorImpl"
|
|
MODE := "NORMAL"
|
|
qr := map[string]string{
|
|
"name": name,
|
|
"type": NODE_TYPE,
|
|
"json": makeJson(map[string]interface{}{
|
|
"name": name,
|
|
"nodeDescription": description,
|
|
"remoteFS": remoteFS,
|
|
"numExecutors": numExecutors,
|
|
"mode": MODE,
|
|
"type": NODE_TYPE,
|
|
"labelString": label,
|
|
"retentionsStrategy": map[string]string{"stapler-class": "hudson.slaves.RetentionStrategy$Always"},
|
|
"nodeProperties": map[string]string{"stapler-class-bag": "true"},
|
|
"launcher": launcher,
|
|
}),
|
|
}
|
|
|
|
resp, err := j.Requester.Post("/computer/doCreateItem", nil, nil, qr)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.StatusCode < 400 {
|
|
_, err := node.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return node, nil
|
|
}
|
|
return nil, errors.New(strconv.Itoa(resp.StatusCode))
|
|
}
|
|
|
|
// Delete a Jenkins slave node
|
|
func (j *Jenkins) DeleteNode(name string) (bool, error) {
|
|
node := Node{Jenkins: j, Raw: new(NodeResponse), Base: "/computer/" + name}
|
|
return node.Delete()
|
|
}
|
|
|
|
// Create a new folder
|
|
// This folder can be nested in other parent folders
|
|
// Example: jenkins.CreateFolder("newFolder", "grandparentFolder", "parentFolder")
|
|
func (j *Jenkins) CreateFolder(name, description string, parents ...string) (*Folder, error) {
|
|
folderObj := &Folder{Jenkins: j, Raw: new(FolderResponse), Base: "/job/" + strings.Join(append(parents, name), "/job/")}
|
|
folder, err := folderObj.Create(name, description)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return folder, nil
|
|
}
|
|
|
|
// Create a new job in the folder
|
|
// Example: jenkins.CreateJobInFolder("<config></config>", "newJobName", "myFolder", "parentFolder")
|
|
func (j *Jenkins) CreateJobInFolder(config string, jobName string, parentIDs ...string) (*Job, error) {
|
|
jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, jobName), "/job/")}
|
|
qr := map[string]string{
|
|
"name": jobName,
|
|
}
|
|
job, err := jobObj.Create(config, qr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return job, nil
|
|
}
|
|
|
|
// Create a new job from config File
|
|
// Method takes XML string as first parameter, and if the name is not specified in the config file
|
|
// takes name as string as second parameter
|
|
// e.g jenkins.CreateJob("<config></config>","newJobName")
|
|
func (j *Jenkins) CreateJob(config string, options ...interface{}) (*Job, error) {
|
|
qr := make(map[string]string)
|
|
if len(options) > 0 {
|
|
qr["name"] = options[0].(string)
|
|
} else {
|
|
return nil, errors.New("Error Creating Job, job name is missing")
|
|
}
|
|
jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + qr["name"]}
|
|
job, err := jobObj.Create(config, qr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return job, nil
|
|
}
|
|
|
|
// Rename a job.
|
|
// First parameter job old name, Second parameter job new name.
|
|
func (j *Jenkins) RenameJob(job string, name string) *Job {
|
|
jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + job}
|
|
jobObj.Rename(name)
|
|
return &jobObj
|
|
}
|
|
|
|
// Create a copy of a job.
|
|
// First parameter Name of the job to copy from, Second parameter new job name.
|
|
func (j *Jenkins) CopyJob(copyFrom string, newName string) (*Job, error) {
|
|
job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + copyFrom}
|
|
_, err := job.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return job.Copy(newName)
|
|
}
|
|
|
|
// Delete a job.
|
|
func (j *Jenkins) DeleteJob(name string, parentIDs ...string) (bool, error) {
|
|
job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, name), "/job/")}
|
|
return job.Delete()
|
|
}
|
|
|
|
// Invoke a job.
|
|
// First parameter job name, second parameter is optional Build parameters.
|
|
func (j *Jenkins) BuildJob(name string, options ...interface{}) (int64, error) {
|
|
job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + name}
|
|
var params map[string]string
|
|
if len(options) > 0 {
|
|
params, _ = options[0].(map[string]string)
|
|
}
|
|
return job.InvokeSimple(params)
|
|
}
|
|
|
|
func (j *Jenkins) GetNode(name string) (*Node, error) {
|
|
node := Node{Jenkins: j, Raw: new(NodeResponse), Base: "/computer/" + name}
|
|
status, err := node.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if status == 200 {
|
|
return &node, nil
|
|
}
|
|
return nil, errors.New("No node found")
|
|
}
|
|
|
|
func (j *Jenkins) GetLabel(name string) (*Label, error) {
|
|
label := Label{Jenkins: j, Raw: new(LabelResponse), Base: "/label/" + name}
|
|
status, err := label.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if status == 200 {
|
|
return &label, nil
|
|
}
|
|
return nil, errors.New("No label found")
|
|
}
|
|
|
|
func (j *Jenkins) GetBuild(jobName string, number int64) (*Build, error) {
|
|
job, err := j.GetJob(jobName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
build, err := job.GetBuild(number)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return build, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetJob(id string, parentIDs ...string) (*Job, error) {
|
|
job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, id), "/job/")}
|
|
status, err := job.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if status == 200 {
|
|
return &job, nil
|
|
}
|
|
return nil, errors.New(strconv.Itoa(status))
|
|
}
|
|
|
|
func (j *Jenkins) GetSubJob(parentId string, childId string) (*Job, error) {
|
|
job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + parentId + "/job/" + childId}
|
|
status, err := job.Poll()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("trouble polling job: %v", err)
|
|
}
|
|
if status == 200 {
|
|
return &job, nil
|
|
}
|
|
return nil, errors.New(strconv.Itoa(status))
|
|
}
|
|
|
|
func (j *Jenkins) GetFolder(id string, parents ...string) (*Folder, error) {
|
|
folder := Folder{Jenkins: j, Raw: new(FolderResponse), Base: "/job/" + strings.Join(append(parents, id), "/job/")}
|
|
status, err := folder.Poll()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("trouble polling folder: %v", err)
|
|
}
|
|
if status == 200 {
|
|
return &folder, nil
|
|
}
|
|
return nil, errors.New(strconv.Itoa(status))
|
|
}
|
|
|
|
func (j *Jenkins) GetAllNodes() ([]*Node, error) {
|
|
computers := new(Computers)
|
|
|
|
qr := map[string]string{
|
|
"depth": "1",
|
|
}
|
|
|
|
_, err := j.Requester.GetJSON("/computer", computers, qr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
nodes := make([]*Node, len(computers.Computers))
|
|
for i, node := range computers.Computers {
|
|
nodes[i] = &Node{Jenkins: j, Raw: node, Base: "/computer/" + node.DisplayName}
|
|
}
|
|
|
|
return nodes, nil
|
|
}
|
|
|
|
// Get all builds Numbers and URLS for a specific job.
|
|
// There are only build IDs here,
|
|
// To get all the other info of the build use jenkins.GetBuild(job,buildNumber)
|
|
// or job.GetBuild(buildNumber)
|
|
func (j *Jenkins) GetAllBuildIds(job string) ([]JobBuild, error) {
|
|
jobObj, err := j.GetJob(job)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return jobObj.GetAllBuildIds()
|
|
}
|
|
|
|
func (j *Jenkins) GetAllBuildStatus(jobId string) ([]JobBuildStatus, error) {
|
|
job, err := j.GetJob(jobId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return job.GetAllBuildStatus()
|
|
}
|
|
|
|
// Get Only Array of Job Names, Color, URL
|
|
// Does not query each single Job.
|
|
func (j *Jenkins) GetAllJobNames() ([]InnerJob, error) {
|
|
exec := Executor{Raw: new(ExecutorResponse), Jenkins: j}
|
|
_, err := j.Requester.GetJSON("/", exec.Raw, nil)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return exec.Raw.Jobs, nil
|
|
}
|
|
|
|
// Get All Possible Job Objects.
|
|
// Each job will be queried.
|
|
func (j *Jenkins) GetAllJobs() ([]*Job, error) {
|
|
exec := Executor{Raw: new(ExecutorResponse), Jenkins: j}
|
|
_, err := j.Requester.GetJSON("/", exec.Raw, nil)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
jobs := make([]*Job, len(exec.Raw.Jobs))
|
|
for i, job := range exec.Raw.Jobs {
|
|
ji, err := j.GetJob(job.Name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
jobs[i] = ji
|
|
}
|
|
return jobs, nil
|
|
}
|
|
|
|
// Returns a Queue
|
|
func (j *Jenkins) GetQueue() (*Queue, error) {
|
|
q := &Queue{Jenkins: j, Raw: new(queueResponse), Base: j.GetQueueUrl()}
|
|
_, err := q.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return q, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetQueueUrl() string {
|
|
return "/queue"
|
|
}
|
|
|
|
// Get Artifact data by Hash
|
|
func (j *Jenkins) GetArtifactData(id string) (*FingerPrintResponse, error) {
|
|
fp := FingerPrint{Jenkins: j, Base: "/fingerprint/", Id: id, Raw: new(FingerPrintResponse)}
|
|
return fp.GetInfo()
|
|
}
|
|
|
|
// Returns the list of all plugins installed on the Jenkins server.
|
|
// You can supply depth parameter, to limit how much data is returned.
|
|
func (j *Jenkins) GetPlugins(depth int) (*Plugins, error) {
|
|
p := Plugins{Jenkins: j, Raw: new(PluginResponse), Base: "/pluginManager", Depth: depth}
|
|
_, err := p.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &p, nil
|
|
}
|
|
|
|
// Check if the plugin is installed on the server.
|
|
// Depth level 1 is used. If you need to go deeper, you can use GetPlugins, and iterate through them.
|
|
func (j *Jenkins) HasPlugin(name string) (*Plugin, error) {
|
|
p, err := j.GetPlugins(1)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return p.Contains(name), nil
|
|
}
|
|
|
|
// Verify FingerPrint
|
|
func (j *Jenkins) ValidateFingerPrint(id string) (bool, error) {
|
|
fp := FingerPrint{Jenkins: j, Base: "/fingerprint/", Id: id, Raw: new(FingerPrintResponse)}
|
|
valid, err := fp.Valid()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if valid {
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetView(name string) (*View, error) {
|
|
url := "/view/" + name
|
|
view := View{Jenkins: j, Raw: new(ViewResponse), Base: url}
|
|
_, err := view.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &view, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetAllViews() ([]*View, error) {
|
|
_, err := j.Poll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
views := make([]*View, len(j.Raw.Views))
|
|
for i, v := range j.Raw.Views {
|
|
views[i], _ = j.GetView(v.Name)
|
|
}
|
|
return views, nil
|
|
}
|
|
|
|
// Create View
|
|
// First Parameter - name of the View
|
|
// Second parameter - Type
|
|
// Possible Types:
|
|
// gojenkins.LIST_VIEW
|
|
// gojenkins.NESTED_VIEW
|
|
// gojenkins.MY_VIEW
|
|
// gojenkins.DASHBOARD_VIEW
|
|
// gojenkins.PIPELINE_VIEW
|
|
// Example: jenkins.CreateView("newView",gojenkins.LIST_VIEW)
|
|
func (j *Jenkins) CreateView(name string, viewType string) (*View, error) {
|
|
view := &View{Jenkins: j, Raw: new(ViewResponse), Base: "/view/" + name}
|
|
endpoint := "/createView"
|
|
data := map[string]string{
|
|
"name": name,
|
|
"mode": viewType,
|
|
"Submit": "OK",
|
|
"json": makeJson(map[string]string{
|
|
"name": name,
|
|
"mode": viewType,
|
|
}),
|
|
}
|
|
r, err := j.Requester.Post(endpoint, nil, view.Raw, data)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if r.StatusCode == 200 {
|
|
return j.GetView(name)
|
|
}
|
|
return nil, errors.New(strconv.Itoa(r.StatusCode))
|
|
}
|
|
|
|
func (j *Jenkins) Poll() (int, error) {
|
|
resp, err := j.Requester.GetJSON("/", j.Raw, nil)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return resp.StatusCode, nil
|
|
}
|
|
|
|
// Create a ssh credentials
|
|
// return credentials id
|
|
func (j *Jenkins) CreateSshCredential(id, username, passphrase, privateKey, description string) (*string, error) {
|
|
requestStruct := NewCreateSshCredentialRequest(id, username, passphrase, privateKey, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
responseString := ""
|
|
response, err := j.Requester.PostForm("/credentials/store/system/domain/_/createCredentials",
|
|
nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &requestStruct.Credentials.Id, nil
|
|
}
|
|
|
|
func (j *Jenkins) CreateUsernamePasswordCredential(id, username, password, description string) (*string, error) {
|
|
requestStruct := NewCreateUsernamePasswordRequest(id, username, password, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
responseString := ""
|
|
response, err := j.Requester.PostForm("/credentials/store/system/domain/_/createCredentials",
|
|
nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &requestStruct.Credentials.Id, nil
|
|
}
|
|
|
|
func (j *Jenkins) CreateSshCredentialInFolder(domain, id, username, passphrase, privateKey, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewCreateSshCredentialRequest(id, username, passphrase, privateKey, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
responseString := ""
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
|
|
nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &requestStruct.Credentials.Id, nil
|
|
}
|
|
|
|
func (j *Jenkins) CreateUsernamePasswordCredentialInFolder(domain, id, username, password, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewCreateUsernamePasswordRequest(id, username, password, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
responseString := ""
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
|
|
nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &requestStruct.Credentials.Id, nil
|
|
}
|
|
|
|
func (j *Jenkins) CreateSecretTextCredentialInFolder(domain, id, secret, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewCreateSecretTextCredentialRequest(id, secret, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
responseString := ""
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
|
|
nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &requestStruct.Credentials.Id, nil
|
|
}
|
|
|
|
func (j *Jenkins) CreateKubeconfigCredentialInFolder(domain, id, content, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewCreateKubeconfigCredentialRequest(id, content, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
responseString := ""
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
|
|
nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &requestStruct.Credentials.Id, nil
|
|
}
|
|
|
|
func (j *Jenkins) UpdateSshCredentialInFolder(domain, id, username, passphrase, privateKey, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewSshCredential(id, username, passphrase, privateKey, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
|
|
nil, nil, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &id, nil
|
|
}
|
|
|
|
func (j *Jenkins) UpdateUsernamePasswordCredentialInFolder(domain, id, username, password, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewUsernamePasswordCredential(id, username, password, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
|
|
nil, nil, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &id, nil
|
|
}
|
|
|
|
func (j *Jenkins) UpdateSecretTextCredentialInFolder(domain, id, secret, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewSecretTextCredential(id, secret, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
|
|
nil, nil, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &id, nil
|
|
}
|
|
|
|
func (j *Jenkins) UpdateKubeconfigCredentialInFolder(domain, id, content, description string, folders ...string) (*string, error) {
|
|
requestStruct := NewKubeconfigCredential(id, content, description)
|
|
param := map[string]string{"json": makeJson(requestStruct)}
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.PostForm(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
|
|
nil, nil, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &id, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetCredentialInFolder(domain, id string, folders ...string) (*CredentialResponse, error) {
|
|
responseStruct := &CredentialResponse{}
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.GetJSON(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s", domain, id),
|
|
responseStruct, map[string]string{
|
|
"depth": "2",
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
responseStruct.Domain = domain
|
|
return responseStruct, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetCredentialContentInFolder(domain, id string, folders ...string) (string, error) {
|
|
responseStruct := ""
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return "", fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.GetHtml(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/update", domain, id),
|
|
&responseStruct, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return "", errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return responseStruct, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetCredentialsInFolder(domain string, folders ...string) ([]*CredentialResponse, error) {
|
|
prePath := ""
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
|
|
if domain == "" {
|
|
var responseStruct = &struct {
|
|
Domains map[string]struct {
|
|
Credentials []*CredentialResponse `json:"credentials"`
|
|
} `json:"domains"`
|
|
}{}
|
|
response, err := j.Requester.GetJSON(prePath+
|
|
"/credentials/store/folder/",
|
|
responseStruct, map[string]string{
|
|
"depth": "2",
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
responseArray := make([]*CredentialResponse, 0)
|
|
for domainName, domain := range responseStruct.Domains {
|
|
for _, credential := range domain.Credentials {
|
|
credential.Domain = domainName
|
|
responseArray = append(responseArray, credential)
|
|
}
|
|
}
|
|
return responseArray, nil
|
|
}
|
|
|
|
var responseStruct = &struct {
|
|
Credentials []*CredentialResponse `json:"credentials"`
|
|
}{}
|
|
response, err := j.Requester.GetJSON(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s", domain),
|
|
responseStruct, map[string]string{
|
|
"depth": "2",
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
for _, credential := range responseStruct.Credentials {
|
|
credential.Domain = domain
|
|
}
|
|
return responseStruct.Credentials, nil
|
|
|
|
}
|
|
|
|
func (j *Jenkins) DeleteCredentialInFolder(domain, id string, folders ...string) (*string, error) {
|
|
prePath := ""
|
|
if domain == "" {
|
|
domain = "_"
|
|
}
|
|
if len(folders) == 0 {
|
|
return nil, fmt.Errorf("folder name shoud not be nil")
|
|
}
|
|
for _, folder := range folders {
|
|
prePath = prePath + fmt.Sprintf("/job/%s", folder)
|
|
}
|
|
response, err := j.Requester.Post(prePath+
|
|
fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/doDelete", domain, id),
|
|
nil, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return &id, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetGlobalRole(roleName string) (*GlobalRole, error) {
|
|
roleResponse := &GlobalRoleResponse{
|
|
RoleName: roleName,
|
|
}
|
|
stringResponse := ""
|
|
response, err := j.Requester.Get("/role-strategy/strategy/getRole",
|
|
&stringResponse,
|
|
map[string]string{
|
|
"roleName": roleName,
|
|
"type": GLOBAL_ROLE,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
if stringResponse == "{}" {
|
|
return nil, nil
|
|
}
|
|
err = json.Unmarshal([]byte(stringResponse), roleResponse)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &GlobalRole{
|
|
Jenkins: j,
|
|
Raw: *roleResponse,
|
|
}, nil
|
|
}
|
|
|
|
func (j *Jenkins) GetProjectRole(roleName string) (*ProjectRole, error) {
|
|
roleResponse := &ProjectRoleResponse{
|
|
RoleName: roleName,
|
|
}
|
|
stringResponse := ""
|
|
response, err := j.Requester.Get("/role-strategy/strategy/getRole",
|
|
&stringResponse,
|
|
map[string]string{
|
|
"roleName": roleName,
|
|
"type": PROJECT_ROLE,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
if stringResponse == "{}" {
|
|
return nil, nil
|
|
}
|
|
err = json.Unmarshal([]byte(stringResponse), roleResponse)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &ProjectRole{
|
|
Jenkins: j,
|
|
Raw: *roleResponse,
|
|
}, nil
|
|
}
|
|
|
|
func (j *Jenkins) AddGlobalRole(roleName string, ids GlobalPermissionIds, overwrite bool) (*GlobalRole, error) {
|
|
responseRole := &GlobalRole{
|
|
Jenkins: j,
|
|
Raw: GlobalRoleResponse{
|
|
RoleName: roleName,
|
|
PermissionIds: ids,
|
|
}}
|
|
var idArray []string
|
|
values := reflect.ValueOf(ids)
|
|
for i := 0; i < values.NumField(); i++ {
|
|
field := values.Field(i)
|
|
if field.Bool() {
|
|
idArray = append(idArray, values.Type().Field(i).Tag.Get("json"))
|
|
}
|
|
}
|
|
param := map[string]string{
|
|
"roleName": roleName,
|
|
"type": GLOBAL_ROLE,
|
|
"permissionIds": strings.Join(idArray, ","),
|
|
"overwrite": strconv.FormatBool(overwrite),
|
|
}
|
|
responseString := ""
|
|
response, err := j.Requester.Post("/role-strategy/strategy/addRole", nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return responseRole, nil
|
|
}
|
|
|
|
func (j *Jenkins) DeleteProjectRoles(roleName ...string) error {
|
|
responseString := ""
|
|
|
|
response, err := j.Requester.Post("/role-strategy/strategy/removeRoles", nil, &responseString, map[string]string{
|
|
"type": PROJECT_ROLE,
|
|
"roleNames": strings.Join(roleName, ","),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
fmt.Println(responseString)
|
|
return errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (j *Jenkins) AddProjectRole(roleName string, pattern string, ids ProjectPermissionIds, overwrite bool) (*ProjectRole, error) {
|
|
responseRole := &ProjectRole{
|
|
Jenkins: j,
|
|
Raw: ProjectRoleResponse{
|
|
RoleName: roleName,
|
|
PermissionIds: ids,
|
|
Pattern: pattern,
|
|
}}
|
|
var idArray []string
|
|
values := reflect.ValueOf(ids)
|
|
for i := 0; i < values.NumField(); i++ {
|
|
field := values.Field(i)
|
|
if field.Bool() {
|
|
idArray = append(idArray, values.Type().Field(i).Tag.Get("json"))
|
|
}
|
|
}
|
|
param := map[string]string{
|
|
"roleName": roleName,
|
|
"type": PROJECT_ROLE,
|
|
"permissionIds": strings.Join(idArray, ","),
|
|
"overwrite": strconv.FormatBool(overwrite),
|
|
"pattern": pattern,
|
|
}
|
|
responseString := ""
|
|
response, err := j.Requester.Post("/role-strategy/strategy/addRole", nil, &responseString, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return responseRole, nil
|
|
}
|
|
|
|
func (j *Jenkins) DeleteUserInProject(username string) error {
|
|
param := map[string]string{
|
|
"type": PROJECT_ROLE,
|
|
"sid": username,
|
|
}
|
|
responseString := ""
|
|
response, err := j.Requester.Post("/role-strategy/strategy/deleteSid", nil, &responseString, param)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (j *Jenkins) GetQueueItem(number int64) (*QueueItemResponse, error) {
|
|
responseItem := &QueueItemResponse{}
|
|
response, err := j.Requester.GetJSON(fmt.Sprintf("/queue/item/%s", strconv.FormatInt(number, 10)),
|
|
responseItem, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, errors.New(strconv.Itoa(response.StatusCode))
|
|
}
|
|
return responseItem, nil
|
|
}
|
|
|
|
// Creates a new Jenkins Instance
|
|
// Optional parameters are: client, username, password
|
|
// After creating an instance call init method.
|
|
func CreateJenkins(client *http.Client, base string, maxConnection int, auth ...interface{}) *Jenkins {
|
|
j := &Jenkins{}
|
|
if strings.HasSuffix(base, "/") {
|
|
base = base[:len(base)-1]
|
|
}
|
|
j.Server = base
|
|
j.Requester = &Requester{Base: base, SslVerify: true, Client: client, connControl: make(chan struct{}, maxConnection)}
|
|
if j.Requester.Client == nil {
|
|
j.Requester.Client = http.DefaultClient
|
|
}
|
|
if len(auth) == 2 {
|
|
j.Requester.BasicAuth = &BasicAuth{Username: auth[0].(string), Password: auth[1].(string)}
|
|
}
|
|
return j
|
|
}
|