mirror of
https://github.com/jenkinsci/kubernetes-operator.git
synced 2026-10-22 07:02:58 +02:00
Add backup API
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/backup"
|
||||
jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants"
|
||||
@@ -61,7 +62,16 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
|
||||
return reconcile.Result{}, nil, err
|
||||
}
|
||||
|
||||
result, err := r.ensureJenkinsMasterPod(metaObject)
|
||||
pluginsRequiredByAllBackupProviders := backup.GetPluginsRequiredByAllBackupProviders()
|
||||
result, err := r.ensurePluginsRequiredByAllBackupProviders(pluginsRequiredByAllBackupProviders)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, nil, err
|
||||
}
|
||||
if result.Requeue {
|
||||
return result, nil, nil
|
||||
}
|
||||
|
||||
result, err = r.ensureJenkinsMasterPod(metaObject)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, nil, err
|
||||
}
|
||||
@@ -85,7 +95,7 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
|
||||
}
|
||||
r.logger.V(log.VDebug).Info("Jenkins API client set")
|
||||
|
||||
ok, err := r.verifyBasePlugins(jenkinsClient)
|
||||
ok, err := r.verifyPlugins(jenkinsClient, plugins.BasePluginsMap, pluginsRequiredByAllBackupProviders)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, nil, err
|
||||
}
|
||||
@@ -142,7 +152,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) verifyBasePlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) {
|
||||
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins, allRequiredPlugins ...map[string][]plugins.Plugin) (bool, error) {
|
||||
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -157,17 +167,19 @@ func (r *ReconcileJenkinsBaseConfiguration) verifyBasePlugins(jenkinsClient jenk
|
||||
r.logger.V(log.VDebug).Info(fmt.Sprintf("Installed plugins '%+v'", installedPlugins))
|
||||
|
||||
status := true
|
||||
for rootPluginName, p := range plugins.BasePluginsMap {
|
||||
rootPlugin, _ := plugins.New(rootPluginName)
|
||||
if found, ok := isPluginInstalled(allPluginsInJenkins, *rootPlugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Missing plugin '%s', actual '%+v'", rootPlugin, found))
|
||||
status = false
|
||||
}
|
||||
for _, requiredPlugin := range p {
|
||||
if found, ok := isPluginInstalled(allPluginsInJenkins, requiredPlugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Missing plugin '%s', actual '%+v'", requiredPlugin, found))
|
||||
for _, requiredPlugins := range allRequiredPlugins {
|
||||
for rootPluginName, p := range requiredPlugins {
|
||||
rootPlugin, _ := plugins.New(rootPluginName)
|
||||
if found, ok := isPluginInstalled(allPluginsInJenkins, *rootPlugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Missing plugin '%s', actual '%+v'", rootPlugin, found))
|
||||
status = false
|
||||
}
|
||||
for _, requiredPlugin := range p {
|
||||
if found, ok := isPluginInstalled(allPluginsInJenkins, requiredPlugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Missing plugin '%s', actual '%+v'", requiredPlugin, found))
|
||||
status = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,3 +500,28 @@ func (r *ReconcileJenkinsBaseConfiguration) verifyLabelsForWatchedResource(objec
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) ensurePluginsRequiredByAllBackupProviders(requiredPlugins map[string][]plugins.Plugin) (reconcile.Result, error) {
|
||||
copiedPlugins := map[string][]string{}
|
||||
for key, value := range r.jenkins.Spec.Master.Plugins {
|
||||
copiedPlugins[key] = value
|
||||
}
|
||||
for key, value := range requiredPlugins {
|
||||
copiedPlugins[key] = func() []string {
|
||||
var pluginsWithVersion []string
|
||||
for _, plugin := range value {
|
||||
pluginsWithVersion = append(pluginsWithVersion, plugin.String())
|
||||
}
|
||||
return pluginsWithVersion
|
||||
}()
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(r.jenkins.Spec.Master.Plugins, copiedPlugins) {
|
||||
r.logger.Info("Adding plugins required by backup providers to '.spec.master.plugins'")
|
||||
r.jenkins.Spec.Master.Plugins = copiedPlugins
|
||||
err := r.k8sClient.Update(context.TODO(), r.jenkins)
|
||||
return reconcile.Result{Requeue: true}, err
|
||||
}
|
||||
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugins"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
)
|
||||
|
||||
func TestReconcileJenkinsBaseConfiguration_ensurePluginsRequiredByAllBackupProviders(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
jenkins *virtuslabv1alpha1.Jenkins
|
||||
requiredPlugins map[string][]plugins.Plugin
|
||||
want reconcile.Result
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "happy, no required plugins",
|
||||
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||
Master: virtuslabv1alpha1.JenkinsMaster{
|
||||
Plugins: map[string][]string{
|
||||
"first-plugin:0.0.1": {"second-plugin:0.0.1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: reconcile.Result{Requeue: false},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "happy, required plugins are set",
|
||||
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||
Master: virtuslabv1alpha1.JenkinsMaster{
|
||||
Plugins: map[string][]string{
|
||||
"first-plugin:0.0.1": {"second-plugin:0.0.1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
requiredPlugins: map[string][]plugins.Plugin{
|
||||
"first-plugin:0.0.1": {plugins.Must(plugins.New("second-plugin:0.0.1"))},
|
||||
},
|
||||
want: reconcile.Result{Requeue: false},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "happy, jenkins CR must be updated",
|
||||
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||
Master: virtuslabv1alpha1.JenkinsMaster{
|
||||
Plugins: map[string][]string{
|
||||
"first-plugin:0.0.1": {"second-plugin:0.0.1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
requiredPlugins: map[string][]plugins.Plugin{
|
||||
"first-plugin:0.0.1": {plugins.Must(plugins.New("second-plugin:0.0.1"))},
|
||||
"third-plugin:0.0.1": {},
|
||||
},
|
||||
want: reconcile.Result{Requeue: true},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "happy, jenkins CR must be updated",
|
||||
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||
Master: virtuslabv1alpha1.JenkinsMaster{
|
||||
Plugins: map[string][]string{
|
||||
"first-plugin:0.0.1": {"second-plugin:0.0.1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
requiredPlugins: map[string][]plugins.Plugin{
|
||||
"first-plugin:0.0.1": {plugins.Must(plugins.New("second-plugin:0.0.1"))},
|
||||
"third-plugin:0.0.1": {plugins.Must(plugins.New("fourth-plugin:0.0.1"))},
|
||||
},
|
||||
want: reconcile.Result{Requeue: true},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := virtuslabv1alpha1.SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
assert.NoError(t, err)
|
||||
r := &ReconcileJenkinsBaseConfiguration{
|
||||
k8sClient: fake.NewFakeClient(),
|
||||
scheme: nil,
|
||||
logger: logf.ZapLogger(false),
|
||||
jenkins: tt.jenkins,
|
||||
local: false,
|
||||
minikube: false,
|
||||
}
|
||||
err = r.k8sClient.Create(context.TODO(), tt.jenkins)
|
||||
assert.NoError(t, err)
|
||||
got, err := r.ensurePluginsRequiredByAllBackupProviders(tt.requiredPlugins)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user