diff --git a/go.mod b/go.mod index c2d16cd0..22aa3627 100644 --- a/go.mod +++ b/go.mod @@ -19,11 +19,11 @@ require ( github.com/stretchr/testify v1.3.0 go.uber.org/zap v1.9.1 golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 // indirect - golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac // indirect + golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/net v0.0.0-20190909003024-a7b16738d86b // indirect golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b // indirect golang.org/x/text v0.3.2 // indirect - golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e // indirect + golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3 // indirect k8s.io/api v0.0.0-20190612125737-db0771252981 k8s.io/apimachinery v0.0.0-20190612125636-6a5db36e93ad k8s.io/client-go v11.0.0+incompatible diff --git a/go.sum b/go.sum index bc3d8a58..2d411a76 100644 --- a/go.sum +++ b/go.sum @@ -439,6 +439,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f h1:hX65Cu3JDlGH3uEdK7I99Ii+ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -529,6 +531,8 @@ golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578 h1:f0Gfd654rnnfXT1+BK1YHPT golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e h1:1xWUkZQQ9Z9UuZgNaIR6OQOE7rUFglXUUBZlO+dGg6I= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3 h1:2AmBLzhAfXj+2HCW09VCkJtHIYgHTIPcTeYqgP7Bwt0= +golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= diff --git a/pkg/controller/jenkins/client/script.go b/pkg/controller/jenkins/client/script.go index 61077133..ad3d1264 100644 --- a/pkg/controller/jenkins/client/script.go +++ b/pkg/controller/jenkins/client/script.go @@ -11,7 +11,12 @@ import ( ) // GroovyScriptExecutionFailed is custom error type which indicates passed groovy script is invalid -type GroovyScriptExecutionFailed struct{} +type GroovyScriptExecutionFailed struct { + ConfigurationType string + Source string + Name string + Logs string +} func (e GroovyScriptExecutionFailed) Error() string { return "script execution failed" diff --git a/pkg/controller/jenkins/configuration/base/reconcile.go b/pkg/controller/jenkins/configuration/base/reconcile.go index 4a7cd7bf..9d1e6a7f 100644 --- a/pkg/controller/jenkins/configuration/base/reconcile.go +++ b/pkg/controller/jenkins/configuration/base/reconcile.go @@ -14,6 +14,7 @@ import ( "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/backuprestore" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/groovy" + "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/notifications" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins" "github.com/jenkinsci/kubernetes-operator/pkg/log" "github.com/jenkinsci/kubernetes-operator/version" @@ -39,27 +40,30 @@ const ( // ReconcileJenkinsBaseConfiguration defines values required for Jenkins base configuration type ReconcileJenkinsBaseConfiguration struct { - k8sClient client.Client - scheme *runtime.Scheme - logger logr.Logger - jenkins *v1alpha2.Jenkins - local, minikube bool - clientSet *kubernetes.Clientset - config *rest.Config + k8sClient client.Client + scheme *runtime.Scheme + logger logr.Logger + jenkins *v1alpha2.Jenkins + local, minikube bool + clientSet *kubernetes.Clientset + config *rest.Config + notificationEvents *chan notifications.Event } // New create structure which takes care of base configuration func New(client client.Client, scheme *runtime.Scheme, logger logr.Logger, - jenkins *v1alpha2.Jenkins, local, minikube bool, clientSet *kubernetes.Clientset, config *rest.Config) *ReconcileJenkinsBaseConfiguration { + jenkins *v1alpha2.Jenkins, local, minikube bool, clientSet *kubernetes.Clientset, config *rest.Config, + notificationEvents *chan notifications.Event) *ReconcileJenkinsBaseConfiguration { return &ReconcileJenkinsBaseConfiguration{ - k8sClient: client, - scheme: scheme, - logger: logger, - jenkins: jenkins, - local: local, - minikube: minikube, - clientSet: clientSet, - config: config, + k8sClient: client, + scheme: scheme, + logger: logger, + jenkins: jenkins, + local: local, + minikube: minikube, + clientSet: clientSet, + config: config, + notificationEvents: notificationEvents, } } @@ -435,6 +439,12 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O resources.JenkinsMasterContainerName, []string{"bash", "-c", fmt.Sprintf("%s/%s && && /sbin/tini -s -- /usr/local/bin/jenkins.sh", resources.JenkinsScriptsVolumePath, resources.InitScriptName)})) } + *r.notificationEvents <- notifications.Event{ + Jenkins: *r.jenkins, + Phase: notifications.PhaseBase, + LogLevel: v1alpha2.NotificationLogLevelInfo, + Message: "Creating a new Jenkins Master Pod", + } r.logger.Info(fmt.Sprintf("Creating a new Jenkins Master Pod %s/%s", jenkinsMasterPod.Namespace, jenkinsMasterPod.Name)) err = r.createResource(jenkinsMasterPod) if err != nil { diff --git a/pkg/controller/jenkins/configuration/base/reconcile_test.go b/pkg/controller/jenkins/configuration/base/reconcile_test.go index 01e911f6..ea3c0afd 100644 --- a/pkg/controller/jenkins/configuration/base/reconcile_test.go +++ b/pkg/controller/jenkins/configuration/base/reconcile_test.go @@ -233,7 +233,7 @@ func TestCompareVolumes(t *testing.T) { Volumes: resources.GetJenkinsMasterPodBaseVolumes(jenkins), }, } - reconciler := New(nil, nil, nil, jenkins, false, false, nil, nil) + reconciler := New(nil, nil, nil, jenkins, false, false, nil, nil, nil) got := reconciler.compareVolumes(pod) @@ -257,7 +257,7 @@ func TestCompareVolumes(t *testing.T) { Volumes: resources.GetJenkinsMasterPodBaseVolumes(jenkins), }, } - reconciler := New(nil, nil, nil, jenkins, false, false, nil, nil) + reconciler := New(nil, nil, nil, jenkins, false, false, nil, nil, nil) got := reconciler.compareVolumes(pod) @@ -281,7 +281,7 @@ func TestCompareVolumes(t *testing.T) { Volumes: append(resources.GetJenkinsMasterPodBaseVolumes(jenkins), corev1.Volume{Name: "added"}), }, } - reconciler := New(nil, nil, nil, jenkins, false, false, nil, nil) + reconciler := New(nil, nil, nil, jenkins, false, false, nil, nil, nil) got := reconciler.compareVolumes(pod) diff --git a/pkg/controller/jenkins/configuration/base/validate_test.go b/pkg/controller/jenkins/configuration/base/validate_test.go index ea03a478..41980de4 100644 --- a/pkg/controller/jenkins/configuration/base/validate_test.go +++ b/pkg/controller/jenkins/configuration/base/validate_test.go @@ -22,7 +22,7 @@ import ( func TestValidatePlugins(t *testing.T) { log.SetupLogger(true) baseReconcileLoop := New(nil, nil, log.Log, - nil, false, false, nil, nil) + nil, false, false, nil, nil, nil) t.Run("empty", func(t *testing.T) { var requiredBasePlugins []plugins.Plugin var basePlugins []v1alpha2.Plugin @@ -163,7 +163,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateImagePullSecrets() assert.Nil(t, got) @@ -184,7 +184,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got, _ := baseReconcileLoop.validateImagePullSecrets() @@ -218,7 +218,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got, _ := baseReconcileLoop.validateImagePullSecrets() @@ -252,7 +252,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got, _ := baseReconcileLoop.validateImagePullSecrets() @@ -286,7 +286,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got, _ := baseReconcileLoop.validateImagePullSecrets() @@ -320,7 +320,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got, _ := baseReconcileLoop.validateImagePullSecrets() @@ -352,7 +352,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateJenkinsMasterPodEnvs() assert.Nil(t, got) }) @@ -378,7 +378,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateJenkinsMasterPodEnvs() assert.Equal(t, got, []string{"Jenkins Master container env 'JENKINS_HOME' cannot be overridden"}) @@ -401,7 +401,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateJenkinsMasterPodEnvs() assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djava.awt.headless=true'"}) @@ -424,7 +424,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateJenkinsMasterPodEnvs() assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djenkins.install.runSetupWizard=false'"}) @@ -445,7 +445,7 @@ func TestValidateReservedVolumes(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateReservedVolumes() assert.Nil(t, got) }) @@ -462,7 +462,7 @@ func TestValidateReservedVolumes(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateReservedVolumes() assert.Equal(t, got, []string{"Jenkins Master pod volume 'jenkins-home' is reserved please choose different one"}) @@ -477,7 +477,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateContainerVolumeMounts(v1alpha2.Container{}) assert.Nil(t, got) }) @@ -504,7 +504,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) assert.Nil(t, got) }) @@ -531,7 +531,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) assert.Equal(t, got, []string{"mountPath not set for 'example' volume mount in container ''"}) }) @@ -553,7 +553,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { }, } baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), - &jenkins, false, false, nil, nil) + &jenkins, false, false, nil, nil, nil) got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) assert.Equal(t, got, []string{"Not found volume for 'missing-volume' volume mount in container ''"}) @@ -574,7 +574,7 @@ func TestValidateConfigMapVolume(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - nil, false, false, nil, nil) + nil, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateConfigMapVolume(volume) @@ -600,7 +600,7 @@ func TestValidateConfigMapVolume(t *testing.T) { err := fakeClient.Create(context.TODO(), &configMap) assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateConfigMapVolume(volume) @@ -624,7 +624,7 @@ func TestValidateConfigMapVolume(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateConfigMapVolume(volume) @@ -648,7 +648,7 @@ func TestValidateSecretVolume(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - nil, false, false, nil, nil) + nil, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateSecretVolume(volume) @@ -672,7 +672,7 @@ func TestValidateSecretVolume(t *testing.T) { err := fakeClient.Create(context.TODO(), &secret) assert.NoError(t, err) baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateSecretVolume(volume) @@ -694,7 +694,7 @@ func TestValidateSecretVolume(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateSecretVolume(volume) @@ -717,7 +717,7 @@ func TestValidateCustomization(t *testing.T) { customization := v1alpha2.Customization{} fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) got, err := baseReconcileLoop.validateCustomization(customization, "spec.groovyScripts") @@ -737,7 +737,7 @@ func TestValidateCustomization(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) err := fakeClient.Create(context.TODO(), secret) require.NoError(t, err) @@ -766,7 +766,7 @@ func TestValidateCustomization(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) err := fakeClient.Create(context.TODO(), secret) require.NoError(t, err) err = fakeClient.Create(context.TODO(), configMap) @@ -791,7 +791,7 @@ func TestValidateCustomization(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) err := fakeClient.Create(context.TODO(), configMap) require.NoError(t, err) @@ -814,7 +814,7 @@ func TestValidateCustomization(t *testing.T) { } fakeClient := fake.NewFakeClient() baseReconcileLoop := New(fakeClient, nil, logf.ZapLogger(false), - jenkins, false, false, nil, nil) + jenkins, false, false, nil, nil, nil) err := fakeClient.Create(context.TODO(), secret) require.NoError(t, err) diff --git a/pkg/controller/jenkins/groovy/groovy.go b/pkg/controller/jenkins/groovy/groovy.go index 399ec216..dd092b04 100644 --- a/pkg/controller/jenkins/groovy/groovy.go +++ b/pkg/controller/jenkins/groovy/groovy.go @@ -49,7 +49,11 @@ func (g *Groovy) EnsureSingle(source, name, hash, groovyScript string) (requeue logs, err := g.jenkinsClient.ExecuteScript(groovyScript) if err != nil { - if _, ok := err.(*jenkinsclient.GroovyScriptExecutionFailed); ok { + if groovyErr, ok := err.(*jenkinsclient.GroovyScriptExecutionFailed); ok { + groovyErr.ConfigurationType = g.configurationType + groovyErr.Name = name + groovyErr.Source = source + groovyErr.Logs = logs g.logger.V(log.VWarn).Info(fmt.Sprintf("%s Source '%s' Name '%s' groovy script execution failed, logs :\n%s", g.configurationType, source, name, logs)) } return true, err diff --git a/pkg/controller/jenkins/jenkins_controller.go b/pkg/controller/jenkins/jenkins_controller.go index 0c085fdd..ee234c22 100644 --- a/pkg/controller/jenkins/jenkins_controller.go +++ b/pkg/controller/jenkins/jenkins_controller.go @@ -3,7 +3,6 @@ package jenkins import ( "context" "fmt" - "reflect" "github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" @@ -169,7 +168,14 @@ func (r *ReconcileJenkins) Reconcile(request reconcile.Request) (reconcile.Resul } } - if _, ok := err.(*jenkinsclient.GroovyScriptExecutionFailed); ok { + if groovyErr, ok := err.(*jenkinsclient.GroovyScriptExecutionFailed); ok { + *r.notificationEvents <- notifications.Event{ + Jenkins: *jenkins, + Phase: notifications.PhaseBase, + LogLevel: v1alpha2.NotificationLogLevelWarning, + Message: fmt.Sprintf("%s Source '%s' Name '%s' groovy script execution failed, logs:", groovyErr.ConfigurationType, groovyErr.Source, groovyErr.Name), + MessagesVerbose: []string{groovyErr.Logs}, + } return reconcile.Result{Requeue: false}, nil } return reconcile.Result{Requeue: true}, nil @@ -193,14 +199,14 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg } err = r.setDefaults(jenkins, logger) if err != nil { - return reconcile.Result{}, nil, err + return reconcile.Result{}, jenkins, err } // Reconcile base configuration - baseConfiguration := base.New(r.client, r.scheme, logger, jenkins, r.local, r.minikube, &r.clientSet, &r.config) + baseConfiguration := base.New(r.client, r.scheme, logger, jenkins, r.local, r.minikube, &r.clientSet, &r.config, r.notificationEvents) messages, err := baseConfiguration.Validate(jenkins) if err != nil { - return reconcile.Result{}, nil, err + return reconcile.Result{}, jenkins, err } if len(messages) > 0 { message := "Validation of base configuration failed, please correct Jenkins CR." @@ -215,18 +221,18 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg for _, msg := range messages { logger.V(log.VWarn).Info(msg) } - return reconcile.Result{}, nil, nil // don't requeue + return reconcile.Result{}, jenkins, nil // don't requeue } result, jenkinsClient, err := baseConfiguration.Reconcile() if err != nil { - return reconcile.Result{}, nil, err + return reconcile.Result{}, jenkins, err } if result.Requeue { - return result, nil, nil + return result, jenkins, nil } if jenkinsClient == nil { - return reconcile.Result{Requeue: false}, nil, nil + return reconcile.Result{Requeue: false}, jenkins, nil } if jenkins.Status.BaseConfigurationCompletedTime == nil { @@ -234,7 +240,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg jenkins.Status.BaseConfigurationCompletedTime = &now err = r.client.Update(context.TODO(), jenkins) if err != nil { - return reconcile.Result{}, nil, errors.WithStack(err) + return reconcile.Result{}, jenkins, errors.WithStack(err) } message := fmt.Sprintf("Base configuration phase is complete, took %s", @@ -253,7 +259,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg messages, err = userConfiguration.Validate(jenkins) if err != nil { - return reconcile.Result{}, nil, err + return reconcile.Result{}, jenkins, err } if len(messages) > 0 { message := fmt.Sprintf("Validation of user configuration failed, please correct Jenkins CR") @@ -269,15 +275,15 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg for _, msg := range messages { logger.V(log.VWarn).Info(msg) } - return reconcile.Result{}, nil, nil // don't requeue + return reconcile.Result{}, jenkins, nil // don't requeue } result, err = userConfiguration.Reconcile() if err != nil { - return reconcile.Result{}, nil, err + return reconcile.Result{}, jenkins, err } if result.Requeue { - return result, nil, nil + return result, jenkins, nil } if jenkins.Status.UserConfigurationCompletedTime == nil { @@ -285,7 +291,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg jenkins.Status.UserConfigurationCompletedTime = &now err = r.client.Update(context.TODO(), jenkins) if err != nil { - return reconcile.Result{}, nil, errors.WithStack(err) + return reconcile.Result{}, jenkins, errors.WithStack(err) } message := fmt.Sprintf("User configuration phase is complete, took %s", jenkins.Status.UserConfigurationCompletedTime.Sub(jenkins.Status.ProvisionStartTime.Time)) diff --git a/pkg/controller/jenkins/notifications/mailgun.go b/pkg/controller/jenkins/notifications/mailgun.go index 45a166a2..3658abd9 100644 --- a/pkg/controller/jenkins/notifications/mailgun.go +++ b/pkg/controller/jenkins/notifications/mailgun.go @@ -65,7 +65,7 @@ func (m MailGun) Send(event Event, config v1alpha2.Notification) error { secretValue := string(secret.Data[selector.Key]) if secretValue == "" { - return errors.Errorf("Mailgun API is empty in secret '%s/%s[%s]", event.Jenkins.Namespace, selector.Name, selector.Key) + return errors.Errorf("Mailgun API secret is empty in secret '%s/%s[%s]", event.Jenkins.Namespace, selector.Name, selector.Key) } mg := mailgun.NewMailgun(config.Mailgun.Domain, secretValue) diff --git a/pkg/controller/jenkins/notifications/msteams.go b/pkg/controller/jenkins/notifications/msteams.go index c883fbfb..ff6811b7 100644 --- a/pkg/controller/jenkins/notifications/msteams.go +++ b/pkg/controller/jenkins/notifications/msteams.go @@ -66,7 +66,7 @@ func (t Teams) Send(event Event, config v1alpha2.Notification) error { secretValue := string(secret.Data[selector.Key]) if secretValue == "" { - return errors.Errorf("Microsoft Teams webhook URL is empty in secret '%s/%s[%s]", event.Jenkins.Namespace, selector.Name, selector.Key) + return errors.Errorf("Microsoft Teams WebHook URL is empty in secret '%s/%s[%s]", event.Jenkins.Namespace, selector.Name, selector.Key) } tm := &TeamsMessage{ diff --git a/pkg/controller/jenkins/notifications/sender.go b/pkg/controller/jenkins/notifications/sender.go index 441d9030..fad1219f 100644 --- a/pkg/controller/jenkins/notifications/sender.go +++ b/pkg/controller/jenkins/notifications/sender.go @@ -7,6 +7,7 @@ import ( "github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" "github.com/jenkinsci/kubernetes-operator/pkg/event" "github.com/jenkinsci/kubernetes-operator/pkg/log" + "github.com/pkg/errors" k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -68,9 +69,9 @@ type service interface { // Listen listens for incoming events and send it as notifications func Listen(events chan Event, k8sEvent event.Recorder, k8sClient k8sclient.Client) { - for event := range events { - logger := log.Log.WithValues("cr", event.Jenkins.Name) - for _, notificationConfig := range event.Jenkins.Spec.Notifications { + for evt := range events { + logger := log.Log.WithValues("cr", evt.Jenkins.Name) + for _, notificationConfig := range evt.Jenkins.Spec.Notifications { var err error var svc service @@ -86,18 +87,18 @@ func Listen(events chan Event, k8sEvent event.Recorder, k8sClient k8sclient.Clie } go func(notificationConfig v1alpha2.Notification) { - err = notify(svc, event, notificationConfig) + err = notify(svc, evt, notificationConfig) if err != nil { if log.Debug { - logger.Error(nil, fmt.Sprintf("%+v", errors.WithMessage(err, "failed to send notification"))) + logger.Error(nil, fmt.Sprintf("%+v", errors.WithMessage(err, fmt.Sprintf("failed to send notification '%s'", notificationConfig.Name)))) } else { - logger.Error(nil, fmt.Sprintf("%s", errors.WithMessage(err, "failed to send notification"))) + logger.Error(nil, fmt.Sprintf("%s", errors.WithMessage(err, fmt.Sprintf("failed to send notification '%s'", notificationConfig.Name)))) } } }(notificationConfig) } - k8sEvent.Emit(&event.Jenkins, logLevelEventType(event.LogLevel), "NotificationSent", event.Message) + k8sEvent.Emit(&evt.Jenkins, logLevelEventType(evt.LogLevel), "NotificationSent", evt.Message) } } diff --git a/pkg/controller/jenkins/notifications/slack.go b/pkg/controller/jenkins/notifications/slack.go index 5ee08a98..062a61e6 100644 --- a/pkg/controller/jenkins/notifications/slack.go +++ b/pkg/controller/jenkins/notifications/slack.go @@ -71,18 +71,18 @@ func (s Slack) Send(event Event, config v1alpha2.Notification) error { Color: s.getStatusColor(event.LogLevel), Fields: []SlackField{ { - Title: messageFieldName, + Title: "", Value: event.Message, Short: false, }, { - Title: crNameFieldName, - Value: event.Jenkins.Name, + Title: namespaceFieldName, + Value: event.Jenkins.Namespace, Short: true, }, { - Title: namespaceFieldName, - Value: event.Jenkins.Namespace, + Title: crNameFieldName, + Value: event.Jenkins.Name, Short: true, }, }, @@ -119,7 +119,7 @@ func (s Slack) Send(event Event, config v1alpha2.Notification) error { secretValue := string(secret.Data[selector.Key]) if secretValue == "" { - return errors.Errorf("Secret with given name `%s` and selector name `%s` is empty", secret.Name, selector.Name) + return errors.Errorf("Slack WebHook URL is empty in secret '%s/%s[%s]", event.Jenkins.Namespace, selector.Name, selector.Key) } request, err := http.NewRequest("POST", secretValue, bytes.NewBuffer(slackMessage)) diff --git a/pkg/controller/jenkins/notifications/slack_test.go b/pkg/controller/jenkins/notifications/slack_test.go index 261a6172..b32283a6 100644 --- a/pkg/controller/jenkins/notifications/slack_test.go +++ b/pkg/controller/jenkins/notifications/slack_test.go @@ -52,14 +52,14 @@ func TestSlack_Send(t *testing.T) { assert.Equal(t, field.Value, string(event.Phase)) case crNameFieldName: assert.Equal(t, field.Value, event.Jenkins.Name) - case messageFieldName: + case "": assert.Equal(t, field.Value, event.Message) case loggingLevelFieldName: assert.Equal(t, field.Value, string(event.LogLevel)) case namespaceFieldName: assert.Equal(t, field.Value, event.Jenkins.Namespace) default: - t.Fail() + t.Errorf("Unexpected field %+v", field) } } diff --git a/pkg/controller/jenkins/plugins/base_plugins.go b/pkg/controller/jenkins/plugins/base_plugins.go index d203dd38..96b40916 100644 --- a/pkg/controller/jenkins/plugins/base_plugins.go +++ b/pkg/controller/jenkins/plugins/base_plugins.go @@ -3,12 +3,12 @@ package plugins const ( configurationAsCodePlugin = "configuration-as-code:1.29" configurationAsCodeSupportPlugin = "configuration-as-code-support:1.19" - gitPlugin = "git:3.12.0" + gitPlugin = "git:3.12.1" jobDslPlugin = "job-dsl:1.76" kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:0.12.1" - kubernetesPlugin = "kubernetes:1.18.3" + kubernetesPlugin = "kubernetes:1.19.3" workflowAggregatorPlugin = "workflow-aggregator:2.6" - workflowJobPlugin = "workflow-job:2.34" + workflowJobPlugin = "workflow-job:2.35" ) // basePluginsList contains plugins to install by operator