138 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
package client
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"os/exec"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/bndr/gojenkins"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
)
 | 
						|
 | 
						|
var errorNotFound = errors.New("404")
 | 
						|
 | 
						|
// Jenkins defines Jenkins API
 | 
						|
type Jenkins interface {
 | 
						|
	GenerateToken(userName, tokenName string) (*UserToken, error)
 | 
						|
	Info() (*gojenkins.ExecutorResponse, error)
 | 
						|
	SafeRestart() error
 | 
						|
	CreateNode(name string, numExecutors int, description string, remoteFS string, label string, options ...interface{}) (*gojenkins.Node, error)
 | 
						|
	DeleteNode(name string) (bool, error)
 | 
						|
	CreateFolder(name string, parents ...string) (*gojenkins.Folder, error)
 | 
						|
	CreateJobInFolder(config string, jobName string, parentIDs ...string) (*gojenkins.Job, error)
 | 
						|
	CreateJob(config string, options ...interface{}) (*gojenkins.Job, error)
 | 
						|
	CreateOrUpdateJob(config, jobName string) (*gojenkins.Job, bool, error)
 | 
						|
	RenameJob(job string, name string) *gojenkins.Job
 | 
						|
	CopyJob(copyFrom string, newName string) (*gojenkins.Job, error)
 | 
						|
	DeleteJob(name string) (bool, error)
 | 
						|
	BuildJob(name string, options ...interface{}) (int64, error)
 | 
						|
	GetNode(name string) (*gojenkins.Node, error)
 | 
						|
	GetLabel(name string) (*gojenkins.Label, error)
 | 
						|
	GetBuild(jobName string, number int64) (*gojenkins.Build, error)
 | 
						|
	GetJob(id string, parentIDs ...string) (*gojenkins.Job, error)
 | 
						|
	GetSubJob(parentID string, childID string) (*gojenkins.Job, error)
 | 
						|
	GetFolder(id string, parents ...string) (*gojenkins.Folder, error)
 | 
						|
	GetAllNodes() ([]*gojenkins.Node, error)
 | 
						|
	GetAllBuildIds(job string) ([]gojenkins.JobBuild, error)
 | 
						|
	GetAllJobNames() ([]gojenkins.InnerJob, error)
 | 
						|
	GetAllJobs() ([]*gojenkins.Job, error)
 | 
						|
	GetQueue() (*gojenkins.Queue, error)
 | 
						|
	GetQueueUrl() string
 | 
						|
	GetQueueItem(id int64) (*gojenkins.Task, error)
 | 
						|
	GetArtifactData(id string) (*gojenkins.FingerPrintResponse, error)
 | 
						|
	GetPlugins(depth int) (*gojenkins.Plugins, error)
 | 
						|
	UninstallPlugin(name string) error
 | 
						|
	HasPlugin(name string) (*gojenkins.Plugin, error)
 | 
						|
	InstallPlugin(name string, version string) error
 | 
						|
	ValidateFingerPrint(id string) (bool, error)
 | 
						|
	GetView(name string) (*gojenkins.View, error)
 | 
						|
	GetAllViews() ([]*gojenkins.View, error)
 | 
						|
	CreateView(name string, viewType string) (*gojenkins.View, error)
 | 
						|
	Poll() (int, error)
 | 
						|
}
 | 
						|
 | 
						|
type jenkins struct {
 | 
						|
	gojenkins.Jenkins
 | 
						|
}
 | 
						|
 | 
						|
// CreateOrUpdateJob creates or updates a job from config
 | 
						|
func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkins.Job, created bool, err error) {
 | 
						|
	// create or update
 | 
						|
	job, err = jenkins.GetJob(jobName)
 | 
						|
	if isNotFoundError(err) {
 | 
						|
		job, err = jenkins.CreateJob(config, jobName)
 | 
						|
		created = true
 | 
						|
		return
 | 
						|
	} else if err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = job.UpdateConfig(config)
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func isNotFoundError(err error) bool {
 | 
						|
	if err != nil {
 | 
						|
		return err.Error() == errorNotFound.Error()
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// BuildJenkinsAPIUrl returns Jenkins API URL
 | 
						|
func BuildJenkinsAPIUrl(namespace, serviceName string, portNumber int, local, minikube bool) (string, error) {
 | 
						|
	// Get Jenkins URL from minikube command
 | 
						|
	if local && minikube {
 | 
						|
		cmd := exec.Command("minikube", "service", "--url", "-n", namespace, serviceName)
 | 
						|
		var out bytes.Buffer
 | 
						|
		cmd.Stdout = &out
 | 
						|
		err := cmd.Run()
 | 
						|
		if err != nil {
 | 
						|
			return "", err
 | 
						|
		}
 | 
						|
		lines := strings.Split(out.String(), "\n")
 | 
						|
		// First is for http, the second one is for Jenkins slaves communication
 | 
						|
		// see pkg/controller/jenkins/configuration/base/resources/service.go
 | 
						|
		url := lines[0]
 | 
						|
		return url, nil
 | 
						|
	}
 | 
						|
 | 
						|
	if local {
 | 
						|
		// When run locally make port-forward to jenkins pod ('kubectl -n default port-forward jenkins-operator-example 8080')
 | 
						|
		return fmt.Sprintf("http://localhost:%d", portNumber), nil
 | 
						|
	}
 | 
						|
 | 
						|
	// Connect through Kubernetes service, operator has to be run inside cluster
 | 
						|
	return fmt.Sprintf("http://%s:%d", serviceName, portNumber), nil
 | 
						|
}
 | 
						|
 | 
						|
// New creates Jenkins API client
 | 
						|
func New(url, user, passwordOrToken string) (Jenkins, error) {
 | 
						|
	if strings.HasSuffix(url, "/") {
 | 
						|
		url = url[:len(url)-1]
 | 
						|
	}
 | 
						|
 | 
						|
	jenkinsClient := &jenkins{}
 | 
						|
	jenkinsClient.Server = url
 | 
						|
	jenkinsClient.Requester = &gojenkins.Requester{
 | 
						|
		Base:      url,
 | 
						|
		SslVerify: true,
 | 
						|
		Client:    http.DefaultClient,
 | 
						|
		BasicAuth: &gojenkins.BasicAuth{Username: user, Password: passwordOrToken},
 | 
						|
	}
 | 
						|
	if _, err := jenkinsClient.Init(); err != nil {
 | 
						|
		return nil, errors.Wrap(err, "couldn't init Jenkins API client")
 | 
						|
	}
 | 
						|
 | 
						|
	status, err := jenkinsClient.Poll()
 | 
						|
	if err != nil {
 | 
						|
		return nil, errors.Wrap(err, "couldn't poll data from Jenkins API")
 | 
						|
	}
 | 
						|
	if status != http.StatusOK {
 | 
						|
		return nil, errors.Errorf("couldn't poll data from Jenkins API, invalid status code returned: %d", status)
 | 
						|
	}
 | 
						|
 | 
						|
	return jenkinsClient, nil
 | 
						|
}
 |