Replace creating jobs mechanism, small code fixes
This commit is contained in:
		
							parent
							
								
									ab1d3fb59b
								
							
						
					
					
						commit
						9f2fe2492e
					
				|  | @ -151,6 +151,10 @@ func (jenkins *jenkins) GetNodeSecret(name string) (string, error) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	match := regex.FindStringSubmatch(content) | 	match := regex.FindStringSubmatch(content) | ||||||
|  | 	if match == nil { | ||||||
|  | 		return "", errors.New("Node secret cannot be parsed") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	result := make(map[string]string) | 	result := make(map[string]string) | ||||||
| 
 | 
 | ||||||
| 	for i, name := range regex.SubexpNames() { | 	for i, name := range regex.SubexpNames() { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ package resources | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 |  | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,14 +5,12 @@ import ( | ||||||
| 	"crypto/sha256" | 	"crypto/sha256" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" |  | ||||||
| 
 |  | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||||
| 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" | 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/jobs" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/groovy" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"reflect" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
| 	stackerr "github.com/pkg/errors" | 	stackerr "github.com/pkg/errors" | ||||||
|  | @ -26,16 +24,6 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	// ConfigureSeedJobsName this is the fixed seed job name
 |  | ||||||
| 	ConfigureSeedJobsName = constants.OperatorName + "-configure-seed-job" |  | ||||||
| 
 |  | ||||||
| 	idParameterName               = "ID" |  | ||||||
| 	credentialIDParameterName     = "CREDENTIAL_ID" |  | ||||||
| 	repositoryURLParameterName    = "REPOSITORY_URL" |  | ||||||
| 	repositoryBranchParameterName = "REPOSITORY_BRANCH" |  | ||||||
| 	targetsParameterName          = "TARGETS" |  | ||||||
| 	displayNameParameterName      = "SEED_JOB_DISPLAY_NAME" |  | ||||||
| 
 |  | ||||||
| 	// UsernameSecretKey is username data key in Kubernetes secret used to create Jenkins username/password credential
 | 	// UsernameSecretKey is username data key in Kubernetes secret used to create Jenkins username/password credential
 | ||||||
| 	UsernameSecretKey = "username" | 	UsernameSecretKey = "username" | ||||||
| 	// PasswordSecretKey is password data key in Kubernetes secret used to create Jenkins username/password credential
 | 	// PasswordSecretKey is password data key in Kubernetes secret used to create Jenkins username/password credential
 | ||||||
|  | @ -49,9 +37,6 @@ const ( | ||||||
| 
 | 
 | ||||||
| 	// AgentName is the name of seed job agent
 | 	// AgentName is the name of seed job agent
 | ||||||
| 	AgentName = "seed-job-agent" | 	AgentName = "seed-job-agent" | ||||||
| 
 |  | ||||||
| 	// AgentNamespace is the namespace of seed job agent
 |  | ||||||
| 	AgentNamespace = "default" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // SeedJobs defines API for configuring and ensuring Jenkins Seed Jobs and Deploy Keys
 | // SeedJobs defines API for configuring and ensuring Jenkins Seed Jobs and Deploy Keys
 | ||||||
|  | @ -77,20 +62,35 @@ func (s *SeedJobs) EnsureSeedJobs(jenkins *v1alpha2.Jenkins) (done bool, err err | ||||||
| 		return false, s.restartJenkinsMasterPod(*jenkins) | 		return false, s.restartJenkinsMasterPod(*jenkins) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err = s.createJob(); err != nil { | 	if len(jenkins.Spec.SeedJobs) > 0 { | ||||||
| 		s.logger.V(log.VWarn).Info("Couldn't create jenkins seed job") | 		err := s.createAgent(s.jenkinsClient, s.k8sClient, jenkins, jenkins.Namespace, AgentName) | ||||||
|  | 		if err != nil { | ||||||
| 			return false, err | 			return false, err | ||||||
| 		} | 		} | ||||||
|  | 	} else if len(jenkins.Spec.SeedJobs) == 0 { | ||||||
|  | 		err := s.k8sClient.Delete(context.TODO(), &appsv1.Deployment{ | ||||||
|  | 			ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 				Namespace: jenkins.Namespace, | ||||||
|  | 				Name:      fmt.Sprintf("%s-deployment", AgentName), | ||||||
|  | 			}, | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if err = s.ensureLabelsForSecrets(*jenkins); err != nil { | 	if err = s.ensureLabelsForSecrets(*jenkins); err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	done, err = s.buildJobs(jenkins) | 	requeue, err := s.createJobs(jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		s.logger.V(log.VWarn).Info("Couldn't build jenkins seed job") |  | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
|  | 	if requeue { | ||||||
|  | 		return false, nil | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	seedJobIDs := s.getAllSeedJobIDs(*jenkins) | 	seedJobIDs := s.getAllSeedJobIDs(*jenkins) | ||||||
| 	if done && !reflect.DeepEqual(seedJobIDs, jenkins.Status.CreatedSeedJobs) { | 	if done && !reflect.DeepEqual(seedJobIDs, jenkins.Status.CreatedSeedJobs) { | ||||||
|  | @ -98,37 +98,35 @@ func (s *SeedJobs) EnsureSeedJobs(jenkins *v1alpha2.Jenkins) (done bool, err err | ||||||
| 		return false, stackerr.WithStack(s.k8sClient.Update(context.TODO(), jenkins)) | 		return false, stackerr.WithStack(s.k8sClient.Update(context.TODO(), jenkins)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if len(seedJobIDs) > 0 { | 	return true, nil | ||||||
| 		err := CreateAgent(s.jenkinsClient, s.k8sClient, jenkins, jenkins.Namespace, AgentName) |  | ||||||
| 		if err != nil { |  | ||||||
| 			panic(err) |  | ||||||
| 		} |  | ||||||
| 	} else if len(seedJobIDs) == 0 { |  | ||||||
| 		err := s.k8sClient.Delete(context.TODO(), &appsv1.Deployment{ |  | ||||||
| 			ObjectMeta: metav1.ObjectMeta{ |  | ||||||
| 				Namespace: AgentNamespace, |  | ||||||
| 				Name:      fmt.Sprintf("%s-deployment", AgentName), |  | ||||||
| 			}, |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 		if err != nil { |  | ||||||
| 			return done, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return done, nil |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // createJob is responsible for creating jenkins job which configures jenkins seed jobs and deploy keys
 | // createJob is responsible for creating jenkins job which configures jenkins seed jobs and deploy keys
 | ||||||
| func (s *SeedJobs) createJob() error { | func (s *SeedJobs) createJobs(jenkins *v1alpha2.Jenkins) (bool, error) { | ||||||
| 	_, created, err := s.jenkinsClient.CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName) | 	groovyClient := groovy.New(s.jenkinsClient, s.k8sClient, s.logger, jenkins, "user-groovy", jenkins.Spec.GroovyScripts.Customization) | ||||||
|  | 	for _, seedJob := range jenkins.Spec.SeedJobs { | ||||||
|  | 		credentialValue, err := s.credentialValue(jenkins.Namespace, seedJob) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 		return err | 			return true, err | ||||||
| 		} | 		} | ||||||
| 	if created { | 
 | ||||||
| 		s.logger.Info(fmt.Sprintf("'%s' job has been created", ConfigureSeedJobsName)) | 		groovyScript := seedJobCreatingGroovyScript(seedJob) | ||||||
|  | 
 | ||||||
|  | 		hash := sha256.New() | ||||||
|  | 		hash.Write([]byte(groovyScript)) | ||||||
|  | 		hash.Write([]byte(credentialValue)) | ||||||
|  | 		requeue, err := groovyClient.EnsureSingle(seedJob.ID, fmt.Sprintf("%s.groovy", seedJob.ID), base64.URLEncoding.EncodeToString(hash.Sum(nil)), groovyScript) | ||||||
|  | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return true, err | ||||||
| 		} | 		} | ||||||
| 	return nil | 
 | ||||||
|  | 		if requeue { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ensureLabelsForSecrets adds labels to Kubernetes secrets where are Jenkins credentials used for seed jobs,
 | // ensureLabelsForSecrets adds labels to Kubernetes secrets where are Jenkins credentials used for seed jobs,
 | ||||||
|  | @ -160,45 +158,6 @@ func (s *SeedJobs) ensureLabelsForSecrets(jenkins v1alpha2.Jenkins) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // buildJobs is responsible for running jenkins builds which configures jenkins seed jobs and deploy keys
 |  | ||||||
| func (s *SeedJobs) buildJobs(jenkins *v1alpha2.Jenkins) (done bool, err error) { |  | ||||||
| 	allDone := true |  | ||||||
| 	for _, seedJob := range jenkins.Spec.SeedJobs { |  | ||||||
| 		credentialValue, err := s.credentialValue(jenkins.Namespace, seedJob) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return false, err |  | ||||||
| 		} |  | ||||||
| 		parameters := map[string]string{ |  | ||||||
| 			idParameterName:               seedJob.ID, |  | ||||||
| 			credentialIDParameterName:     seedJob.CredentialID, |  | ||||||
| 			repositoryURLParameterName:    seedJob.RepositoryURL, |  | ||||||
| 			repositoryBranchParameterName: seedJob.RepositoryBranch, |  | ||||||
| 			targetsParameterName:          seedJob.Targets, |  | ||||||
| 			displayNameParameterName:      fmt.Sprintf("Seed Job from %s", seedJob.ID), |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		hash := sha256.New() |  | ||||||
| 		hash.Write([]byte(parameters[idParameterName])) |  | ||||||
| 		hash.Write([]byte(parameters[credentialIDParameterName])) |  | ||||||
| 		hash.Write([]byte(credentialValue)) |  | ||||||
| 		hash.Write([]byte(parameters[repositoryURLParameterName])) |  | ||||||
| 		hash.Write([]byte(parameters[repositoryBranchParameterName])) |  | ||||||
| 		hash.Write([]byte(parameters[targetsParameterName])) |  | ||||||
| 		hash.Write([]byte(parameters[displayNameParameterName])) |  | ||||||
| 		encodedHash := base64.URLEncoding.EncodeToString(hash.Sum(nil)) |  | ||||||
| 
 |  | ||||||
| 		jobsClient := jobs.New(s.jenkinsClient, s.k8sClient, s.logger) |  | ||||||
| 		done, err := jobsClient.EnsureBuildJob(ConfigureSeedJobsName, encodedHash, parameters, jenkins, true) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return false, err |  | ||||||
| 		} |  | ||||||
| 		if !done { |  | ||||||
| 			allDone = false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return allDone, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (s *SeedJobs) credentialValue(namespace string, seedJob v1alpha2.SeedJob) (string, error) { | func (s *SeedJobs) credentialValue(namespace string, seedJob v1alpha2.SeedJob) (string, error) { | ||||||
| 	if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType { | 	if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType { | ||||||
| 		secret := &corev1.Secret{} | 		secret := &corev1.Secret{} | ||||||
|  | @ -262,7 +221,7 @@ func (s *SeedJobs) isRecreatePodNeeded(jenkins v1alpha2.Jenkins) bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CreateAgent deploys Jenkins agent to Kubernetes cluster
 | // CreateAgent deploys Jenkins agent to Kubernetes cluster
 | ||||||
| func CreateAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string) error { | func (s SeedJobs) createAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string) error { | ||||||
| 	var exists bool | 	var exists bool | ||||||
| 
 | 
 | ||||||
| 	nodes, err := jenkinsClient.GetAllNodes() | 	nodes, err := jenkinsClient.GetAllNodes() | ||||||
|  | @ -286,41 +245,28 @@ func CreateAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, j | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	deployments := &apps.DeploymentList{} |  | ||||||
| 	exists = false |  | ||||||
| 	secret, err := jenkinsClient.GetNodeSecret(agentName) | 	secret, err := jenkinsClient.GetNodeSecret(agentName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	deployment := agentDeployment(jenkinsManifest, namespace, agentName, secret) | 	deployment := agentDeployment(jenkinsManifest, namespace, agentName, secret) | ||||||
| 	err = k8sClient.List(context.TODO(), &client.ListOptions{}, deployments) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if len(deployments.Items) > 0 { |  | ||||||
| 		for _, deployment := range deployments.Items { |  | ||||||
| 			if deployment.ObjectMeta.Name == fmt.Sprintf("%s-deployment", agentName) { |  | ||||||
| 				exists = true |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Create deployment if not exists
 |  | ||||||
| 	if !exists { |  | ||||||
| 	err = k8sClient.Create(context.TODO(), deployment) | 	err = k8sClient.Create(context.TODO(), deployment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		err := k8sClient.Update(context.TODO(), deployment) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string, secret string) *apps.Deployment { | func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string, secret string) *apps.Deployment { | ||||||
| 	return &apps.Deployment{ | 	return &apps.Deployment{ | ||||||
| 		ObjectMeta: metav1.ObjectMeta{ | 		ObjectMeta: metav1.ObjectMeta{ | ||||||
| 			Name:      fmt.Sprintf("%s-deployment", agentName), | 			Name:      "jnlp", | ||||||
| 			Namespace: namespace, | 			Namespace: namespace, | ||||||
| 		}, | 		}, | ||||||
| 		Spec: apps.DeploymentSpec{ | 		Spec: apps.DeploymentSpec{ | ||||||
|  | @ -374,60 +320,26 @@ func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentN | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		Status: apps.DeploymentStatus{}, |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // seedJobConfigXML this is the XML representation of seed job
 | func seedJobCreatingGroovyScript(s v1alpha2.SeedJob) string { | ||||||
| var seedJobConfigXML = ` | 	return ` | ||||||
| <flow-definition plugin="workflow-job@2.30"> | import hudson.model.FreeStyleProject; | ||||||
|   <actions/> | import hudson.plugins.git.GitSCM; | ||||||
|   <description>Configure Seed Jobs</description> | import hudson.plugins.git.BranchSpec; | ||||||
|   <keepDependencies>false</keepDependencies> | import hudson.triggers.SCMTrigger; | ||||||
|   <properties> | import hudson.util.Secret; | ||||||
|     <hudson.model.ParametersDefinitionProperty> | import javaposse.jobdsl.plugin.*; | ||||||
|       <parameterDefinitions> | import jenkins.model.Jenkins; | ||||||
|         <hudson.model.StringParameterDefinition> | import jenkins.model.JenkinsLocationConfiguration; | ||||||
|           <name>` + idParameterName + `</name> | import com.cloudbees.plugins.credentials.CredentialsScope; | ||||||
|           <description></description> | import com.cloudbees.plugins.credentials.domains.Domain; | ||||||
|           <defaultValue></defaultValue> | import com.cloudbees.plugins.credentials.SystemCredentialsProvider; | ||||||
|           <trim>false</trim> | import jenkins.model.JenkinsLocationConfiguration; | ||||||
|         </hudson.model.StringParameterDefinition> | import org.jenkinsci.plugins.workflow.job.WorkflowJob; | ||||||
|         <hudson.model.StringParameterDefinition> | import org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition; | ||||||
|           <name>` + credentialIDParameterName + `</name> | 
 | ||||||
|           <description></description> |  | ||||||
|           <defaultValue></defaultValue> |  | ||||||
|           <trim>false</trim> |  | ||||||
|         </hudson.model.StringParameterDefinition> |  | ||||||
|         <hudson.model.StringParameterDefinition> |  | ||||||
|           <name>` + repositoryURLParameterName + `</name> |  | ||||||
|           <description></description> |  | ||||||
|           <defaultValue></defaultValue> |  | ||||||
|           <trim>false</trim> |  | ||||||
|         </hudson.model.StringParameterDefinition> |  | ||||||
|         <hudson.model.StringParameterDefinition> |  | ||||||
|           <name>` + repositoryBranchParameterName + `</name> |  | ||||||
|           <description></description> |  | ||||||
|           <defaultValue>master</defaultValue> |  | ||||||
|           <trim>false</trim> |  | ||||||
|         </hudson.model.StringParameterDefinition> |  | ||||||
|         <hudson.model.StringParameterDefinition> |  | ||||||
|           <name>` + displayNameParameterName + `</name> |  | ||||||
|           <description></description> |  | ||||||
|           <defaultValue></defaultValue> |  | ||||||
|           <trim>false</trim> |  | ||||||
|         </hudson.model.StringParameterDefinition> |  | ||||||
|         <hudson.model.StringParameterDefinition> |  | ||||||
|           <name>` + targetsParameterName + `</name> |  | ||||||
|           <description></description> |  | ||||||
|           <defaultValue>cicd/jobs/*.jenkins</defaultValue> |  | ||||||
|           <trim>false</trim> |  | ||||||
|         </hudson.model.StringParameterDefinition> |  | ||||||
|       </parameterDefinitions> |  | ||||||
|     </hudson.model.ParametersDefinitionProperty> |  | ||||||
|   </properties> |  | ||||||
|   <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.61"> |  | ||||||
|     <script> |  | ||||||
| import hudson.model.FreeStyleProject | import hudson.model.FreeStyleProject | ||||||
| import hudson.model.labels.LabelAtom | import hudson.model.labels.LabelAtom | ||||||
| import hudson.plugins.git.BranchSpec | import hudson.plugins.git.BranchSpec | ||||||
|  | @ -443,23 +355,23 @@ import static com.google.common.collect.Lists.newArrayList | ||||||
| 
 | 
 | ||||||
| Jenkins jenkins = Jenkins.instance | Jenkins jenkins = Jenkins.instance | ||||||
| 
 | 
 | ||||||
| def jobDslSeedName = "${params.` + idParameterName + `}-` + constants.SeedJobSuffix + `" | def jobDslSeedName = "` + s.ID + `-` + constants.SeedJobSuffix + `"; | ||||||
| def jobRef = jenkins.getItem(jobDslSeedName) | def jobRef = jenkins.getItem(jobDslSeedName) | ||||||
| 
 | 
 | ||||||
| def repoList = GitSCM.createRepoList("${params.` + repositoryURLParameterName + `}", "${params.` + credentialIDParameterName + `}") | def repoList = GitSCM.createRepoList("` + s.RepositoryURL + `", "` + s.CredentialID + `") | ||||||
| def gitExtensions = [new CloneOption(true, true, "", 10)] | def gitExtensions = [new CloneOption(true, true, ";", 10)] | ||||||
| def scm = new GitSCM( | def scm = new GitSCM( | ||||||
|         repoList, |         repoList, | ||||||
|         newArrayList(new BranchSpec("${params.` + repositoryBranchParameterName + `}")), |         newArrayList(new BranchSpec("` + s.RepositoryBranch + `")), | ||||||
|         false, |         false, | ||||||
|         Collections.<SubmoduleConfig> emptyList(), |         Collections.<SubmoduleConfig>emptyList(), | ||||||
|         null, |         null, | ||||||
|         null, |         null, | ||||||
|         gitExtensions |         gitExtensions | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| def executeDslScripts = new ExecuteDslScripts() | def executeDslScripts = new ExecuteDslScripts() | ||||||
| executeDslScripts.setTargets("${params.` + targetsParameterName + `}") | executeDslScripts.setTargets("` + s.Targets + `") | ||||||
| executeDslScripts.setSandbox(false) | executeDslScripts.setSandbox(false) | ||||||
| executeDslScripts.setRemovedJobAction(RemovedJobAction.DELETE) | executeDslScripts.setRemovedJobAction(RemovedJobAction.DELETE) | ||||||
| executeDslScripts.setRemovedViewAction(RemovedViewAction.DELETE) | executeDslScripts.setRemovedViewAction(RemovedViewAction.DELETE) | ||||||
|  | @ -468,18 +380,15 @@ executeDslScripts.setLookupStrategy(LookupStrategy.SEED_JOB) | ||||||
| if (jobRef == null) { | if (jobRef == null) { | ||||||
|         jobRef = jenkins.createProject(FreeStyleProject, jobDslSeedName) |         jobRef = jenkins.createProject(FreeStyleProject, jobDslSeedName) | ||||||
| } | } | ||||||
|  | 
 | ||||||
| jobRef.getBuildersList().clear() | jobRef.getBuildersList().clear() | ||||||
| jobRef.getBuildersList().add(executeDslScripts) | jobRef.getBuildersList().add(executeDslScripts) | ||||||
| jobRef.setDisplayName("${params.` + displayNameParameterName + `}") | jobRef.setDisplayName("` + fmt.Sprintf("Seed Job from %s", s.ID) + `") | ||||||
| jobRef.setScm(scm) | jobRef.setScm(scm) | ||||||
| // TODO don't use master executors
 | 
 | ||||||
| jobRef.setAssignedLabel(new LabelAtom("` + AgentName + `")) | jobRef.setAssignedLabel(new LabelAtom("` + AgentName + `")) | ||||||
| 
 | 
 | ||||||
| jenkins.getQueue().schedule(jobRef) | jenkins.getQueue().schedule(jobRef) | ||||||
| </script> | 
 | ||||||
|     <sandbox>false</sandbox> |  | ||||||
|   </definition> |  | ||||||
|   <triggers/> |  | ||||||
|   <disabled>false</disabled> |  | ||||||
| </flow-definition> |  | ||||||
| ` | ` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -16,7 +16,6 @@ import ( | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/api/resource" | 	"k8s.io/apimachinery/pkg/api/resource" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/types" |  | ||||||
| 	"k8s.io/client-go/kubernetes/scheme" | 	"k8s.io/client-go/kubernetes/scheme" | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/client/fake" | 	"sigs.k8s.io/controller-runtime/pkg/client/fake" | ||||||
| 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" | 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" | ||||||
|  | @ -37,7 +36,6 @@ func TestEnsureSeedJobs(t *testing.T) { | ||||||
| 	jenkins := jenkinsCustomResource() | 	jenkins := jenkinsCustomResource() | ||||||
| 	err = fakeClient.Create(ctx, jenkins) | 	err = fakeClient.Create(ctx, jenkins) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	buildNumber := int64(1) |  | ||||||
| 
 | 
 | ||||||
| 	agentName := "seed-job-agent" | 	agentName := "seed-job-agent" | ||||||
| 	secret := "test-secret" | 	secret := "test-secret" | ||||||
|  | @ -52,78 +50,12 @@ func TestEnsureSeedJobs(t *testing.T) { | ||||||
| 	jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName).Return(testNode, nil) | 	jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName).Return(testNode, nil) | ||||||
| 	jenkinsClient.EXPECT().GetNode(agentName).Return(testNode, nil).AnyTimes() | 	jenkinsClient.EXPECT().GetNode(agentName).Return(testNode, nil).AnyTimes() | ||||||
| 
 | 
 | ||||||
| 	for reconcileAttempt := 1; reconcileAttempt <= 2; reconcileAttempt++ { | 	jenkinsClient.EXPECT().ExecuteScript(seedJobCreatingGroovyScript(jenkins.Spec.SeedJobs[0])).AnyTimes() | ||||||
| 		logger.Info(fmt.Sprintf("Reconcile attempt #%d", reconcileAttempt)) |  | ||||||
| 
 | 
 | ||||||
| 		seedJobs := New(jenkinsClient, fakeClient, logger) | 	seedJobClient := New(jenkinsClient, fakeClient, logger) | ||||||
| 
 | 
 | ||||||
| 		// first run - should create job and schedule build
 | 	_, err = seedJobClient.EnsureSeedJobs(jenkins) | ||||||
| 		if reconcileAttempt == 1 { |  | ||||||
| 			jenkinsClient. |  | ||||||
| 				EXPECT(). |  | ||||||
| 				CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName). |  | ||||||
| 				Return(nil, true, nil) |  | ||||||
| 
 |  | ||||||
| 			jenkinsClient. |  | ||||||
| 				EXPECT(). |  | ||||||
| 				GetJob(ConfigureSeedJobsName). |  | ||||||
| 				Return(&gojenkins.Job{ |  | ||||||
| 					Raw: &gojenkins.JobResponse{ |  | ||||||
| 						NextBuildNumber: buildNumber, |  | ||||||
| 					}, |  | ||||||
| 				}, nil) |  | ||||||
| 
 |  | ||||||
| 			jenkinsClient. |  | ||||||
| 				EXPECT(). |  | ||||||
| 				BuildJob(ConfigureSeedJobsName, gomock.Any()). |  | ||||||
| 				Return(int64(0), nil) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// second run - should update and finish job
 |  | ||||||
| 		if reconcileAttempt == 2 { |  | ||||||
| 			jenkinsClient. |  | ||||||
| 				EXPECT(). |  | ||||||
| 				CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName). |  | ||||||
| 				Return(nil, false, nil) |  | ||||||
| 
 |  | ||||||
| 			jenkinsClient. |  | ||||||
| 				EXPECT(). |  | ||||||
| 				GetBuild(ConfigureSeedJobsName, gomock.Any()). |  | ||||||
| 				Return(&gojenkins.Build{ |  | ||||||
| 					Raw: &gojenkins.BuildResponse{ |  | ||||||
| 						Result: string(v1alpha2.BuildSuccessStatus), |  | ||||||
| 					}, |  | ||||||
| 				}, nil) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		done, err := seedJobs.EnsureSeedJobs(jenkins) |  | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 
 |  | ||||||
| 		err = fakeClient.Get(ctx, types.NamespacedName{Name: jenkins.Name, Namespace: jenkins.Namespace}, jenkins) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 
 |  | ||||||
| 		assert.Equal(t, 1, len(jenkins.Status.Builds), "There is one running job") |  | ||||||
| 		build := jenkins.Status.Builds[0] |  | ||||||
| 		assert.Equal(t, buildNumber, build.Number) |  | ||||||
| 		assert.Equal(t, ConfigureSeedJobsName, build.JobName) |  | ||||||
| 		assert.NotNil(t, build.CreateTime) |  | ||||||
| 		assert.NotEmpty(t, build.Hash) |  | ||||||
| 		assert.NotNil(t, build.LastUpdateTime) |  | ||||||
| 		assert.Equal(t, 0, build.Retires) |  | ||||||
| 
 |  | ||||||
| 		// first run - should create job and schedule build
 |  | ||||||
| 		if reconcileAttempt == 1 { |  | ||||||
| 			assert.False(t, done) |  | ||||||
| 			assert.Equal(t, string(v1alpha2.BuildRunningStatus), string(build.Status)) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// second run - should update and finish job
 |  | ||||||
| 		if reconcileAttempt == 2 { |  | ||||||
| 			assert.False(t, done) |  | ||||||
| 			assert.Equal(t, string(v1alpha2.BuildSuccessStatus), string(build.Status)) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func jenkinsCustomResource() *v1alpha2.Jenkins { | func jenkinsCustomResource() *v1alpha2.Jenkins { | ||||||
|  | @ -235,47 +167,6 @@ func TestSeedJobs_isRecreatePodNeeded(t *testing.T) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCreateAgent(t *testing.T) { | func TestCreateAgent(t *testing.T) { | ||||||
| 	t.Run("happy", func(t *testing.T) { |  | ||||||
| 		// given
 |  | ||||||
| 		//logger := logf.ZapLogger(false)
 |  | ||||||
| 		ctrl := gomock.NewController(t) |  | ||||||
| 		ctx := context.TODO() |  | ||||||
| 		defer ctrl.Finish() |  | ||||||
| 
 |  | ||||||
| 		namespace := "test-namespace" |  | ||||||
| 		agentName := "test-agent" |  | ||||||
| 		secret := "test-secret" |  | ||||||
| 		jenkinsCustomRes := jenkinsCustomResource() |  | ||||||
| 		testNode := &gojenkins.Node{ |  | ||||||
| 			Raw: &gojenkins.NodeResponse{ |  | ||||||
| 				DisplayName: agentName, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		jenkinsClient := jenkinsclient.NewMockJenkins(ctrl) |  | ||||||
| 		fakeClient := fake.NewFakeClient() |  | ||||||
| 		err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 
 |  | ||||||
| 		jenkinsClient.EXPECT().GetNode(agentName).Return(testNode, nil) |  | ||||||
| 		jenkinsClient.EXPECT().GetNodeSecret(agentName).Return(secret, nil) |  | ||||||
| 		jenkinsClient.EXPECT().GetAllNodes().Return([]*gojenkins.Node{}, nil) |  | ||||||
| 		jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName).Return(testNode, nil) |  | ||||||
| 
 |  | ||||||
| 		// when
 |  | ||||||
| 		err = CreateAgent(jenkinsClient, fakeClient, jenkinsCustomRes, namespace, agentName) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 
 |  | ||||||
| 		//then
 |  | ||||||
| 		err = fakeClient.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s-deployment", agentName), Namespace: namespace}, &appsv1.Deployment{}) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 
 |  | ||||||
| 		node, err := jenkinsClient.GetNode(agentName) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 
 |  | ||||||
| 		assert.Equal(t, node.Raw.DisplayName, testNode.Raw.DisplayName) |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	t.Run("not fail when deployment is available", func(t *testing.T) { | 	t.Run("not fail when deployment is available", func(t *testing.T) { | ||||||
| 		// given
 | 		// given
 | ||||||
| 		ctrl := gomock.NewController(t) | 		ctrl := gomock.NewController(t) | ||||||
|  | @ -295,6 +186,8 @@ func TestCreateAgent(t *testing.T) { | ||||||
| 		jenkinsClient.EXPECT().GetAllNodes().Return([]*gojenkins.Node{}, nil) | 		jenkinsClient.EXPECT().GetAllNodes().Return([]*gojenkins.Node{}, nil) | ||||||
| 		jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName) | 		jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName) | ||||||
| 
 | 
 | ||||||
|  | 		seedJobsClient := New(jenkinsClient, fakeClient, nil) | ||||||
|  | 
 | ||||||
| 		// when
 | 		// when
 | ||||||
| 		err = fakeClient.Create(ctx, &appsv1.Deployment{ | 		err = fakeClient.Create(ctx, &appsv1.Deployment{ | ||||||
| 			ObjectMeta: metav1.ObjectMeta{ | 			ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | @ -306,7 +199,7 @@ func TestCreateAgent(t *testing.T) { | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 		// then
 | 		// then
 | ||||||
| 		err = CreateAgent(jenkinsClient, fakeClient, jenkinsCustomResource(), namespace, agentName) | 		err = seedJobsClient.createAgent(jenkinsClient, fakeClient, jenkinsCustomResource(), namespace, agentName) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue