Add seedjob agent
This commit is contained in:
		
							parent
							
								
									76e72702f2
								
							
						
					
					
						commit
						ebd44b83fc
					
				|  | @ -3,15 +3,18 @@ package client | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" |  | ||||||
| 	"os/exec" |  | ||||||
| 	"strings" |  | ||||||
| 
 |  | ||||||
| 	"github.com/bndr/gojenkins" | 	"github.com/bndr/gojenkins" | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
|  | 	"net/http" | ||||||
|  | 	"os/exec" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var errorNotFound = errors.New("404") | var ( | ||||||
|  | 	errorNotFound = errors.New("404") | ||||||
|  | 	regex = regexp.MustCompile("(<application-desc main-class=\"hudson.remoting.jnlp.Main\"><argument>)(?P<secret>[a-z0-9]*)") | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| // Jenkins defines Jenkins API
 | // Jenkins defines Jenkins API
 | ||||||
| type Jenkins interface { | type Jenkins interface { | ||||||
|  | @ -52,6 +55,7 @@ type Jenkins interface { | ||||||
| 	CreateView(name string, viewType string) (*gojenkins.View, error) | 	CreateView(name string, viewType string) (*gojenkins.View, error) | ||||||
| 	Poll() (int, error) | 	Poll() (int, error) | ||||||
| 	ExecuteScript(groovyScript string) (logs string, err error) | 	ExecuteScript(groovyScript string) (logs string, err error) | ||||||
|  | 	GetNodeSecret(name string) (string, error) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type jenkins struct { | type jenkins struct { | ||||||
|  | @ -136,3 +140,23 @@ func isNotFoundError(err error) bool { | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (jenkins *jenkins) GetNodeSecret(name string) (string, error) { | ||||||
|  | 	var content string | ||||||
|  | 	_, err := jenkins.Requester.GetXML(fmt.Sprintf("/computer/%s/slave-agent.jnlp", name), &content, nil) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	match := regex.FindStringSubmatch(content) | ||||||
|  | 	result := make(map[string]string) | ||||||
|  | 
 | ||||||
|  | 	for i, name := range regex.SubexpNames() { | ||||||
|  | 		if i != 0 && name != "" { | ||||||
|  | 			result[name] = match[i] | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return result["secret"], nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -16,6 +16,19 @@ type MockJenkins struct { | ||||||
| 	recorder *MockJenkinsMockRecorder | 	recorder *MockJenkinsMockRecorder | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (m *MockJenkins) GetNodeSecret(name string) (string, error) { | ||||||
|  | 	m.ctrl.T.Helper() | ||||||
|  | 	ret := m.ctrl.Call(m, "GetNodeSecret", name) | ||||||
|  | 	ret0, _ := ret[0].(string) | ||||||
|  | 	ret1, _ := ret[1].(error) | ||||||
|  | 	return ret0, ret1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (mr *MockJenkinsMockRecorder) GetNodeSecret(name string) *gomock.Call { | ||||||
|  | 	mr.mock.ctrl.T.Helper() | ||||||
|  | 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeSecret", reflect.TypeOf((*MockJenkins)(nil).GetNodeSecret), name) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // MockJenkinsMockRecorder is the mock recorder for MockJenkins
 | // MockJenkinsMockRecorder is the mock recorder for MockJenkins
 | ||||||
| type MockJenkinsMockRecorder struct { | type MockJenkinsMockRecorder struct { | ||||||
| 	mock *MockJenkins | 	mock *MockJenkins | ||||||
|  |  | ||||||
|  | @ -168,7 +168,6 @@ import jenkins.model.GlobalConfiguration | ||||||
| GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).useScriptSecurity=false | GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).useScriptSecurity=false | ||||||
| GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).save() | GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).save() | ||||||
| ` | ` | ||||||
| 
 |  | ||||||
| // GetBaseConfigurationConfigMapName returns name of Kubernetes config map used to base configuration
 | // GetBaseConfigurationConfigMapName returns name of Kubernetes config map used to base configuration
 | ||||||
| func GetBaseConfigurationConfigMapName(jenkins *v1alpha2.Jenkins) string { | func GetBaseConfigurationConfigMapName(jenkins *v1alpha2.Jenkins) string { | ||||||
| 	return fmt.Sprintf("%s-base-configuration-%s", constants.OperatorName, jenkins.ObjectMeta.Name) | 	return fmt.Sprintf("%s-base-configuration-%s", constants.OperatorName, jenkins.ObjectMeta.Name) | ||||||
|  |  | ||||||
|  | @ -5,20 +5,24 @@ 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/jobs" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"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" | ||||||
|  | 	appsv1 "k8s.io/api/apps/v1" | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | ||||||
|  | 
 | ||||||
|  | 	apps "k8s.io/api/apps/v1" | ||||||
|  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | 	"sigs.k8s.io/controller-runtime/pkg/client" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -42,6 +46,10 @@ const ( | ||||||
| 	// JenkinsCredentialTypeLabelName is label for kubernetes-credentials-provider-plugin which determine Jenkins
 | 	// JenkinsCredentialTypeLabelName is label for kubernetes-credentials-provider-plugin which determine Jenkins
 | ||||||
| 	// credential type
 | 	// credential type
 | ||||||
| 	JenkinsCredentialTypeLabelName = "jenkins.io/credentials-type" | 	JenkinsCredentialTypeLabelName = "jenkins.io/credentials-type" | ||||||
|  | 
 | ||||||
|  | 	// AgentName is the name of seed job
 | ||||||
|  | 	AgentName = "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
 | ||||||
|  | @ -88,6 +96,24 @@ 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 { | ||||||
|  | 		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 | 	return done, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -233,6 +259,122 @@ func (s *SeedJobs) isRecreatePodNeeded(jenkins v1alpha2.Jenkins) bool { | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func CreateAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string) error { | ||||||
|  | 	var exists bool | ||||||
|  | 
 | ||||||
|  | 	nodes, err := jenkinsClient.GetAllNodes() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(nodes) != 0 { | ||||||
|  | 		for _, node := range nodes { | ||||||
|  | 			if node.GetName() == agentName { | ||||||
|  | 				exists = true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Create node if not exists
 | ||||||
|  | 	if !exists { | ||||||
|  | 		_, err = jenkinsClient.CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	deployments := &apps.DeploymentList{} | ||||||
|  | 	exists = false | ||||||
|  | 	secret, err := jenkinsClient.GetNodeSecret(agentName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	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) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string, secret string) *apps.Deployment { | ||||||
|  | 	return &apps.Deployment{ | ||||||
|  | 		ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 			Name:                       fmt.Sprintf("%s-deployment", agentName), | ||||||
|  | 			Namespace:                  namespace, | ||||||
|  | 		}, | ||||||
|  | 		Spec: apps.DeploymentSpec{ | ||||||
|  | 			Template: corev1.PodTemplateSpec{ | ||||||
|  | 				Spec: corev1.PodSpec{ | ||||||
|  | 					Containers: []corev1.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Name:  fmt.Sprintf("%s-container", agentName), | ||||||
|  | 							Image: "jenkins/jnlp-slave:alpine", | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{ | ||||||
|  | 									Name: "JENKINS_TUNNEL", | ||||||
|  | 									Value: fmt.Sprintf("%s.%s:%d", | ||||||
|  | 										resources.GetJenkinsSlavesServiceName(jenkinsManifest), | ||||||
|  | 										jenkinsManifest.ObjectMeta.Namespace, | ||||||
|  | 										jenkinsManifest.Spec.SlaveService.Port), | ||||||
|  | 								}, | ||||||
|  | 								{ | ||||||
|  | 									Name: "JENKINS_SECRET", | ||||||
|  | 									Value: secret, | ||||||
|  | 								}, | ||||||
|  | 								{ | ||||||
|  | 									Name: "JENKINS_AGENT_NAME", | ||||||
|  | 									Value: agentName, | ||||||
|  | 								}, | ||||||
|  | 								{ | ||||||
|  | 									Name: "JENKINS_URL", | ||||||
|  | 									Value: fmt.Sprintf("http://%s.%s:%d", | ||||||
|  | 										resources.GetJenkinsHTTPServiceName(jenkinsManifest), | ||||||
|  | 										jenkinsManifest.ObjectMeta.Namespace, | ||||||
|  | 										jenkinsManifest.Spec.Service.Port, | ||||||
|  | 									), | ||||||
|  | 								}, | ||||||
|  | 								{ | ||||||
|  | 									Name: "JENKINS_AGENT_WORKDIR", | ||||||
|  | 									Value: "/home/jenkins/agent", | ||||||
|  | 								}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 					Labels: map[string]string{ | ||||||
|  | 						"app": fmt.Sprintf("%s-selector", agentName), | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			Selector: &metav1.LabelSelector{ | ||||||
|  | 				MatchLabels: map[string]string{ | ||||||
|  | 					"app": fmt.Sprintf("%s-selector", agentName), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		Status: apps.DeploymentStatus{}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // seedJobConfigXML this is the XML representation of seed job
 | // seedJobConfigXML this is the XML representation of seed job
 | ||||||
| var seedJobConfigXML = ` | var seedJobConfigXML = ` | ||||||
| <flow-definition plugin="workflow-job@2.30"> | <flow-definition plugin="workflow-job@2.30"> | ||||||
|  | @ -319,7 +461,6 @@ executeDslScripts.setSandbox(false) | ||||||
| executeDslScripts.setRemovedJobAction(RemovedJobAction.DELETE) | executeDslScripts.setRemovedJobAction(RemovedJobAction.DELETE) | ||||||
| executeDslScripts.setRemovedViewAction(RemovedViewAction.DELETE) | executeDslScripts.setRemovedViewAction(RemovedViewAction.DELETE) | ||||||
| executeDslScripts.setLookupStrategy(LookupStrategy.SEED_JOB) | executeDslScripts.setLookupStrategy(LookupStrategy.SEED_JOB) | ||||||
| executeDslScripts.setAdditionalClasspath("src") |  | ||||||
| 
 | 
 | ||||||
| if (jobRef == null) { | if (jobRef == null) { | ||||||
|         jobRef = jenkins.createProject(FreeStyleProject, jobDslSeedName) |         jobRef = jenkins.createProject(FreeStyleProject, jobDslSeedName) | ||||||
|  | @ -329,7 +470,7 @@ jobRef.getBuildersList().add(executeDslScripts) | ||||||
| jobRef.setDisplayName("${params.` + displayNameParameterName + `}") | jobRef.setDisplayName("${params.` + displayNameParameterName + `}") | ||||||
| jobRef.setScm(scm) | jobRef.setScm(scm) | ||||||
| // TODO don't use master executors
 | // TODO don't use master executors
 | ||||||
| jobRef.setAssignedLabel(new LabelAtom("master")) | jobRef.setAssignedLabel(new LabelAtom("`+AgentName+`")) | ||||||
| 
 | 
 | ||||||
| jenkins.getQueue().schedule(jobRef) | jenkins.getQueue().schedule(jobRef) | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -6,12 +6,13 @@ import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"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/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/bndr/gojenkins" | 	"github.com/bndr/gojenkins" | ||||||
| 	"github.com/golang/mock/gomock" | 	"github.com/golang/mock/gomock" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	appsv1 "k8s.io/api/apps/v1" | ||||||
| 	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" | ||||||
|  | @ -28,7 +29,7 @@ func TestEnsureSeedJobs(t *testing.T) { | ||||||
| 	ctx := context.TODO() | 	ctx := context.TODO() | ||||||
| 	defer ctrl.Finish() | 	defer ctrl.Finish() | ||||||
| 
 | 
 | ||||||
| 	jenkinsClient := client.NewMockJenkins(ctrl) | 	jenkinsClient := jenkinsclient.NewMockJenkins(ctrl) | ||||||
| 	fakeClient := fake.NewFakeClient() | 	fakeClient := fake.NewFakeClient() | ||||||
| 	err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme) | 	err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  | @ -219,3 +220,80 @@ func TestSeedJobs_isRecreatePodNeeded(t *testing.T) { | ||||||
| 		assert.True(t, got) | 		assert.True(t, got) | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 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) { | ||||||
|  | 		// given
 | ||||||
|  | 		ctrl := gomock.NewController(t) | ||||||
|  | 		ctx := context.TODO() | ||||||
|  | 		defer ctrl.Finish() | ||||||
|  | 
 | ||||||
|  | 		namespace := "test-namespace" | ||||||
|  | 		agentName := "test-agent" | ||||||
|  | 		secret := "test-secret" | ||||||
|  | 
 | ||||||
|  | 		jenkinsClient := jenkinsclient.NewMockJenkins(ctrl) | ||||||
|  | 		fakeClient := fake.NewFakeClient() | ||||||
|  | 		err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme) | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 		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) | ||||||
|  | 
 | ||||||
|  | 		// when
 | ||||||
|  | 		err = fakeClient.Create(ctx, &appsv1.Deployment{ | ||||||
|  | 			ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 				Name: fmt.Sprintf("%s-deployment", agentName), | ||||||
|  | 				Namespace:namespace, | ||||||
|  | 			}, | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 		// then
 | ||||||
|  | 		err = CreateAgent(jenkinsClient, fakeClient, jenkinsCustomResource(), namespace, agentName) | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | @ -4,7 +4,7 @@ const ( | ||||||
| 	// OperatorName is a operator name
 | 	// OperatorName is a operator name
 | ||||||
| 	OperatorName = "jenkins-operator" | 	OperatorName = "jenkins-operator" | ||||||
| 	// DefaultAmountOfExecutors is the default amount of Jenkins executors
 | 	// DefaultAmountOfExecutors is the default amount of Jenkins executors
 | ||||||
| 	DefaultAmountOfExecutors = 3 | 	DefaultAmountOfExecutors = 0 | ||||||
| 	// SeedJobSuffix is a suffix added for all seed jobs
 | 	// SeedJobSuffix is a suffix added for all seed jobs
 | ||||||
| 	SeedJobSuffix = "job-dsl-seed" | 	SeedJobSuffix = "job-dsl-seed" | ||||||
| 	// DefaultJenkinsMasterImage is the default Jenkins master docker image
 | 	// DefaultJenkinsMasterImage is the default Jenkins master docker image
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue