Refactoring for jenkins client (#366)
This commit is contained in:
		
							parent
							
								
									12ecfaa2b3
								
							
						
					
					
						commit
						eb8b2e32e8
					
				
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							|  | @ -23,7 +23,7 @@ require ( | ||||||
| 	go.uber.org/zap v1.14.1 | 	go.uber.org/zap v1.14.1 | ||||||
| 	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect | 	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect | ||||||
| 	golang.org/x/net v0.0.0-20200226121028-0de0cce0169b | 	golang.org/x/net v0.0.0-20200226121028-0de0cce0169b | ||||||
| 	golang.org/x/tools v0.0.0-20200504022951-6b6965ac5dd1 // indirect | 	golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8 // indirect | ||||||
| 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect | 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect | ||||||
| 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||||||
| 	k8s.io/api v0.17.4 | 	k8s.io/api v0.17.4 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							|  | @ -958,6 +958,8 @@ golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b h1:zSzQJAznWxAh9fZxiPy2FZo | ||||||
| golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||||||
| golang.org/x/tools v0.0.0-20200504022951-6b6965ac5dd1 h1:C8rdnd6KieI73Z2Av0sS0t4kW+geIH/M8kNX8Hmvn9E= | golang.org/x/tools v0.0.0-20200504022951-6b6965ac5dd1 h1:C8rdnd6KieI73Z2Av0sS0t4kW+geIH/M8kNX8Hmvn9E= | ||||||
| golang.org/x/tools v0.0.0-20200504022951-6b6965ac5dd1/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | golang.org/x/tools v0.0.0-20200504022951-6b6965ac5dd1/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||||||
|  | golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8 h1:BMFHd4OFnFtWX46Xj4DN6vvT1btiBxyq+s0orYBqcQY= | ||||||
|  | golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= | ||||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
|  |  | ||||||
|  | @ -147,7 +147,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Check if this Pod already exists
 | 	// Check if this Pod already exists
 | ||||||
| 	currentJenkinsMasterPod, err := r.getJenkinsMasterPod() | 	currentJenkinsMasterPod, err := r.Configuration.GetJenkinsMasterPod() | ||||||
| 	if err != nil && apierrors.IsNotFound(err) { | 	if err != nil && apierrors.IsNotFound(err) { | ||||||
| 		jenkinsMasterPod := resources.NewJenkinsMasterPod(meta, r.Configuration.Jenkins) | 		jenkinsMasterPod := resources.NewJenkinsMasterPod(meta, r.Configuration.Jenkins) | ||||||
| 		*r.Notifications <- event.Event{ | 		*r.Notifications <- event.Event{ | ||||||
|  |  | ||||||
|  | @ -83,7 +83,7 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki | ||||||
| 	} | 	} | ||||||
| 	r.logger.V(log.VDebug).Info("Jenkins master pod is ready") | 	r.logger.V(log.VDebug).Info("Jenkins master pod is ready") | ||||||
| 
 | 
 | ||||||
| 	jenkinsClient, err := r.ensureJenkinsClient() | 	jenkinsClient, err := r.Configuration.GetJenkinsClient() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, nil, err | 		return reconcile.Result{}, nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -110,32 +110,6 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki | ||||||
| 	return result, jenkinsClient, err | 	return result, jenkinsClient, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetJenkinsOpts gets JENKINS_OPTS env parameter, parses it's values and returns it as a map`
 |  | ||||||
| func GetJenkinsOpts(jenkins v1alpha2.Jenkins) map[string]string { |  | ||||||
| 	envs := jenkins.Spec.Master.Containers[0].Env |  | ||||||
| 	jenkinsOpts := make(map[string]string) |  | ||||||
| 
 |  | ||||||
| 	for key, value := range envs { |  | ||||||
| 		if value.Name == "JENKINS_OPTS" { |  | ||||||
| 			jenkinsOptsEnv := envs[key] |  | ||||||
| 			jenkinsOptsWithDashes := jenkinsOptsEnv.Value |  | ||||||
| 			if len(jenkinsOptsWithDashes) == 0 { |  | ||||||
| 				return nil |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			jenkinsOptsWithEqOperators := strings.Split(jenkinsOptsWithDashes, " ") |  | ||||||
| 
 |  | ||||||
| 			for _, vx := range jenkinsOptsWithEqOperators { |  | ||||||
| 				opt := strings.Split(vx, "=") |  | ||||||
| 				jenkinsOpts[strings.ReplaceAll(opt[0], "--", "")] = opt[1] |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			return jenkinsOpts |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod(metaObject metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod(metaObject metav1.ObjectMeta) error { | ||||||
| 	if err := r.createOperatorCredentialsSecret(metaObject); err != nil { | 	if err := r.createOperatorCredentialsSecret(metaObject); err != nil { | ||||||
| 		return err | 		return err | ||||||
|  | @ -216,16 +190,6 @@ func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta | ||||||
| 	return stackerr.WithStack(r.UpdateResource(resources.NewOperatorCredentialsSecret(meta, r.Configuration.Jenkins))) | 	return stackerr.WithStack(r.UpdateResource(resources.NewOperatorCredentialsSecret(meta, r.Configuration.Jenkins))) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) getJenkinsMasterPod() (*corev1.Pod, error) { |  | ||||||
| 	jenkinsMasterPodName := resources.GetJenkinsMasterPodName(*r.Configuration.Jenkins) |  | ||||||
| 	currentJenkinsMasterPod := &corev1.Pod{} |  | ||||||
| 	err := r.Client.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPodName, Namespace: r.Configuration.Jenkins.Namespace}, currentJenkinsMasterPod) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err // don't wrap error
 |  | ||||||
| 	} |  | ||||||
| 	return currentJenkinsMasterPod, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) calculateUserAndPasswordHash() (string, error) { | func (r *ReconcileJenkinsBaseConfiguration) calculateUserAndPasswordHash() (string, error) { | ||||||
| 	credentialsSecret := &corev1.Secret{} | 	credentialsSecret := &corev1.Secret{} | ||||||
| 	err := r.Client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.Configuration.Jenkins), Namespace: r.Configuration.Jenkins.ObjectMeta.Namespace}, credentialsSecret) | 	err := r.Client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.Configuration.Jenkins), Namespace: r.Configuration.Jenkins.ObjectMeta.Namespace}, credentialsSecret) | ||||||
|  | @ -309,7 +273,7 @@ func (r *ReconcileJenkinsBaseConfiguration) compareVolumes(actualPod corev1.Pod) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) detectJenkinsMasterPodStartingIssues() (stopReconcileLoop bool, err error) { | func (r *ReconcileJenkinsBaseConfiguration) detectJenkinsMasterPodStartingIssues() (stopReconcileLoop bool, err error) { | ||||||
| 	jenkinsMasterPod, err := r.getJenkinsMasterPod() | 	jenkinsMasterPod, err := r.Configuration.GetJenkinsMasterPod() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
|  | @ -360,7 +324,7 @@ func (r *ReconcileJenkinsBaseConfiguration) filterEvents(source corev1.EventList | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) waitForJenkins() (reconcile.Result, error) { | func (r *ReconcileJenkinsBaseConfiguration) waitForJenkins() (reconcile.Result, error) { | ||||||
| 	jenkinsMasterPod, err := r.getJenkinsMasterPod() | 	jenkinsMasterPod, err := r.Configuration.GetJenkinsMasterPod() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, err | ||||||
| 	} | 	} | ||||||
|  | @ -400,106 +364,6 @@ func (r *ReconcileJenkinsBaseConfiguration) waitForJenkins() (reconcile.Result, | ||||||
| 	return reconcile.Result{}, nil | 	return reconcile.Result{}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient.Jenkins, error) { |  | ||||||
| 	switch r.Configuration.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy { |  | ||||||
| 	case v1alpha2.ServiceAccountAuthorizationStrategy: |  | ||||||
| 		return r.ensureJenkinsClientFromServiceAccount() |  | ||||||
| 	case v1alpha2.CreateUserAuthorizationStrategy: |  | ||||||
| 		return r.ensureJenkinsClientFromSecret() |  | ||||||
| 	default: |  | ||||||
| 		return nil, stackerr.Errorf("unrecognized '%s' spec.jenkinsAPISettings.authorizationStrategy", r.Configuration.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) getJenkinsAPIUrl() (string, error) { |  | ||||||
| 	var service corev1.Service |  | ||||||
| 
 |  | ||||||
| 	err := r.Client.Get(context.TODO(), types.NamespacedName{ |  | ||||||
| 		Namespace: r.Configuration.Jenkins.ObjectMeta.Namespace, |  | ||||||
| 		Name:      resources.GetJenkinsHTTPServiceName(r.Configuration.Jenkins), |  | ||||||
| 	}, &service) |  | ||||||
| 
 |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 	jenkinsURL := r.jenkinsAPIConnectionSettings.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort) |  | ||||||
| 	if prefix, ok := GetJenkinsOpts(*r.Configuration.Jenkins)["prefix"]; ok { |  | ||||||
| 		jenkinsURL = jenkinsURL + prefix |  | ||||||
| 	} |  | ||||||
| 	return jenkinsURL, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClientFromServiceAccount() (jenkinsclient.Jenkins, error) { |  | ||||||
| 	jenkinsAPIUrl, err := r.getJenkinsAPIUrl() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	podName := resources.GetJenkinsMasterPodName(*r.Configuration.Jenkins) |  | ||||||
| 	token, _, err := r.Configuration.Exec(podName, resources.JenkinsMasterContainerName, []string{"cat", "/var/run/secrets/kubernetes.io/serviceaccount/token"}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return jenkinsclient.NewBearerTokenAuthorization(jenkinsAPIUrl, token.String()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClientFromSecret() (jenkinsclient.Jenkins, error) { |  | ||||||
| 	jenkinsURL, err := r.getJenkinsAPIUrl() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	r.logger.V(log.VDebug).Info(fmt.Sprintf("Jenkins API URL '%s'", jenkinsURL)) |  | ||||||
| 	credentialsSecret := &corev1.Secret{} |  | ||||||
| 	err = r.Client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.Configuration.Jenkins), Namespace: r.Configuration.Jenkins.ObjectMeta.Namespace}, credentialsSecret) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, stackerr.WithStack(err) |  | ||||||
| 	} |  | ||||||
| 	currentJenkinsMasterPod, err := r.getJenkinsMasterPod() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	var tokenCreationTime *time.Time |  | ||||||
| 	tokenCreationTimeBytes := credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] |  | ||||||
| 	if tokenCreationTimeBytes != nil { |  | ||||||
| 		tokenCreationTime = &time.Time{} |  | ||||||
| 		err = tokenCreationTime.UnmarshalText(tokenCreationTimeBytes) |  | ||||||
| 		if err != nil { |  | ||||||
| 			tokenCreationTime = nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey] == nil || |  | ||||||
| 		tokenCreationTimeBytes == nil || tokenCreationTime == nil || |  | ||||||
| 		currentJenkinsMasterPod.ObjectMeta.CreationTimestamp.Time.UTC().After(tokenCreationTime.UTC()) { |  | ||||||
| 		r.logger.Info("Generating Jenkins API token for operator") |  | ||||||
| 		userName := string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]) |  | ||||||
| 		jenkinsClient, err := jenkinsclient.NewUserAndPasswordAuthorization( |  | ||||||
| 			jenkinsURL, |  | ||||||
| 			userName, |  | ||||||
| 			string(credentialsSecret.Data[resources.OperatorCredentialsSecretPasswordKey])) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		token, err := jenkinsClient.GenerateToken(userName, "token") |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey] = []byte(token.GetToken()) |  | ||||||
| 		now, _ := time.Now().UTC().MarshalText() |  | ||||||
| 		credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] = now |  | ||||||
| 		err = r.UpdateResource(credentialsSecret) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, stackerr.WithStack(err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return jenkinsclient.NewUserAndPasswordAuthorization( |  | ||||||
| 		jenkinsURL, |  | ||||||
| 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]), |  | ||||||
| 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey])) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) ensureBaseConfiguration(jenkinsClient jenkinsclient.Jenkins) (reconcile.Result, error) { | func (r *ReconcileJenkinsBaseConfiguration) ensureBaseConfiguration(jenkinsClient jenkinsclient.Jenkins) (reconcile.Result, error) { | ||||||
| 	customization := v1alpha2.GroovyScripts{ | 	customization := v1alpha2.GroovyScripts{ | ||||||
| 		Customization: v1alpha2.Customization{ | 		Customization: v1alpha2.Customization{ | ||||||
|  | @ -517,14 +381,14 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureBaseConfiguration(jenkinsClien | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) waitUntilCreateJenkinsMasterPod() (currentJenkinsMasterPod *corev1.Pod, err error) { | func (r *ReconcileJenkinsBaseConfiguration) waitUntilCreateJenkinsMasterPod() (currentJenkinsMasterPod *corev1.Pod, err error) { | ||||||
| 	currentJenkinsMasterPod, err = r.getJenkinsMasterPod() | 	currentJenkinsMasterPod, err = r.Configuration.GetJenkinsMasterPod() | ||||||
| 	for { | 	for { | ||||||
| 		if err != nil && !apierrors.IsNotFound(err) { | 		if err != nil && !apierrors.IsNotFound(err) { | ||||||
| 			return nil, stackerr.WithStack(err) | 			return nil, stackerr.WithStack(err) | ||||||
| 		} else if err == nil { | 		} else if err == nil { | ||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
| 		currentJenkinsMasterPod, err = r.getJenkinsMasterPod() | 		currentJenkinsMasterPod, err = r.Configuration.GetJenkinsMasterPod() | ||||||
| 		time.Sleep(time.Millisecond * 10) | 		time.Sleep(time.Millisecond * 10) | ||||||
| 	} | 	} | ||||||
| 	return | 	return | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ import ( | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration" | ||||||
| 	"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/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
| 
 |  | ||||||
| 	"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" | ||||||
|  | @ -22,140 +21,6 @@ import ( | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/client/fake" | 	"sigs.k8s.io/controller-runtime/pkg/client/fake" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestGetJenkinsOpts(t *testing.T) { |  | ||||||
| 	t.Run("JENKINS_OPTS is uninitialized", func(t *testing.T) { |  | ||||||
| 		jenkins := v1alpha2.Jenkins{ |  | ||||||
| 			Spec: v1alpha2.JenkinsSpec{ |  | ||||||
| 				Master: v1alpha2.JenkinsMaster{ |  | ||||||
| 					Containers: []v1alpha2.Container{ |  | ||||||
| 						{ |  | ||||||
| 							Env: []corev1.EnvVar{ |  | ||||||
| 								{Name: "", Value: ""}, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		opts := GetJenkinsOpts(jenkins) |  | ||||||
| 		assert.Equal(t, 0, len(opts)) |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	t.Run("JENKINS_OPTS is empty", func(t *testing.T) { |  | ||||||
| 		jenkins := v1alpha2.Jenkins{ |  | ||||||
| 			Spec: v1alpha2.JenkinsSpec{ |  | ||||||
| 				Master: v1alpha2.JenkinsMaster{ |  | ||||||
| 					Containers: []v1alpha2.Container{ |  | ||||||
| 						{ |  | ||||||
| 							Env: []corev1.EnvVar{ |  | ||||||
| 								{Name: "JENKINS_OPTS", Value: ""}, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		opts := GetJenkinsOpts(jenkins) |  | ||||||
| 		assert.Equal(t, 0, len(opts)) |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	t.Run("JENKINS_OPTS have --prefix argument ", func(t *testing.T) { |  | ||||||
| 		jenkins := v1alpha2.Jenkins{ |  | ||||||
| 			Spec: v1alpha2.JenkinsSpec{ |  | ||||||
| 				Master: v1alpha2.JenkinsMaster{ |  | ||||||
| 					Containers: []v1alpha2.Container{ |  | ||||||
| 						{ |  | ||||||
| 							Env: []corev1.EnvVar{ |  | ||||||
| 								{Name: "JENKINS_OPTS", Value: "--prefix=/jenkins"}, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		opts := GetJenkinsOpts(jenkins) |  | ||||||
| 
 |  | ||||||
| 		assert.Equal(t, 1, len(opts)) |  | ||||||
| 		assert.NotContains(t, opts, "httpPort") |  | ||||||
| 		assert.Contains(t, opts, "prefix") |  | ||||||
| 		assert.Equal(t, opts["prefix"], "/jenkins") |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	t.Run("JENKINS_OPTS have --prefix and --httpPort argument", func(t *testing.T) { |  | ||||||
| 		jenkins := v1alpha2.Jenkins{ |  | ||||||
| 			Spec: v1alpha2.JenkinsSpec{ |  | ||||||
| 				Master: v1alpha2.JenkinsMaster{ |  | ||||||
| 					Containers: []v1alpha2.Container{ |  | ||||||
| 						{ |  | ||||||
| 							Env: []corev1.EnvVar{ |  | ||||||
| 								{Name: "JENKINS_OPTS", Value: "--prefix=/jenkins --httpPort=8080"}, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		opts := GetJenkinsOpts(jenkins) |  | ||||||
| 
 |  | ||||||
| 		assert.Equal(t, 2, len(opts)) |  | ||||||
| 
 |  | ||||||
| 		assert.Contains(t, opts, "prefix") |  | ||||||
| 		assert.Equal(t, opts["prefix"], "/jenkins") |  | ||||||
| 
 |  | ||||||
| 		assert.Contains(t, opts, "httpPort") |  | ||||||
| 		assert.Equal(t, opts["httpPort"], "8080") |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	t.Run("JENKINS_OPTS have --httpPort argument", func(t *testing.T) { |  | ||||||
| 		jenkins := v1alpha2.Jenkins{ |  | ||||||
| 			Spec: v1alpha2.JenkinsSpec{ |  | ||||||
| 				Master: v1alpha2.JenkinsMaster{ |  | ||||||
| 					Containers: []v1alpha2.Container{ |  | ||||||
| 						{ |  | ||||||
| 							Env: []corev1.EnvVar{ |  | ||||||
| 								{Name: "JENKINS_OPTS", Value: "--httpPort=8080"}, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		opts := GetJenkinsOpts(jenkins) |  | ||||||
| 
 |  | ||||||
| 		assert.Equal(t, 1, len(opts)) |  | ||||||
| 		assert.NotContains(t, opts, "prefix") |  | ||||||
| 		assert.Contains(t, opts, "httpPort") |  | ||||||
| 		assert.Equal(t, opts["httpPort"], "8080") |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	t.Run("JENKINS_OPTS have --httpPort=--8080 argument", func(t *testing.T) { |  | ||||||
| 		jenkins := v1alpha2.Jenkins{ |  | ||||||
| 			Spec: v1alpha2.JenkinsSpec{ |  | ||||||
| 				Master: v1alpha2.JenkinsMaster{ |  | ||||||
| 					Containers: []v1alpha2.Container{ |  | ||||||
| 						{ |  | ||||||
| 							Env: []corev1.EnvVar{ |  | ||||||
| 								{Name: "JENKINS_OPTS", Value: "--httpPort=--8080"}, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		opts := GetJenkinsOpts(jenkins) |  | ||||||
| 
 |  | ||||||
| 		assert.Equal(t, 1, len(opts)) |  | ||||||
| 		assert.NotContains(t, opts, "prefix") |  | ||||||
| 		assert.Contains(t, opts, "httpPort") |  | ||||||
| 		assert.Equal(t, opts["httpPort"], "--8080") |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| func TestCompareContainerVolumeMounts(t *testing.T) { | func TestCompareContainerVolumeMounts(t *testing.T) { | ||||||
| 	t.Run("happy with service account", func(t *testing.T) { | 	t.Run("happy with service account", func(t *testing.T) { | ||||||
|  |  | ||||||
|  | @ -3,12 +3,14 @@ package configuration | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"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/configuration/base/resources" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/notifications/event" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/notifications/event" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/notifications/reason" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/notifications/reason" | ||||||
| 
 | 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" | ||||||
| 	stackerr "github.com/pkg/errors" | 	stackerr "github.com/pkg/errors" | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
|  | @ -25,17 +27,18 @@ import ( | ||||||
| 
 | 
 | ||||||
| // Configuration holds required for Jenkins configuration
 | // Configuration holds required for Jenkins configuration
 | ||||||
| type Configuration struct { | type Configuration struct { | ||||||
| 	Client        client.Client | 	Client                       client.Client | ||||||
| 	ClientSet     kubernetes.Clientset | 	ClientSet                    kubernetes.Clientset | ||||||
| 	Notifications *chan event.Event | 	Notifications                *chan event.Event | ||||||
| 	Jenkins       *v1alpha2.Jenkins | 	Jenkins                      *v1alpha2.Jenkins | ||||||
| 	Scheme        *runtime.Scheme | 	Scheme                       *runtime.Scheme | ||||||
| 	Config        *rest.Config | 	Config                       *rest.Config | ||||||
|  | 	JenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RestartJenkinsMasterPod terminate Jenkins master pod and notifies about it
 | // RestartJenkinsMasterPod terminate Jenkins master pod and notifies about it
 | ||||||
| func (c *Configuration) RestartJenkinsMasterPod(reason reason.Reason) error { | func (c *Configuration) RestartJenkinsMasterPod(reason reason.Reason) error { | ||||||
| 	currentJenkinsMasterPod, err := c.getJenkinsMasterPod() | 	currentJenkinsMasterPod, err := c.GetJenkinsMasterPod() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | @ -54,7 +57,8 @@ func (c *Configuration) RestartJenkinsMasterPod(reason reason.Reason) error { | ||||||
| 	return stackerr.WithStack(c.Client.Delete(context.TODO(), currentJenkinsMasterPod)) | 	return stackerr.WithStack(c.Client.Delete(context.TODO(), currentJenkinsMasterPod)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Configuration) getJenkinsMasterPod() (*corev1.Pod, error) { | // GetJenkinsMasterPod gets the jenkins master pod
 | ||||||
|  | func (c *Configuration) GetJenkinsMasterPod() (*corev1.Pod, error) { | ||||||
| 	jenkinsMasterPodName := resources.GetJenkinsMasterPodName(*c.Jenkins) | 	jenkinsMasterPodName := resources.GetJenkinsMasterPodName(*c.Jenkins) | ||||||
| 	currentJenkinsMasterPod := &corev1.Pod{} | 	currentJenkinsMasterPod := &corev1.Pod{} | ||||||
| 	err := c.Client.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPodName, Namespace: c.Jenkins.Namespace}, currentJenkinsMasterPod) | 	err := c.Client.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPodName, Namespace: c.Jenkins.Namespace}, currentJenkinsMasterPod) | ||||||
|  | @ -159,3 +163,130 @@ func (c *Configuration) GetJenkinsMasterContainer() *v1alpha2.Container { | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // GetJenkinsClient gets jenkins client from a configuration
 | ||||||
|  | func (c *Configuration) GetJenkinsClient() (jenkinsclient.Jenkins, error) { | ||||||
|  | 	switch c.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy  { | ||||||
|  | 	case v1alpha2.ServiceAccountAuthorizationStrategy: | ||||||
|  | 		return c.GetJenkinsClientFromServiceAccount() | ||||||
|  | 	case v1alpha2.CreateUserAuthorizationStrategy: | ||||||
|  | 		return c.GetJenkinsClientFromSecret() | ||||||
|  | 	default: | ||||||
|  | 		return nil, stackerr.Errorf("unrecognized '%s' spec.jenkinsAPISettings.authorizationStrategy", c.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *Configuration) getJenkinsAPIUrl() (string, error) { | ||||||
|  | 	var service corev1.Service | ||||||
|  | 
 | ||||||
|  | 	err := c.Client.Get(context.TODO(), types.NamespacedName{ | ||||||
|  | 		Namespace: c.Jenkins.ObjectMeta.Namespace, | ||||||
|  | 		Name:      resources.GetJenkinsHTTPServiceName(c.Jenkins), | ||||||
|  | 	}, &service) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	jenkinsURL := c.JenkinsAPIConnectionSettings.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort) | ||||||
|  | 	if prefix, ok := GetJenkinsOpts(*c.Jenkins)["prefix"]; ok { | ||||||
|  | 		jenkinsURL = jenkinsURL + prefix | ||||||
|  | 	} | ||||||
|  | 	return jenkinsURL, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetJenkinsClientFromServiceAccount gets jenkins client from a serviceAccount
 | ||||||
|  | func (c *Configuration) GetJenkinsClientFromServiceAccount() (jenkinsclient.Jenkins, error) { | ||||||
|  | 	jenkinsAPIUrl, err := c.getJenkinsAPIUrl() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	podName := resources.GetJenkinsMasterPodName(*c.Jenkins) | ||||||
|  | 	token, _, err := c.Exec(podName, resources.JenkinsMasterContainerName, []string{"cat", "/var/run/secrets/kubernetes.io/serviceaccount/token"}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return jenkinsclient.NewBearerTokenAuthorization(jenkinsAPIUrl, token.String()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetJenkinsClientFromSecret gets jenkins client from a secret
 | ||||||
|  | func (c *Configuration) GetJenkinsClientFromSecret() (jenkinsclient.Jenkins, error) { | ||||||
|  | 	jenkinsURL, err := c.getJenkinsAPIUrl() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	credentialsSecret := &corev1.Secret{} | ||||||
|  | 	err = c.Client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(c.Jenkins), Namespace: c.Jenkins.ObjectMeta.Namespace}, credentialsSecret) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, stackerr.WithStack(err) | ||||||
|  | 	} | ||||||
|  | 	currentJenkinsMasterPod, err := c.GetJenkinsMasterPod() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	var tokenCreationTime *time.Time | ||||||
|  | 	tokenCreationTimeBytes := credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] | ||||||
|  | 	if tokenCreationTimeBytes != nil { | ||||||
|  | 		tokenCreationTime = &time.Time{} | ||||||
|  | 		err = tokenCreationTime.UnmarshalText(tokenCreationTimeBytes) | ||||||
|  | 		if err != nil { | ||||||
|  | 			tokenCreationTime = nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey] == nil || | ||||||
|  | 		tokenCreationTimeBytes == nil || tokenCreationTime == nil || | ||||||
|  | 		currentJenkinsMasterPod.ObjectMeta.CreationTimestamp.Time.UTC().After(tokenCreationTime.UTC()) { | ||||||
|  | 		userName := string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]) | ||||||
|  | 		jenkinsClient, err := jenkinsclient.NewUserAndPasswordAuthorization( | ||||||
|  | 			jenkinsURL, | ||||||
|  | 			userName, | ||||||
|  | 			string(credentialsSecret.Data[resources.OperatorCredentialsSecretPasswordKey])) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		token, err := jenkinsClient.GenerateToken(userName, "token") | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey] = []byte(token.GetToken()) | ||||||
|  | 		now, _ := time.Now().UTC().MarshalText() | ||||||
|  | 		credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] = now | ||||||
|  | 		err = c.UpdateResource(credentialsSecret) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, stackerr.WithStack(err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return jenkinsclient.NewUserAndPasswordAuthorization( | ||||||
|  | 		jenkinsURL, | ||||||
|  | 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]), | ||||||
|  | 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey])) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetJenkinsOpts gets JENKINS_OPTS env parameter, parses it's values and returns it as a map`
 | ||||||
|  | func GetJenkinsOpts(jenkins v1alpha2.Jenkins) map[string]string { | ||||||
|  | 	envs := jenkins.Spec.Master.Containers[0].Env | ||||||
|  | 	jenkinsOpts := make(map[string]string) | ||||||
|  | 
 | ||||||
|  | 	for key, value := range envs { | ||||||
|  | 		if value.Name == "JENKINS_OPTS" { | ||||||
|  | 			jenkinsOptsEnv := envs[key] | ||||||
|  | 			jenkinsOptsWithDashes := jenkinsOptsEnv.Value | ||||||
|  | 			if len(jenkinsOptsWithDashes) == 0 { | ||||||
|  | 				return nil | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			jenkinsOptsWithEqOperators := strings.Split(jenkinsOptsWithDashes, " ") | ||||||
|  | 
 | ||||||
|  | 			for _, vx := range jenkinsOptsWithEqOperators { | ||||||
|  | 				opt := strings.Split(vx, "=") | ||||||
|  | 				jenkinsOpts[strings.ReplaceAll(opt[0], "--", "")] = opt[1] | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return jenkinsOpts | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | @ -0,0 +1,144 @@ | ||||||
|  | package configuration | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 	 | ||||||
|  | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	corev1 "k8s.io/api/core/v1" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestGetJenkinsOpts(t *testing.T) { | ||||||
|  | 	t.Run("JENKINS_OPTS is uninitialized", func(t *testing.T) { | ||||||
|  | 		jenkins := v1alpha2.Jenkins{ | ||||||
|  | 			Spec: v1alpha2.JenkinsSpec{ | ||||||
|  | 				Master: v1alpha2.JenkinsMaster{ | ||||||
|  | 					Containers: []v1alpha2.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{Name: "", Value: ""}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		opts := GetJenkinsOpts(jenkins) | ||||||
|  | 		assert.Equal(t, 0, len(opts)) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("JENKINS_OPTS is empty", func(t *testing.T) { | ||||||
|  | 		jenkins := v1alpha2.Jenkins{ | ||||||
|  | 			Spec: v1alpha2.JenkinsSpec{ | ||||||
|  | 				Master: v1alpha2.JenkinsMaster{ | ||||||
|  | 					Containers: []v1alpha2.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{Name: "JENKINS_OPTS", Value: ""}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		opts := GetJenkinsOpts(jenkins) | ||||||
|  | 		assert.Equal(t, 0, len(opts)) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("JENKINS_OPTS have --prefix argument ", func(t *testing.T) { | ||||||
|  | 		jenkins := v1alpha2.Jenkins{ | ||||||
|  | 			Spec: v1alpha2.JenkinsSpec{ | ||||||
|  | 				Master: v1alpha2.JenkinsMaster{ | ||||||
|  | 					Containers: []v1alpha2.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{Name: "JENKINS_OPTS", Value: "--prefix=/jenkins"}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		opts := GetJenkinsOpts(jenkins) | ||||||
|  | 
 | ||||||
|  | 		assert.Equal(t, 1, len(opts)) | ||||||
|  | 		assert.NotContains(t, opts, "httpPort") | ||||||
|  | 		assert.Contains(t, opts, "prefix") | ||||||
|  | 		assert.Equal(t, opts["prefix"], "/jenkins") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("JENKINS_OPTS have --prefix and --httpPort argument", func(t *testing.T) { | ||||||
|  | 		jenkins := v1alpha2.Jenkins{ | ||||||
|  | 			Spec: v1alpha2.JenkinsSpec{ | ||||||
|  | 				Master: v1alpha2.JenkinsMaster{ | ||||||
|  | 					Containers: []v1alpha2.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{Name: "JENKINS_OPTS", Value: "--prefix=/jenkins --httpPort=8080"}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		opts := GetJenkinsOpts(jenkins) | ||||||
|  | 
 | ||||||
|  | 		assert.Equal(t, 2, len(opts)) | ||||||
|  | 
 | ||||||
|  | 		assert.Contains(t, opts, "prefix") | ||||||
|  | 		assert.Equal(t, opts["prefix"], "/jenkins") | ||||||
|  | 
 | ||||||
|  | 		assert.Contains(t, opts, "httpPort") | ||||||
|  | 		assert.Equal(t, opts["httpPort"], "8080") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("JENKINS_OPTS have --httpPort argument", func(t *testing.T) { | ||||||
|  | 		jenkins := v1alpha2.Jenkins{ | ||||||
|  | 			Spec: v1alpha2.JenkinsSpec{ | ||||||
|  | 				Master: v1alpha2.JenkinsMaster{ | ||||||
|  | 					Containers: []v1alpha2.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{Name: "JENKINS_OPTS", Value: "--httpPort=8080"}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		opts := GetJenkinsOpts(jenkins) | ||||||
|  | 
 | ||||||
|  | 		assert.Equal(t, 1, len(opts)) | ||||||
|  | 		assert.NotContains(t, opts, "prefix") | ||||||
|  | 		assert.Contains(t, opts, "httpPort") | ||||||
|  | 		assert.Equal(t, opts["httpPort"], "8080") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("JENKINS_OPTS have --httpPort=--8080 argument", func(t *testing.T) { | ||||||
|  | 		jenkins := v1alpha2.Jenkins{ | ||||||
|  | 			Spec: v1alpha2.JenkinsSpec{ | ||||||
|  | 				Master: v1alpha2.JenkinsMaster{ | ||||||
|  | 					Containers: []v1alpha2.Container{ | ||||||
|  | 						{ | ||||||
|  | 							Env: []corev1.EnvVar{ | ||||||
|  | 								{Name: "JENKINS_OPTS", Value: "--httpPort=--8080"}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		opts := GetJenkinsOpts(jenkins) | ||||||
|  | 
 | ||||||
|  | 		assert.Equal(t, 1, len(opts)) | ||||||
|  | 		assert.NotContains(t, opts, "prefix") | ||||||
|  | 		assert.Contains(t, opts, "httpPort") | ||||||
|  | 		assert.Equal(t, opts["httpPort"], "--8080") | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | @ -381,7 +381,7 @@ func agentDeployment(jenkins *v1alpha2.Jenkins, namespace string, agentName stri | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	jenkinsHttpServiceFQDN, err := resources.GetJenkinsHTTPServiceFQDN(jenkins) | 	jenkinsHTTPServiceFQDN, err := resources.GetJenkinsHTTPServiceFQDN(jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -428,7 +428,7 @@ func agentDeployment(jenkins *v1alpha2.Jenkins, namespace string, agentName stri | ||||||
| 								{ | 								{ | ||||||
| 									Name: "JENKINS_URL", | 									Name: "JENKINS_URL", | ||||||
| 									Value: fmt.Sprintf("http://%s:%d", | 									Value: fmt.Sprintf("http://%s:%d", | ||||||
| 										jenkinsHttpServiceFQDN, | 										jenkinsHTTPServiceFQDN, | ||||||
| 										jenkins.Spec.Service.Port, | 										jenkins.Spec.Service.Port, | ||||||
| 									), | 									), | ||||||
| 								}, | 								}, | ||||||
|  |  | ||||||
|  | @ -227,12 +227,13 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	config := configuration.Configuration{ | 	config := configuration.Configuration{ | ||||||
| 		Client:        r.client, | 		Client:        				  r.client, | ||||||
| 		ClientSet:     r.clientSet, | 		ClientSet:     				  r.clientSet, | ||||||
| 		Notifications: r.notificationEvents, | 		Notifications: 				  r.notificationEvents, | ||||||
| 		Jenkins:       jenkins, | 		Jenkins:       				  jenkins, | ||||||
| 		Scheme:        r.scheme, | 		Scheme:        				  r.scheme, | ||||||
| 		Config:        &r.config, | 		Config:        				  &r.config, | ||||||
|  | 		JenkinsAPIConnectionSettings: r.jenkinsAPIConnectionSettings, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Reconcile base configuration
 | 	// Reconcile base configuration
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue