Seed Jobs refactoring
- add new CreateOrUpdateJob function for Jenkins client - better naming
This commit is contained in:
		
							parent
							
								
									43d45cda31
								
							
						
					
					
						commit
						25d63a881f
					
				|  | @ -8,6 +8,7 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/bndr/gojenkins" | 	"github.com/bndr/gojenkins" | ||||||
|  | 	"errors" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Jenkins defines Jenkins API
 | // Jenkins defines Jenkins API
 | ||||||
|  | @ -20,6 +21,7 @@ type Jenkins interface { | ||||||
| 	CreateFolder(name string, parents ...string) (*gojenkins.Folder, error) | 	CreateFolder(name string, parents ...string) (*gojenkins.Folder, error) | ||||||
| 	CreateJobInFolder(config string, jobName string, parentIDs ...string) (*gojenkins.Job, error) | 	CreateJobInFolder(config string, jobName string, parentIDs ...string) (*gojenkins.Job, error) | ||||||
| 	CreateJob(config string, options ...interface{}) (*gojenkins.Job, error) | 	CreateJob(config string, options ...interface{}) (*gojenkins.Job, error) | ||||||
|  | 	CreateOrUpdateJob(config string, options ...interface{}) (*gojenkins.Job, error) | ||||||
| 	RenameJob(job string, name string) *gojenkins.Job | 	RenameJob(job string, name string) *gojenkins.Job | ||||||
| 	CopyJob(copyFrom string, newName string) (*gojenkins.Job, error) | 	CopyJob(copyFrom string, newName string) (*gojenkins.Job, error) | ||||||
| 	DeleteJob(name string) (bool, error) | 	DeleteJob(name string) (bool, error) | ||||||
|  | @ -53,6 +55,34 @@ type jenkins struct { | ||||||
| 	gojenkins.Jenkins | 	gojenkins.Jenkins | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // CreateOrUpdateJob creates or updates a job from config
 | ||||||
|  | func (jenkins *jenkins) CreateOrUpdateJob(config string, options ...interface{}) (*gojenkins.Job, error) { | ||||||
|  | 	// taken from gojenkins.CreateJob
 | ||||||
|  | 	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") | ||||||
|  | 	} | ||||||
|  | 	// create or update
 | ||||||
|  | 	job, err := jenkins.GetJob(qr["name"]) | ||||||
|  | 	if jobNotExists(err) { | ||||||
|  | 		_, err := jenkins.CreateJob(config, options) | ||||||
|  | 		return nil, err | ||||||
|  | 	} else if err != nil { | ||||||
|  | 		err := job.UpdateConfig(config) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return job, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func jobNotExists(err error) bool { | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err.Error() == errors.New("404").Error() | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // BuildJenkinsAPIUrl returns Jenkins API URL
 | // BuildJenkinsAPIUrl returns Jenkins API URL
 | ||||||
| func BuildJenkinsAPIUrl(namespace, serviceName string, portNumber int, local, minikube bool) (string, error) { | func BuildJenkinsAPIUrl(namespace, serviceName string, portNumber int, local, minikube bool) (string, error) { | ||||||
| 	// Get Jenkins URL from minikube command
 | 	// Get Jenkins URL from minikube command
 | ||||||
|  |  | ||||||
|  | @ -1,2 +1,2 @@ | ||||||
| // Package user is responsible for Jenkins user configuration
 | // Package user implements Jenkins user configuration and reconciliation
 | ||||||
| package user | package user | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ func (r *ReconcileUserConfiguration) Reconcile() (*reconcile.Result, error) { | ||||||
| 		return &reconcile.Result{}, nil | 		return &reconcile.Result{}, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err := seedjobs.ConfigureSeedJobs(r.jenkinsClient, r.k8sClient, r.jenkins) | 	err := seedjobs.EnsureSeedJobs(r.jenkinsClient, r.k8sClient, r.jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return &reconcile.Result{}, err | 		return &reconcile.Result{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -6,7 +6,6 @@ import ( | ||||||
| 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | ||||||
| 
 | 
 | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"k8s.io/api/core/v1" | 	"k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
|  | @ -24,20 +23,35 @@ const ( | ||||||
| 	displayNameParameterName      = "SEED_JOB_DISPLAY_NAME" | 	displayNameParameterName      = "SEED_JOB_DISPLAY_NAME" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ConfigureSeedJobs configures and triggers seed job pipeline for every Jenkins.Spec.SeedJobs entry
 | // EnsureSeedJobs configures seed job and runs it for every entry from Jenkins.Spec.SeedJobs
 | ||||||
| func ConfigureSeedJobs(jenkinsClient jenkins.Jenkins, k8sClient k8s.Client, jenkins *virtuslabv1alpha1.Jenkins) error { | func EnsureSeedJobs(jenkinsClient jenkins.Jenkins, k8sClient k8s.Client, jenkins *virtuslabv1alpha1.Jenkins) error { | ||||||
| 	err := configureSeedJobsPipeline(jenkinsClient) | 	err := configureSeedJob(jenkinsClient) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	err = buildAndVerifySeedJobs(jenkinsClient, k8sClient, jenkins) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | func configureSeedJob(jenkinsClient jenkins.Jenkins) error { | ||||||
|  | 	_, err := jenkinsClient.CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func buildAndVerifySeedJobs(jenkinsClient jenkins.Jenkins, k8sClient k8s.Client, jenkins *virtuslabv1alpha1.Jenkins) error { | ||||||
| 	seedJobs := jenkins.Spec.SeedJobs | 	seedJobs := jenkins.Spec.SeedJobs | ||||||
| 	for _, seedJob := range seedJobs { | 	for _, seedJob := range seedJobs { | ||||||
| 		privateKey, err := extractPrivateKey(k8sClient, jenkins.Namespace, seedJob) | 		privateKey, err := privateKeyFromSecret(k8sClient, jenkins.Namespace, seedJob) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		err = triggerConfigureSeedJobsPipeline( | 		err = buildAndVerifySeedJob( | ||||||
| 			jenkinsClient, | 			jenkinsClient, | ||||||
| 			seedJob.ID, | 			seedJob.ID, | ||||||
| 			privateKey, | 			privateKey, | ||||||
|  | @ -50,33 +64,9 @@ func ConfigureSeedJobs(jenkinsClient jenkins.Jenkins, k8sClient k8s.Client, jenk | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // configureSeedJobsPipeline configures seed jobs and deploy keys
 | func buildAndVerifySeedJob(jenkinsClient jenkins.Jenkins, deployKeyID, privateKey, repositoryURL, repositoryBranch, targets, displayName string) error { | ||||||
| func configureSeedJobsPipeline(jenkinsClient jenkins.Jenkins) error { | 	// FIXME this function should build job and verify job status when finished (state in cr status)
 | ||||||
| 	return createOrUpdateSeedJob(jenkinsClient) | 	// requeue when job is running and check job status next time
 | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // FIXME this function should be part of jenkins client API
 |  | ||||||
| func createOrUpdateSeedJob(jenkinsClient jenkins.Jenkins) error { |  | ||||||
| 	job, err := jenkinsClient.GetJob(ConfigureSeedJobsName) |  | ||||||
| 	if jobNotExists(err) { |  | ||||||
| 		_, err := jenkinsClient.CreateJob(seedJobConfigXML, ConfigureSeedJobsName) |  | ||||||
| 		return err |  | ||||||
| 	} else if err != nil { |  | ||||||
| 		err := job.UpdateConfig(seedJobConfigXML) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func jobNotExists(err error) bool { |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err.Error() == errors.New("404").Error() |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // triggerConfigureSeedJobsPipeline triggers and configures seed job for specific GitHub repository
 |  | ||||||
| func triggerConfigureSeedJobsPipeline(jenkinsClient jenkins.Jenkins, deployKeyID, privateKey, repositoryURL, repositoryBranch, targets, displayName string) error { |  | ||||||
| 	options := map[string]string{ | 	options := map[string]string{ | ||||||
| 		deployKeyIDParameterName:      deployKeyID, | 		deployKeyIDParameterName:      deployKeyID, | ||||||
| 		privateKeyParameterName:       privateKey, | 		privateKeyParameterName:       privateKey, | ||||||
|  | @ -85,7 +75,6 @@ func triggerConfigureSeedJobsPipeline(jenkinsClient jenkins.Jenkins, deployKeyID | ||||||
| 		targetsParameterName:          targets, | 		targetsParameterName:          targets, | ||||||
| 		displayNameParameterName:      displayName, | 		displayNameParameterName:      displayName, | ||||||
| 	} | 	} | ||||||
| 	// FIXME implement EnsureJob()
 |  | ||||||
| 	_, err := jenkinsClient.BuildJob(ConfigureSeedJobsName, options) | 	_, err := jenkinsClient.BuildJob(ConfigureSeedJobsName, options) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|  | @ -93,7 +82,7 @@ func triggerConfigureSeedJobsPipeline(jenkinsClient jenkins.Jenkins, deployKeyID | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func extractPrivateKey(k8sClient k8s.Client, namespace string, seedJob virtuslabv1alpha1.SeedJob) (string, error) { | func privateKeyFromSecret(k8sClient k8s.Client, namespace string, seedJob virtuslabv1alpha1.SeedJob) (string, error) { | ||||||
| 	if seedJob.PrivateKey.SecretKeyRef != nil { | 	if seedJob.PrivateKey.SecretKeyRef != nil { | ||||||
| 		deployKeySecret := &v1.Secret{} | 		deployKeySecret := &v1.Secret{} | ||||||
| 		namespaceName := types.NamespacedName{Namespace: namespace, Name: seedJob.PrivateKey.SecretKeyRef.Name} | 		namespaceName := types.NamespacedName{Namespace: namespace, Name: seedJob.PrivateKey.SecretKeyRef.Name} | ||||||
|  | @ -106,7 +95,7 @@ func extractPrivateKey(k8sClient k8s.Client, namespace string, seedJob virtuslab | ||||||
| 	return "", nil | 	return "", nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FIXME use mask-password plugin for params.PRIVATE_KEY
 | // FIXME consider to use mask-password plugin for params.PRIVATE_KEY
 | ||||||
| var seedJobConfigXML = ` | var seedJobConfigXML = ` | ||||||
| <flow-definition plugin="workflow-job@2.30"> | <flow-definition plugin="workflow-job@2.30"> | ||||||
|   <actions/> |   <actions/> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue