Merge pull request #188 from jakalkhalili/cr-removal-bug

#176 Add owner reference to seed job agent deployment
This commit is contained in:
Tomasz Sęk 2019-11-06 16:32:51 +01:00 committed by GitHub
commit ab65db22d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 150 additions and 130 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/go-logr/logr"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
@ -27,7 +28,36 @@ type backupTrigger struct {
ticker *time.Ticker
}
var backupTriggers = map[string]backupTrigger{}
type backupTriggers struct {
triggers map[string]backupTrigger
}
func (t *backupTriggers) stop(logger logr.Logger, namespace string, name string) {
key := t.key(namespace, name)
trigger, found := t.triggers[key]
if found {
logger.Info(fmt.Sprintf("Stopping backup trigger for '%s'", key))
trigger.ticker.Stop()
delete(t.triggers, key)
} else {
logger.V(log.VWarn).Info(fmt.Sprintf("Can't stop backup trigger for '%s', not found, skipping", key))
}
}
func (t *backupTriggers) get(namespace, name string) (backupTrigger, bool) {
trigger, found := t.triggers[t.key(namespace, name)]
return trigger, found
}
func (t *backupTriggers) key(namespace, name string) string {
return namespace + "/" + name
}
func (t *backupTriggers) add(namespace string, name string, trigger backupTrigger) {
t.triggers[t.key(namespace, name)] = trigger
}
var triggers = backupTriggers{triggers: make(map[string]backupTrigger)}
// BackupAndRestore represents Jenkins backup and restore client
type BackupAndRestore struct {
@ -169,7 +199,10 @@ func triggerBackup(ticker *time.Ticker, k8sClient k8s.Client, logger logr.Logger
for range ticker.C {
jenkins := &v1alpha2.Jenkins{}
err := k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: name}, jenkins)
if err != nil {
if err != nil && apierrors.IsNotFound(err) {
triggers.stop(logger, namespace, name)
return // abort
} else if err != nil {
logger.V(log.VWarn).Info(fmt.Sprintf("backup trigger, error when fetching CR: %s", err))
}
if jenkins.Status.LastBackup == jenkins.Status.PendingBackup {
@ -184,21 +217,22 @@ func triggerBackup(ticker *time.Ticker, k8sClient k8s.Client, logger logr.Logger
// EnsureBackupTrigger creates or update trigger which update CR to make backup
func (bar *BackupAndRestore) EnsureBackupTrigger() error {
jenkins := bar.jenkins
trigger, found := backupTriggers[jenkins.Name]
if len(jenkins.Spec.Backup.ContainerName) == 0 || jenkins.Spec.Backup.Interval == 0 {
bar.logger.V(log.VDebug).Info("Skipping create backup trigger")
if found {
bar.stopBackupTrigger(trigger)
}
trigger, found := triggers.get(bar.jenkins.Namespace, bar.jenkins.Name)
isBackupConfigured := len(bar.jenkins.Spec.Backup.ContainerName) > 0 && bar.jenkins.Spec.Backup.Interval > 0
if found && !isBackupConfigured {
bar.StopBackupTrigger()
return nil
}
if !found {
// configured backup has no trigger
if !found && isBackupConfigured {
bar.startBackupTrigger()
return nil
}
if found && jenkins.Spec.Backup.Interval != trigger.interval {
bar.stopBackupTrigger(trigger)
if found && isBackupConfigured && bar.jenkins.Spec.Backup.Interval != trigger.interval {
bar.StopBackupTrigger()
bar.startBackupTrigger()
}
@ -207,28 +241,19 @@ func (bar *BackupAndRestore) EnsureBackupTrigger() error {
// StopBackupTrigger stops trigger which update CR to make backup
func (bar *BackupAndRestore) StopBackupTrigger() {
trigger, found := backupTriggers[bar.jenkins.Name]
if found {
bar.stopBackupTrigger(trigger)
}
triggers.stop(bar.logger, bar.jenkins.Namespace, bar.jenkins.Name)
}
func (bar *BackupAndRestore) startBackupTrigger() {
bar.logger.Info("Starting backup trigger")
ticker := time.NewTicker(time.Duration(bar.jenkins.Spec.Backup.Interval) * time.Second)
backupTriggers[bar.jenkins.Name] = backupTrigger{
triggers.add(bar.jenkins.Namespace, bar.jenkins.Name, backupTrigger{
interval: bar.jenkins.Spec.Backup.Interval,
ticker: ticker,
}
})
go triggerBackup(ticker, bar.k8sClient, bar.logger, bar.jenkins.Namespace, bar.jenkins.Name)
}
func (bar *BackupAndRestore) stopBackupTrigger(trigger backupTrigger) {
bar.logger.Info("Stopping backup trigger")
trigger.ticker.Stop()
delete(backupTriggers, bar.jenkins.Name)
}
func (bar *BackupAndRestore) exec(podName, containerName string, command []string) (stdout, stderr bytes.Buffer, err error) {
req := bar.clientSet.CoreV1().RESTClient().Post().
Resource("pods").

View File

@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
@ -42,17 +41,15 @@ const (
// ReconcileJenkinsBaseConfiguration defines values required for Jenkins base configuration
type ReconcileJenkinsBaseConfiguration struct {
configuration.Configuration
scheme *runtime.Scheme
logger logr.Logger
local, minikube bool
config *rest.Config
}
// New create structure which takes care of base configuration
func New(config configuration.Configuration, scheme *runtime.Scheme, logger logr.Logger, local, minikube bool, restConfig *rest.Config) *ReconcileJenkinsBaseConfiguration {
func New(config configuration.Configuration, logger logr.Logger, local, minikube bool, restConfig *rest.Config) *ReconcileJenkinsBaseConfiguration {
return &ReconcileJenkinsBaseConfiguration{
Configuration: config,
scheme: scheme,
logger: logger,
local: local,
minikube: minikube,
@ -255,7 +252,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta
err := r.Configuration.Client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.Configuration.Jenkins), Namespace: r.Configuration.Jenkins.ObjectMeta.Namespace}, found)
if err != nil && apierrors.IsNotFound(err) {
return stackerr.WithStack(r.createResource(resources.NewOperatorCredentialsSecret(meta, r.Configuration.Jenkins)))
return stackerr.WithStack(r.CreateResource(resources.NewOperatorCredentialsSecret(meta, r.Configuration.Jenkins)))
} else if err != nil && !apierrors.IsNotFound(err) {
return stackerr.WithStack(err)
}
@ -265,7 +262,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta
return nil
}
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) createScriptsConfigMap(meta metav1.ObjectMeta) error {
@ -273,7 +270,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createScriptsConfigMap(meta metav1.O
if err != nil {
return err
}
return stackerr.WithStack(r.createOrUpdateResource(configMap))
return stackerr.WithStack(r.CreateOrUpdateResource(configMap))
}
func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(meta metav1.ObjectMeta) error {
@ -281,12 +278,12 @@ func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(met
if err != nil {
return err
}
return stackerr.WithStack(r.createOrUpdateResource(configMap))
return stackerr.WithStack(r.CreateOrUpdateResource(configMap))
}
func (r *ReconcileJenkinsBaseConfiguration) createBaseConfigurationConfigMap(meta metav1.ObjectMeta) error {
configMap := resources.NewBaseConfigurationConfigMap(meta, r.Configuration.Jenkins)
return stackerr.WithStack(r.createOrUpdateResource(configMap))
return stackerr.WithStack(r.CreateOrUpdateResource(configMap))
}
func (r *ReconcileJenkinsBaseConfiguration) addLabelForWatchesResources(customization v1alpha2.Customization) error {
@ -339,19 +336,19 @@ func (r *ReconcileJenkinsBaseConfiguration) addLabelForWatchesResources(customiz
func (r *ReconcileJenkinsBaseConfiguration) createRBAC(meta metav1.ObjectMeta) error {
serviceAccount := resources.NewServiceAccount(meta)
err := r.createResource(serviceAccount)
err := r.CreateResource(serviceAccount)
if err != nil && !errors.IsAlreadyExists(err) {
return stackerr.WithStack(err)
}
role := resources.NewRole(meta)
err = r.createOrUpdateResource(role)
err = r.CreateOrUpdateResource(role)
if err != nil {
return stackerr.WithStack(err)
}
roleBinding := resources.NewRoleBinding(meta)
err = r.createOrUpdateResource(roleBinding)
err = r.CreateOrUpdateResource(roleBinding)
if err != nil {
return stackerr.WithStack(err)
}
@ -373,7 +370,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta
Selector: meta.Labels,
},
}, config)
if err = r.createResource(&service); err != nil {
if err = r.CreateResource(&service); err != nil {
return stackerr.WithStack(err)
}
} else if err != nil {
@ -381,7 +378,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta
}
service = resources.UpdateService(service, config)
return stackerr.WithStack(r.updateResource(&service))
return stackerr.WithStack(r.UpdateResource(&service))
}
func (r *ReconcileJenkinsBaseConfiguration) getJenkinsMasterPod() (*corev1.Pod, error) {
@ -416,7 +413,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O
Reason: reason.NewPodCreation(reason.OperatorSource, []string{"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)
err = r.CreateResource(jenkinsMasterPod)
if err != nil {
return reconcile.Result{}, stackerr.WithStack(err)
}
@ -827,7 +824,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje
credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey] = []byte(token.GetToken())
now, _ := time.Now().UTC().MarshalText()
credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] = now
err = r.updateResource(credentialsSecret)
err = r.UpdateResource(credentialsSecret)
if err != nil {
return nil, stackerr.WithStack(err)
}

View File

@ -234,7 +234,7 @@ func TestCompareVolumes(t *testing.T) {
Volumes: resources.GetJenkinsMasterPodBaseVolumes(jenkins),
},
}
reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, nil, false, false, nil)
reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, false, false, nil)
got := reconciler.compareVolumes(pod)
@ -258,7 +258,7 @@ func TestCompareVolumes(t *testing.T) {
Volumes: resources.GetJenkinsMasterPodBaseVolumes(jenkins),
},
}
reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, nil, false, false, nil)
reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, false, false, nil)
got := reconciler.compareVolumes(pod)
@ -282,7 +282,7 @@ func TestCompareVolumes(t *testing.T) {
Volumes: append(resources.GetJenkinsMasterPodBaseVolumes(jenkins), corev1.Volume{Name: "added"}),
},
}
reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, nil, false, false, nil)
reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, false, false, nil)
got := reconciler.compareVolumes(pod)

View File

@ -1,56 +0,0 @@
package base
import (
"context"
stackerr "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
func (r *ReconcileJenkinsBaseConfiguration) createResource(obj metav1.Object) error {
runtimeObj, ok := obj.(runtime.Object)
if !ok {
return stackerr.Errorf("is not a %T a runtime.Object", obj)
}
// Set Jenkins instance as the owner and controller
if err := controllerutil.SetControllerReference(r.Configuration.Jenkins, obj, r.scheme); err != nil {
return stackerr.WithStack(err)
}
return r.Client.Create(context.TODO(), runtimeObj) // don't wrap error
}
func (r *ReconcileJenkinsBaseConfiguration) updateResource(obj metav1.Object) error {
runtimeObj, ok := obj.(runtime.Object)
if !ok {
return stackerr.Errorf("is not a %T a runtime.Object", obj)
}
// set Jenkins instance as the owner and controller, don't check error(can be already set)
_ = controllerutil.SetControllerReference(r.Configuration.Jenkins, obj, r.scheme)
return r.Client.Update(context.TODO(), runtimeObj) // don't wrap error
}
func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Object) error {
runtimeObj, ok := obj.(runtime.Object)
if !ok {
return stackerr.Errorf("is not a %T a runtime.Object", obj)
}
// set Jenkins instance as the owner and controller, don't check error(can be already set)
_ = controllerutil.SetControllerReference(r.Configuration.Jenkins, obj, r.scheme)
err := r.Client.Create(context.TODO(), runtimeObj)
if err != nil && errors.IsAlreadyExists(err) {
return r.updateResource(obj)
} else if err != nil && !errors.IsAlreadyExists(err) {
return stackerr.WithStack(err)
}
return nil
}

View File

@ -23,7 +23,7 @@ import (
func TestValidatePlugins(t *testing.T) {
log.SetupLogger(true)
baseReconcileLoop := New(configuration.Configuration{}, nil, log.Log, false, false, nil)
baseReconcileLoop := New(configuration.Configuration{}, log.Log, false, false, nil)
t.Run("empty", func(t *testing.T) {
var requiredBasePlugins []plugins.Plugin
var basePlugins []v1alpha2.Plugin
@ -166,7 +166,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateImagePullSecrets()
fmt.Println(got)
@ -190,7 +190,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: &jenkins,
}, nil, nil, false, false, nil)
}, nil, false, false, nil)
got, _ := baseReconcileLoop.validateImagePullSecrets()
@ -226,7 +226,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: &jenkins,
}, nil, nil, false, false, nil)
}, nil, false, false, nil)
got, _ := baseReconcileLoop.validateImagePullSecrets()
@ -262,7 +262,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, _ := baseReconcileLoop.validateImagePullSecrets()
@ -298,7 +298,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, _ := baseReconcileLoop.validateImagePullSecrets()
@ -334,7 +334,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, _ := baseReconcileLoop.validateImagePullSecrets()
@ -367,7 +367,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateJenkinsMasterPodEnvs()
assert.Nil(t, got)
})
@ -394,7 +394,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateJenkinsMasterPodEnvs()
assert.Equal(t, got, []string{"Jenkins Master container env 'JENKINS_HOME' cannot be overridden"})
@ -418,7 +418,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateJenkinsMasterPodEnvs()
assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djava.awt.headless=true'"})
@ -442,7 +442,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateJenkinsMasterPodEnvs()
assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djenkins.install.runSetupWizard=false'"})
@ -464,7 +464,7 @@ func TestValidateReservedVolumes(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateReservedVolumes()
assert.Nil(t, got)
})
@ -482,7 +482,7 @@ func TestValidateReservedVolumes(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateReservedVolumes()
assert.Equal(t, got, []string{"Jenkins Master pod volume 'jenkins-home' is reserved please choose different one"})
@ -498,7 +498,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateContainerVolumeMounts(v1alpha2.Container{})
assert.Nil(t, got)
})
@ -526,7 +526,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0])
assert.Nil(t, got)
})
@ -554,7 +554,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0])
assert.Equal(t, got, []string{"mountPath not set for 'example' volume mount in container ''"})
})
@ -577,7 +577,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}
baseReconcileLoop := New(configuration.Configuration{
Jenkins: &jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0])
assert.Equal(t, got, []string{"Not found volume for 'missing-volume' volume mount in container ''"})
@ -599,7 +599,7 @@ func TestValidateConfigMapVolume(t *testing.T) {
fakeClient := fake.NewFakeClient()
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateConfigMapVolume(volume)
@ -627,7 +627,7 @@ func TestValidateConfigMapVolume(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateConfigMapVolume(volume)
@ -653,7 +653,7 @@ func TestValidateConfigMapVolume(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateConfigMapVolume(volume)
@ -678,7 +678,7 @@ func TestValidateSecretVolume(t *testing.T) {
fakeClient := fake.NewFakeClient()
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateSecretVolume(volume)
@ -704,7 +704,7 @@ func TestValidateSecretVolume(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateSecretVolume(volume)
@ -728,7 +728,7 @@ func TestValidateSecretVolume(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateSecretVolume(volume)
assert.NoError(t, err)
@ -752,7 +752,7 @@ func TestValidateCustomization(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Jenkins: jenkins,
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
got, err := baseReconcileLoop.validateCustomization(customization, "spec.groovyScripts")
@ -774,7 +774,7 @@ func TestValidateCustomization(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Jenkins: jenkins,
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
err := fakeClient.Create(context.TODO(), secret)
require.NoError(t, err)
@ -805,7 +805,7 @@ func TestValidateCustomization(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Jenkins: jenkins,
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
err := fakeClient.Create(context.TODO(), secret)
require.NoError(t, err)
err = fakeClient.Create(context.TODO(), configMap)
@ -832,7 +832,7 @@ func TestValidateCustomization(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Jenkins: jenkins,
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
err := fakeClient.Create(context.TODO(), configMap)
require.NoError(t, err)
@ -857,7 +857,7 @@ func TestValidateCustomization(t *testing.T) {
baseReconcileLoop := New(configuration.Configuration{
Jenkins: jenkins,
Client: fakeClient,
}, nil, logf.ZapLogger(false), false, false, nil)
}, logf.ZapLogger(false), false, false, nil)
err := fakeClient.Create(context.TODO(), secret)
require.NoError(t, err)

View File

@ -10,9 +10,13 @@ import (
stackerr "github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
// Configuration holds required for Jenkins configuration
@ -21,6 +25,7 @@ type Configuration struct {
ClientSet kubernetes.Clientset
Notifications *chan event.Event
Jenkins *v1alpha2.Jenkins
Scheme *runtime.Scheme
}
// RestartJenkinsMasterPod terminate Jenkins master pod and notifies about it
@ -49,3 +54,51 @@ func (c *Configuration) getJenkinsMasterPod() (*corev1.Pod, error) {
}
return currentJenkinsMasterPod, nil
}
// CreateResource is creating kubernetes resource and references it to Jenkins CR
func (c *Configuration) CreateResource(obj metav1.Object) error {
runtimeObj, ok := obj.(runtime.Object)
if !ok {
return stackerr.Errorf("is not a %T a runtime.Object", obj)
}
// Set Jenkins instance as the owner and controller
if err := controllerutil.SetControllerReference(c.Jenkins, obj, c.Scheme); err != nil {
return stackerr.WithStack(err)
}
return c.Client.Create(context.TODO(), runtimeObj) // don't wrap error
}
// UpdateResource is updating kubernetes resource and references it to Jenkins CR
func (c *Configuration) UpdateResource(obj metav1.Object) error {
runtimeObj, ok := obj.(runtime.Object)
if !ok {
return stackerr.Errorf("is not a %T a runtime.Object", obj)
}
// set Jenkins instance as the owner and controller, don't check error(can be already set)
_ = controllerutil.SetControllerReference(c.Jenkins, obj, c.Scheme)
return c.Client.Update(context.TODO(), runtimeObj) // don't wrap error
}
// CreateOrUpdateResource is creating or updating kubernetes resource and references it to Jenkins CR
func (c *Configuration) CreateOrUpdateResource(obj metav1.Object) error {
runtimeObj, ok := obj.(runtime.Object)
if !ok {
return stackerr.Errorf("is not a %T a runtime.Object", obj)
}
// set Jenkins instance as the owner and controller, don't check error(can be already set)
_ = controllerutil.SetControllerReference(c.Jenkins, obj, c.Scheme)
err := c.Client.Create(context.TODO(), runtimeObj)
if err != nil && errors.IsAlreadyExists(err) {
return c.UpdateResource(obj)
} else if err != nil && !errors.IsAlreadyExists(err) {
return stackerr.WithStack(err)
}
return nil
}

View File

@ -214,10 +214,11 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg
ClientSet: r.clientSet,
Notifications: r.notificationEvents,
Jenkins: jenkins,
Scheme: r.scheme,
}
// Reconcile base configuration
baseConfiguration := base.New(config, r.scheme, logger, r.local, r.minikube, &r.config)
baseConfiguration := base.New(config, logger, r.local, r.minikube, &r.config)
baseMessages, err := baseConfiguration.Validate(jenkins)
if err != nil {