Added jenkins theme and updated user reconciliation loop
This commit is contained in:
		
							parent
							
								
									874ff8e0e5
								
							
						
					
					
						commit
						0461e7983b
					
				|  | @ -6,6 +6,8 @@ import ( | ||||||
| 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" | 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" | ||||||
| 	jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client" | 	jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user/seedjobs" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user/seedjobs" | ||||||
|  | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user/theme" | ||||||
|  | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/groovy" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/jobs" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/jobs" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
|  | @ -39,7 +41,18 @@ func (r *ReconcileUserConfiguration) Reconcile() (*reconcile.Result, error) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return result, err | 		return result, err | ||||||
| 	} | 	} | ||||||
|  | 	if result != nil { | ||||||
| 		return result, nil | 		return result, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// reconcile custom groovy scripts
 | ||||||
|  | 	result, err = r.reconcileCustomGroovy() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return result, err | ||||||
|  | 	} | ||||||
|  | 	if result != nil { | ||||||
|  | 		return result, nil | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  | @ -53,7 +66,7 @@ func (r *ReconcileUserConfiguration) reconcileSeedJobs() (*reconcile.Result, err | ||||||
| 			return &reconcile.Result{Requeue: true, RequeueAfter: time.Second * 10}, nil | 			return &reconcile.Result{Requeue: true, RequeueAfter: time.Second * 10}, nil | ||||||
| 		} | 		} | ||||||
| 		// build failed and cannot be recovered
 | 		// build failed and cannot be recovered
 | ||||||
| 		if err == jobs.ErrorUncoverBuildFailed { | 		if err == jobs.ErrorUnrecoverableBuildFailed { | ||||||
| 			return nil, nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 		// unexpected error - requeue reconciliation loop
 | 		// unexpected error - requeue reconciliation loop
 | ||||||
|  | @ -65,3 +78,25 @@ func (r *ReconcileUserConfiguration) reconcileSeedJobs() (*reconcile.Result, err | ||||||
| 	} | 	} | ||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (r *ReconcileUserConfiguration) reconcileCustomGroovy() (*reconcile.Result, error) { | ||||||
|  | 	groovyClient := groovy.New(r.jenkinsClient, r.k8sClient, r.logger) | ||||||
|  | 
 | ||||||
|  | 	err := groovyClient.ConfigureGroovyJob() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &reconcile.Result{}, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set custom jenkins theme
 | ||||||
|  | 	done, err := groovyClient.EnsureGroovyJob(theme.SetThemeGroovyScript, r.jenkins) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &reconcile.Result{}, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// build not finished yet - requeue reconciliation loop with timeout
 | ||||||
|  | 	if !done { | ||||||
|  | 		return &reconcile.Result{Requeue: true, RequeueAfter: time.Second * 10}, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -1,114 +0,0 @@ | ||||||
| package user |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"os" |  | ||||||
| 	"testing" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" |  | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client" |  | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/jobs" |  | ||||||
| 
 |  | ||||||
| 	"github.com/bndr/gojenkins" |  | ||||||
| 	"github.com/golang/mock/gomock" |  | ||||||
| 	"github.com/stretchr/testify/assert" |  | ||||||
| 	corev1 "k8s.io/api/core/v1" |  | ||||||
| 	"k8s.io/apimachinery/pkg/api/resource" |  | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |  | ||||||
| 	"k8s.io/client-go/kubernetes/scheme" |  | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/client/fake" |  | ||||||
| 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func TestMain(m *testing.M) { |  | ||||||
| 	virtuslabv1alpha1.SchemeBuilder.AddToScheme(scheme.Scheme) |  | ||||||
| 	os.Exit(m.Run()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestReconcileUserConfiguration(t *testing.T) { |  | ||||||
| 	// given
 |  | ||||||
| 	logger := logf.ZapLogger(false) |  | ||||||
| 	ctrl := gomock.NewController(t) |  | ||||||
| 	ctx := context.TODO() |  | ||||||
| 	defer ctrl.Finish() |  | ||||||
| 
 |  | ||||||
| 	jenkinsClient := client.NewMockJenkins(ctrl) |  | ||||||
| 	fakeClient := fake.NewFakeClient() |  | ||||||
| 
 |  | ||||||
| 	jenkins := jenkinsCustomResource() |  | ||||||
| 	err := fakeClient.Create(ctx, jenkins) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 
 |  | ||||||
| 	reconcile := New(fakeClient, jenkinsClient, logger, jenkins) |  | ||||||
| 
 |  | ||||||
| 	// first run - should ensure seed jobs(configure seed jobs, run build) and requeue reconciliation loop
 |  | ||||||
| 	jenkinsClient. |  | ||||||
| 		EXPECT(). |  | ||||||
| 		CreateOrUpdateJob(gomock.Any(), gomock.Any()). |  | ||||||
| 		Return(nil, nil) |  | ||||||
| 
 |  | ||||||
| 	jenkinsClient. |  | ||||||
| 		EXPECT(). |  | ||||||
| 		BuildJob(gomock.Any(), gomock.Any()). |  | ||||||
| 		Return(int64(1), nil) |  | ||||||
| 
 |  | ||||||
| 	result, err := reconcile.Reconcile() |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.NotNil(t, result) |  | ||||||
| 	assert.True(t, result.Requeue) |  | ||||||
| 	assert.Equal(t, result.RequeueAfter, time.Second*10) |  | ||||||
| 
 |  | ||||||
| 	// second run - should ensure seed jobs(configure/update seed jobs, finish build) and requeue reconciliation loop
 |  | ||||||
| 	jenkinsClient. |  | ||||||
| 		EXPECT(). |  | ||||||
| 		GetBuild(gomock.Any(), gomock.Any()). |  | ||||||
| 		Return(&gojenkins.Build{ |  | ||||||
| 			Raw: &gojenkins.BuildResponse{ |  | ||||||
| 				Result: jobs.SuccessStatus, |  | ||||||
| 			}, |  | ||||||
| 		}, nil) |  | ||||||
| 
 |  | ||||||
| 	jenkinsClient. |  | ||||||
| 		EXPECT(). |  | ||||||
| 		CreateOrUpdateJob(gomock.Any(), gomock.Any()). |  | ||||||
| 		Return(nil, nil) |  | ||||||
| 
 |  | ||||||
| 	result, err = reconcile.Reconcile() |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.Nil(t, result) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func jenkinsCustomResource() *virtuslabv1alpha1.Jenkins { |  | ||||||
| 	return &virtuslabv1alpha1.Jenkins{ |  | ||||||
| 		ObjectMeta: metav1.ObjectMeta{ |  | ||||||
| 			Name:      "jenkins", |  | ||||||
| 			Namespace: "default", |  | ||||||
| 		}, |  | ||||||
| 		Spec: virtuslabv1alpha1.JenkinsSpec{ |  | ||||||
| 			Master: virtuslabv1alpha1.JenkinsMaster{ |  | ||||||
| 				Image:       "jenkins/jenkins", |  | ||||||
| 				Annotations: map[string]string{"test": "label"}, |  | ||||||
| 				Resources: corev1.ResourceRequirements{ |  | ||||||
| 					Requests: corev1.ResourceList{ |  | ||||||
| 						corev1.ResourceCPU:    resource.MustParse("300m"), |  | ||||||
| 						corev1.ResourceMemory: resource.MustParse("500Mi"), |  | ||||||
| 					}, |  | ||||||
| 					Limits: corev1.ResourceList{ |  | ||||||
| 						corev1.ResourceCPU:    resource.MustParse("2"), |  | ||||||
| 						corev1.ResourceMemory: resource.MustParse("2Gi"), |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 			SeedJobs: []virtuslabv1alpha1.SeedJob{ |  | ||||||
| 				{ |  | ||||||
| 					ID:               "jenkins-operator-e2e", |  | ||||||
| 					Targets:          "cicd/jobs/*.jenkins", |  | ||||||
| 					Description:      "Jenkins Operator e2e tests repository", |  | ||||||
| 					RepositoryBranch: "master", |  | ||||||
| 					RepositoryURL:    "https://github.com/VirtusLab/jenkins-operator-e2e.git", |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -2,6 +2,7 @@ package seedjobs | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | @ -40,25 +41,35 @@ func TestEnsureSeedJobs(t *testing.T) { | ||||||
| 	err := fakeClient.Create(ctx, jenkins) | 	err := fakeClient.Create(ctx, jenkins) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
|  | 	for reconcileAttempt := 1; reconcileAttempt <= 2; reconcileAttempt++ { | ||||||
|  | 		logger.Info(fmt.Sprintf("Reconcile attempt #%d", reconcileAttempt)) | ||||||
|  | 
 | ||||||
| 		seedJobs := New(jenkinsClient, fakeClient, logger) | 		seedJobs := New(jenkinsClient, fakeClient, logger) | ||||||
| 
 | 
 | ||||||
| 		// first run - should create job and schedule build
 | 		// first run - should create job and schedule build
 | ||||||
|  | 		if reconcileAttempt == 1 { | ||||||
| 			jenkinsClient. | 			jenkinsClient. | ||||||
| 				EXPECT(). | 				EXPECT(). | ||||||
| 				CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName). | 				CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName). | ||||||
| 				Return(nil, nil) | 				Return(nil, nil) | ||||||
| 
 | 
 | ||||||
|  | 			jenkinsClient. | ||||||
|  | 				EXPECT(). | ||||||
|  | 				GetJob(ConfigureSeedJobsName). | ||||||
|  | 				Return(&gojenkins.Job{ | ||||||
|  | 					Raw: &gojenkins.JobResponse{ | ||||||
|  | 						NextBuildNumber: int64(1), | ||||||
|  | 					}, | ||||||
|  | 				}, nil) | ||||||
|  | 
 | ||||||
| 			jenkinsClient. | 			jenkinsClient. | ||||||
| 				EXPECT(). | 				EXPECT(). | ||||||
| 				BuildJob(ConfigureSeedJobsName, gomock.Any()). | 				BuildJob(ConfigureSeedJobsName, gomock.Any()). | ||||||
| 		Return(int64(1), nil) | 				Return(int64(0), nil) | ||||||
| 
 | 		} | ||||||
| 	done, err := seedJobs.EnsureSeedJobs(jenkins) |  | ||||||
| 
 |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.False(t, done) |  | ||||||
| 
 | 
 | ||||||
| 		// second run - should update and finish job
 | 		// second run - should update and finish job
 | ||||||
|  | 		if reconcileAttempt == 2 { | ||||||
| 			jenkinsClient. | 			jenkinsClient. | ||||||
| 				EXPECT(). | 				EXPECT(). | ||||||
| 				CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName). | 				CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName). | ||||||
|  | @ -72,14 +83,24 @@ func TestEnsureSeedJobs(t *testing.T) { | ||||||
| 						Result: jobs.SuccessStatus, | 						Result: jobs.SuccessStatus, | ||||||
| 					}, | 					}, | ||||||
| 				}, nil) | 				}, nil) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		done, err := seedJobs.EnsureSeedJobs(jenkins) | ||||||
|  | 		assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 		err = fakeClient.Get(ctx, types.NamespacedName{Name: jenkins.Name, Namespace: jenkins.Namespace}, jenkins) | 		err = fakeClient.Get(ctx, types.NamespacedName{Name: jenkins.Name, Namespace: jenkins.Namespace}, jenkins) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 	done, err = seedJobs.EnsureSeedJobs(jenkins) | 		// first run - should create job and schedule build
 | ||||||
|  | 		if reconcileAttempt == 1 { | ||||||
|  | 			assert.False(t, done) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, err) | 		// second run - should update and finish job
 | ||||||
|  | 		if reconcileAttempt == 2 { | ||||||
| 			assert.True(t, done) | 			assert.True(t, done) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func jenkinsCustomResource() *virtuslabv1alpha1.Jenkins { | func jenkinsCustomResource() *virtuslabv1alpha1.Jenkins { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | package theme | ||||||
|  | 
 | ||||||
|  | // SetThemeGroovyScript it's a groovy script which set custom jenkins theme
 | ||||||
|  | var SetThemeGroovyScript = ` | ||||||
|  | import jenkins.* | ||||||
|  | import jenkins.model.* | ||||||
|  | import hudson.* | ||||||
|  | import hudson.model.* | ||||||
|  | import org.jenkinsci.plugins.simpletheme.ThemeElement | ||||||
|  | import org.jenkinsci.plugins.simpletheme.CssTextThemeElement | ||||||
|  | import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement | ||||||
|  | 
 | ||||||
|  | Jenkins jenkins = Jenkins.getInstance() | ||||||
|  | 
 | ||||||
|  | def decorator = Jenkins.instance.getDescriptorByType(org.codefirst.SimpleThemeDecorator.class) | ||||||
|  | 
 | ||||||
|  | List<ThemeElement> configElements = new ArrayList<>(); | ||||||
|  | configElements.add(new CssTextThemeElement("DEFAULT")); | ||||||
|  | configElements.add(new CssUrlThemeElement("https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-blue-grey.css")); | ||||||
|  | decorator.setElements(configElements); | ||||||
|  | decorator.save(); | ||||||
|  | 
 | ||||||
|  | jenkins.save() | ||||||
|  | ` | ||||||
|  | @ -112,4 +112,5 @@ var BasePluginsMap = map[string][]Plugin{ | ||||||
| 	Must(New("configuration-as-code:1.4")).String(): { | 	Must(New("configuration-as-code:1.4")).String(): { | ||||||
| 		Must(New("configuration-as-code-support:1.4")), | 		Must(New("configuration-as-code-support:1.4")), | ||||||
| 	}, | 	}, | ||||||
|  | 	Must(New("simple-theme-plugin:0.5")).String(): {}, | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue