#1 Split plugins in two groups:required by operator and required by user
This commit is contained in:
parent
dd04c0cf5b
commit
08b6dfb691
|
|
@ -6,9 +6,8 @@ This document describes a getting started guide for **jenkins-operator** and an
|
||||||
2. [Deploy Jenkins](#deploy-jenkins)
|
2. [Deploy Jenkins](#deploy-jenkins)
|
||||||
3. [Configure Seed Jobs and Pipelines](#configure-seed-jobs-and-pipelines)
|
3. [Configure Seed Jobs and Pipelines](#configure-seed-jobs-and-pipelines)
|
||||||
4. [Install Plugins](#install-plugins)
|
4. [Install Plugins](#install-plugins)
|
||||||
5. [Configure Authorization](#configure-authorization)
|
5. [Configure Backup & Restore](#configure-backup-&-restore)
|
||||||
6. [Configure Backup & Restore](#configure-backup-&-restore)
|
6. [Debugging](#debugging)
|
||||||
7. [Debugging](#debugging)
|
|
||||||
|
|
||||||
## First Steps
|
## First Steps
|
||||||
|
|
||||||
|
|
@ -256,6 +255,27 @@ When **jenkins-operator-user-configuration-example** ConfigMap is updated Jenkin
|
||||||
|
|
||||||
## Install Plugins
|
## Install Plugins
|
||||||
|
|
||||||
|
### Via CR
|
||||||
|
|
||||||
|
Edit CR under `spec.master.plugins`:
|
||||||
|
|
||||||
|
```
|
||||||
|
apiVersion: jenkins.io/v1alpha1
|
||||||
|
kind: Jenkins
|
||||||
|
metadata:
|
||||||
|
name: example
|
||||||
|
spec:
|
||||||
|
master:
|
||||||
|
image: jenkins/jenkins:lts
|
||||||
|
plugins:
|
||||||
|
configuration-as-code:1.4:
|
||||||
|
- configuration-as-code-support:1.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Then **jenkins-operator** will automatically install plugins after Jenkins master pod restart.
|
||||||
|
|
||||||
|
### Via groovy script
|
||||||
|
|
||||||
To install a plugin please add **2-install-slack-plugin.groovy** script to the **jenkins-operator-user-configuration-example** ConfigMap:
|
To install a plugin please add **2-install-slack-plugin.groovy** script to the **jenkins-operator-user-configuration-example** ConfigMap:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -318,7 +338,7 @@ data:
|
||||||
|
|
||||||
Then **jenkins-operator** will automatically trigger **jenkins-operator-user-configuration** Jenkins Job again.
|
Then **jenkins-operator** will automatically trigger **jenkins-operator-user-configuration** Jenkins Job again.
|
||||||
|
|
||||||
## Configure Backup & Restore (work in progress)
|
## Configure Backup & Restore
|
||||||
|
|
||||||
Not implemented yet.
|
Not implemented yet.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,10 @@ type JenkinsMaster struct {
|
||||||
Image string `json:"image,omitempty"`
|
Image string `json:"image,omitempty"`
|
||||||
Annotations map[string]string `json:"masterAnnotations,omitempty"`
|
Annotations map[string]string `json:"masterAnnotations,omitempty"`
|
||||||
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||||
Plugins map[string][]string `json:"plugins,omitempty"`
|
// OperatorPlugins contains plugins required by operator
|
||||||
|
OperatorPlugins map[string][]string `json:"basePlugins,omitempty"`
|
||||||
|
// Plugins contains plugins required by user
|
||||||
|
Plugins map[string][]string `json:"plugins,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JenkinsStatus defines the observed state of Jenkins
|
// JenkinsStatus defines the observed state of Jenkins
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,21 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in.Resources.DeepCopyInto(&out.Resources)
|
in.Resources.DeepCopyInto(&out.Resources)
|
||||||
|
if in.OperatorPlugins != nil {
|
||||||
|
in, out := &in.OperatorPlugins, &out.OperatorPlugins
|
||||||
|
*out = make(map[string][]string, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
var outVal []string
|
||||||
|
if val == nil {
|
||||||
|
(*out)[key] = nil
|
||||||
|
} else {
|
||||||
|
in, out := &val, &outVal
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
(*out)[key] = outVal
|
||||||
|
}
|
||||||
|
}
|
||||||
if in.Plugins != nil {
|
if in.Plugins != nil {
|
||||||
in, out := &in.Plugins, &out.Plugins
|
in, out := &in.Plugins, &out.Plugins
|
||||||
*out = make(map[string][]string, len(*in))
|
*out = make(map[string][]string, len(*in))
|
||||||
|
|
|
||||||
|
|
@ -85,12 +85,13 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
|
||||||
}
|
}
|
||||||
r.logger.V(log.VDebug).Info("Jenkins API client set")
|
r.logger.V(log.VDebug).Info("Jenkins API client set")
|
||||||
|
|
||||||
ok, err := r.verifyPlugins(jenkinsClient, plugins.BasePluginsMap)
|
ok, err := r.verifyPlugins(jenkinsClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return reconcile.Result{}, nil, err
|
return reconcile.Result{}, nil, err
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
r.logger.V(log.VWarn).Info("Please correct Jenkins CR (spec.master.plugins)")
|
r.logger.V(log.VWarn).Info("Please correct Jenkins CR(spec.master.OperatorPlugins or spec.master.plugins)")
|
||||||
|
// TODO inform user via Admin Monitor and don't restart Jenkins
|
||||||
return reconcile.Result{Requeue: true}, nil, r.restartJenkinsMasterPod(metaObject)
|
return reconcile.Result{Requeue: true}, nil, r.restartJenkinsMasterPod(metaObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,7 +138,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins, allRequiredPlugins ...map[string][]plugins.Plugin) (bool, error) {
|
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) {
|
||||||
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
@ -151,7 +152,21 @@ func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsc
|
||||||
}
|
}
|
||||||
r.logger.V(log.VDebug).Info(fmt.Sprintf("Installed plugins '%+v'", installedPlugins))
|
r.logger.V(log.VDebug).Info(fmt.Sprintf("Installed plugins '%+v'", installedPlugins))
|
||||||
|
|
||||||
|
userPlugins := map[string][]plugins.Plugin{}
|
||||||
|
for rootPlugin, dependentPluginNames := range r.jenkins.Spec.Master.Plugins {
|
||||||
|
var dependentPlugins []plugins.Plugin
|
||||||
|
for _, pluginNameWithVersion := range dependentPluginNames {
|
||||||
|
plugin, err := plugins.New(pluginNameWithVersion)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
dependentPlugins = append(dependentPlugins, *plugin)
|
||||||
|
}
|
||||||
|
userPlugins[rootPlugin] = dependentPlugins
|
||||||
|
}
|
||||||
|
|
||||||
status := true
|
status := true
|
||||||
|
allRequiredPlugins := []map[string][]plugins.Plugin{plugins.BasePluginsMap, userPlugins}
|
||||||
for _, requiredPlugins := range allRequiredPlugins {
|
for _, requiredPlugins := range allRequiredPlugins {
|
||||||
for rootPluginName, p := range requiredPlugins {
|
for rootPluginName, p := range requiredPlugins {
|
||||||
rootPlugin, _ := plugins.New(rootPluginName)
|
rootPlugin, _ := plugins.New(rootPluginName)
|
||||||
|
|
|
||||||
|
|
@ -254,12 +254,19 @@ chmod +x {{ .JenkinsHomePath }}/scripts/*.sh
|
||||||
{{- $jenkinsHomePath := .JenkinsHomePath }}
|
{{- $jenkinsHomePath := .JenkinsHomePath }}
|
||||||
{{- $installPluginsCommand := .InstallPluginsCommand }}
|
{{- $installPluginsCommand := .InstallPluginsCommand }}
|
||||||
|
|
||||||
echo "Installing plugins - begin"
|
echo "Installing plugins required by Operator - begin"
|
||||||
{{- range $rootPluginName, $plugins := .Plugins }}
|
{{- range $rootPluginName, $plugins := .OperatorPlugins }}
|
||||||
echo "Installing required plugins for '{{ $rootPluginName }}'"
|
echo "Installing required plugins for '{{ $rootPluginName }}'"
|
||||||
{{ $jenkinsHomePath }}/scripts/{{ $installPluginsCommand }} {{ $rootPluginName }} {{ range $index, $plugin := $plugins }}{{ . }} {{ end }}
|
{{ $jenkinsHomePath }}/scripts/{{ $installPluginsCommand }} {{ $rootPluginName }} {{ range $index, $plugin := $plugins }}{{ . }} {{ end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
echo "Installing plugins - end"
|
echo "Installing plugins required by Operator - end"
|
||||||
|
|
||||||
|
echo "Installing plugins required by user - begin"
|
||||||
|
{{- range $rootPluginName, $plugins := .UserPlugins }}
|
||||||
|
echo "Installing required plugins for '{{ $rootPluginName }}'"
|
||||||
|
{{ $jenkinsHomePath }}/scripts/{{ $installPluginsCommand }} {{ $rootPluginName }} {{ range $index, $plugin := $plugins }}{{ . }} {{ end }}
|
||||||
|
{{- end }}
|
||||||
|
echo "Installing plugins required by user - end"
|
||||||
|
|
||||||
/sbin/tini -s -- /usr/local/bin/jenkins.sh
|
/sbin/tini -s -- /usr/local/bin/jenkins.sh
|
||||||
`))
|
`))
|
||||||
|
|
@ -271,17 +278,19 @@ func buildConfigMapTypeMeta() metav1.TypeMeta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildInitBashScript(pluginsToInstall map[string][]string) (*string, error) {
|
func buildInitBashScript(jenkins *v1alpha1.Jenkins) (*string, error) {
|
||||||
data := struct {
|
data := struct {
|
||||||
JenkinsHomePath string
|
JenkinsHomePath string
|
||||||
InitConfigurationPath string
|
InitConfigurationPath string
|
||||||
InstallPluginsCommand string
|
InstallPluginsCommand string
|
||||||
JenkinsScriptsVolumePath string
|
JenkinsScriptsVolumePath string
|
||||||
Plugins map[string][]string
|
OperatorPlugins map[string][]string
|
||||||
|
UserPlugins map[string][]string
|
||||||
}{
|
}{
|
||||||
JenkinsHomePath: jenkinsHomePath,
|
JenkinsHomePath: jenkinsHomePath,
|
||||||
InitConfigurationPath: jenkinsInitConfigurationVolumePath,
|
InitConfigurationPath: jenkinsInitConfigurationVolumePath,
|
||||||
Plugins: pluginsToInstall,
|
OperatorPlugins: jenkins.Spec.Master.OperatorPlugins,
|
||||||
|
UserPlugins: jenkins.Spec.Master.Plugins,
|
||||||
InstallPluginsCommand: installPluginsCommand,
|
InstallPluginsCommand: installPluginsCommand,
|
||||||
JenkinsScriptsVolumePath: jenkinsScriptsVolumePath,
|
JenkinsScriptsVolumePath: jenkinsScriptsVolumePath,
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +311,7 @@ func getScriptsConfigMapName(jenkins *v1alpha1.Jenkins) string {
|
||||||
func NewScriptsConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha1.Jenkins) (*corev1.ConfigMap, error) {
|
func NewScriptsConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha1.Jenkins) (*corev1.ConfigMap, error) {
|
||||||
meta.Name = getScriptsConfigMapName(jenkins)
|
meta.Name = getScriptsConfigMapName(jenkins)
|
||||||
|
|
||||||
initBashScript, err := buildInitBashScript(jenkins.Spec.Master.Plugins)
|
initBashScript, err := buildInitBashScript(jenkins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,34 +28,39 @@ func (r *ReconcileJenkinsBaseConfiguration) Validate(jenkins *v1alpha1.Jenkins)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !r.validatePlugins(jenkins.Spec.Master.Plugins) {
|
if !r.validatePlugins(jenkins.Spec.Master.OperatorPlugins, jenkins.Spec.Master.Plugins) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) validatePlugins(pluginsWithVersions map[string][]string) bool {
|
func (r *ReconcileJenkinsBaseConfiguration) validatePlugins(pluginsWithVersionSlice ...map[string][]string) bool {
|
||||||
valid := true
|
valid := true
|
||||||
allPlugins := map[string][]plugins.Plugin{}
|
allPlugins := map[plugins.Plugin][]plugins.Plugin{}
|
||||||
|
|
||||||
for rootPluginName, dependentPluginNames := range pluginsWithVersions {
|
for _, pluginsWithVersions := range pluginsWithVersionSlice {
|
||||||
if _, err := plugins.New(rootPluginName); err != nil {
|
for rootPluginName, dependentPluginNames := range pluginsWithVersions {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Invalid root plugin name '%s'", rootPluginName))
|
rootPlugin, err := plugins.New(rootPluginName)
|
||||||
valid = false
|
if err != nil {
|
||||||
}
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Invalid root plugin name '%s'", rootPluginName))
|
||||||
|
|
||||||
dependentPlugins := []plugins.Plugin{}
|
|
||||||
for _, pluginName := range dependentPluginNames {
|
|
||||||
if p, err := plugins.New(pluginName); err != nil {
|
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Invalid dependent plugin name '%s' in root plugin '%s'", pluginName, rootPluginName))
|
|
||||||
valid = false
|
valid = false
|
||||||
} else {
|
}
|
||||||
dependentPlugins = append(dependentPlugins, *p)
|
|
||||||
|
var dependentPlugins []plugins.Plugin
|
||||||
|
for _, pluginName := range dependentPluginNames {
|
||||||
|
if p, err := plugins.New(pluginName); err != nil {
|
||||||
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Invalid dependent plugin name '%s' in root plugin '%s'", pluginName, rootPluginName))
|
||||||
|
valid = false
|
||||||
|
} else {
|
||||||
|
dependentPlugins = append(dependentPlugins, *p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rootPlugin != nil {
|
||||||
|
allPlugins[*rootPlugin] = dependentPlugins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allPlugins[rootPluginName] = dependentPlugins
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid {
|
if valid {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package base
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
@ -9,50 +8,60 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidatePlugins(t *testing.T) {
|
func TestValidatePlugins(t *testing.T) {
|
||||||
data := []struct {
|
|
||||||
plugins map[string][]string
|
|
||||||
expectedResult bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
plugins: map[string][]string{
|
|
||||||
"valid-plugin-name:1.0": {
|
|
||||||
"valid-plugin-name:1.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plugins: map[string][]string{
|
|
||||||
"invalid-plugin-name": {
|
|
||||||
"invalid-plugin-name",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plugins: map[string][]string{
|
|
||||||
"valid-plugin-name:1.0": {
|
|
||||||
"valid-plugin-name:1.0",
|
|
||||||
"valid-plugin-name2:1.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plugins: map[string][]string{
|
|
||||||
"valid-plugin-name:1.0": {},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
|
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
|
||||||
nil, false, false)
|
nil, false, false)
|
||||||
|
t.Run("happy", func(t *testing.T) {
|
||||||
|
plugins := map[string][]string{
|
||||||
|
"valid-plugin-name:1.0": {
|
||||||
|
"valid-plugin-name:1.0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := baseReconcileLoop.validatePlugins(plugins)
|
||||||
|
assert.Equal(t, true, got)
|
||||||
|
})
|
||||||
|
t.Run("fail, no version in plugin name", func(t *testing.T) {
|
||||||
|
plugins := map[string][]string{
|
||||||
|
"invalid-plugin-name": {
|
||||||
|
"invalid-plugin-name",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := baseReconcileLoop.validatePlugins(plugins)
|
||||||
|
assert.Equal(t, false, got)
|
||||||
|
})
|
||||||
|
t.Run("fail, no version in root plugin name", func(t *testing.T) {
|
||||||
|
plugins := map[string][]string{
|
||||||
|
"invalid-plugin-name": {
|
||||||
|
"invalid-plugin-name:1.0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := baseReconcileLoop.validatePlugins(plugins)
|
||||||
|
assert.Equal(t, false, got)
|
||||||
|
})
|
||||||
|
t.Run("fail, no version in plugin name", func(t *testing.T) {
|
||||||
|
plugins := map[string][]string{
|
||||||
|
"invalid-plugin-name:1.0": {
|
||||||
|
"invalid-plugin-name",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := baseReconcileLoop.validatePlugins(plugins)
|
||||||
|
assert.Equal(t, false, got)
|
||||||
|
})
|
||||||
|
t.Run("happy", func(t *testing.T) {
|
||||||
|
plugins := map[string][]string{
|
||||||
|
"valid-plugin-name:1.0": {
|
||||||
|
"valid-plugin-name:1.0",
|
||||||
|
"valid-plugin-name2:1.0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := baseReconcileLoop.validatePlugins(plugins)
|
||||||
|
assert.Equal(t, true, got)
|
||||||
|
})
|
||||||
|
t.Run("hapy", func(t *testing.T) {
|
||||||
|
plugins := map[string][]string{
|
||||||
|
"valid-plugin-name:1.0": {},
|
||||||
|
}
|
||||||
|
got := baseReconcileLoop.validatePlugins(plugins)
|
||||||
|
assert.Equal(t, true, got)
|
||||||
|
})
|
||||||
|
|
||||||
for index, testingData := range data {
|
|
||||||
t.Run(fmt.Sprintf("Testing %d plugins set", index), func(t *testing.T) {
|
|
||||||
result := baseReconcileLoop.validatePlugins(testingData.plugins)
|
|
||||||
assert.Equal(t, testingData.expectedResult, result)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -212,10 +212,14 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha1.Jenkins, logger logr.Lo
|
||||||
changed = true
|
changed = true
|
||||||
jenkins.Spec.Master.Image = constants.DefaultJenkinsMasterImage
|
jenkins.Spec.Master.Image = constants.DefaultJenkinsMasterImage
|
||||||
}
|
}
|
||||||
if len(jenkins.Spec.Master.Plugins) == 0 {
|
if len(jenkins.Spec.Master.OperatorPlugins) == 0 {
|
||||||
logger.Info("Setting default base plugins")
|
logger.Info("Setting default base plugins")
|
||||||
changed = true
|
changed = true
|
||||||
jenkins.Spec.Master.Plugins = plugins.BasePlugins()
|
jenkins.Spec.Master.OperatorPlugins = plugins.BasePlugins()
|
||||||
|
}
|
||||||
|
if len(jenkins.Spec.Master.Plugins) == 0 {
|
||||||
|
changed = true
|
||||||
|
jenkins.Spec.Master.Plugins = map[string][]string{"simple-theme-plugin:0.5.1": {}}
|
||||||
}
|
}
|
||||||
_, requestCPUSet := jenkins.Spec.Master.Resources.Requests[corev1.ResourceCPU]
|
_, requestCPUSet := jenkins.Spec.Master.Resources.Requests[corev1.ResourceCPU]
|
||||||
_, requestMemporySet := jenkins.Spec.Master.Resources.Requests[corev1.ResourceMemory]
|
_, requestMemporySet := jenkins.Spec.Master.Resources.Requests[corev1.ResourceMemory]
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,72 @@
|
||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ApacheComponentsClientPlugin is apache-httpcomponents-client-4-api Jenkins plugin with version
|
apacheComponentsClientPlugin = "apache-httpcomponents-client-4-api:4.5.5-3.0"
|
||||||
ApacheComponentsClientPlugin = "apache-httpcomponents-client-4-api:4.5.5-3.0"
|
jackson2ADIPlugin = "jackson2-api:2.9.8"
|
||||||
// Jackson2ADIPlugin is jackson2-api-httpcomponents-client-4-api Jenkins plugin with version
|
credentialsPlugin = "credentials:2.1.18"
|
||||||
Jackson2ADIPlugin = "jackson2-api:2.9.8"
|
cloudBeesFolderPlugin = "cloudbees-folder:6.7"
|
||||||
|
durableTaskPlugin = "durable-task:1.28"
|
||||||
|
plainCredentialsPlugin = "plain-credentials:1.5"
|
||||||
|
structsPlugin = "structs:1.17"
|
||||||
|
workflowStepAPIPlugin = "workflow-step-api:2.17"
|
||||||
|
scmAPIPlugin = "scm-api:2.3.0"
|
||||||
|
workflowAPIPlugin = "workflow-api:2.33"
|
||||||
|
workflowSupportPlugin = "workflow-support:3.0"
|
||||||
|
displayURLAPIPlugin = "display-url-api:2.3.0"
|
||||||
|
gitClientPlugin = "git-client:2.7.6"
|
||||||
|
jschPlugin = "jsch:0.1.55"
|
||||||
|
junitPlugin = "junit:1.26.1"
|
||||||
|
mailerPlugin = "mailer:1.23"
|
||||||
|
matrixProjectPlugin = "matrix-project:1.13"
|
||||||
|
scriptSecurityPlugin = "script-security:1.50"
|
||||||
|
sshCredentialsPlugin = "ssh-credentials:1.14"
|
||||||
|
workflowSCMStepPlugin = "workflow-scm-step:2.7"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BasePluginsMap contains plugins to install by operator
|
// BasePluginsMap contains plugins to install by operator
|
||||||
var BasePluginsMap = map[string][]Plugin{
|
var BasePluginsMap = map[string][]Plugin{
|
||||||
Must(New("kubernetes:1.13.8")).String(): {
|
Must(New("kubernetes:1.13.8")).String(): {
|
||||||
Must(New(ApacheComponentsClientPlugin)),
|
Must(New(apacheComponentsClientPlugin)),
|
||||||
Must(New("cloudbees-folder:6.7")),
|
Must(New(cloudBeesFolderPlugin)),
|
||||||
Must(New("credentials:2.1.18")),
|
Must(New(credentialsPlugin)),
|
||||||
Must(New("durable-task:1.28")),
|
Must(New(durableTaskPlugin)),
|
||||||
Must(New(Jackson2ADIPlugin)),
|
Must(New(jackson2ADIPlugin)),
|
||||||
Must(New("kubernetes-credentials:0.4.0")),
|
Must(New("kubernetes-credentials:0.4.0")),
|
||||||
Must(New("plain-credentials:1.5")),
|
Must(New(plainCredentialsPlugin)),
|
||||||
Must(New("structs:1.17")),
|
Must(New(structsPlugin)),
|
||||||
Must(New("variant:1.1")),
|
Must(New("variant:1.1")),
|
||||||
Must(New("workflow-step-api:2.17")),
|
Must(New(workflowStepAPIPlugin)),
|
||||||
},
|
},
|
||||||
Must(New("workflow-job:2.31")).String(): {
|
Must(New("workflow-job:2.31")).String(): {
|
||||||
Must(New("scm-api:2.3.0")),
|
Must(New(scmAPIPlugin)),
|
||||||
Must(New("script-security:1.50")),
|
Must(New(scriptSecurityPlugin)),
|
||||||
Must(New("structs:1.17")),
|
Must(New(structsPlugin)),
|
||||||
Must(New("workflow-api:2.33")),
|
Must(New(workflowAPIPlugin)),
|
||||||
Must(New("workflow-step-api:2.17")),
|
Must(New(workflowStepAPIPlugin)),
|
||||||
Must(New("workflow-support:3.0")),
|
Must(New(workflowSupportPlugin)),
|
||||||
},
|
},
|
||||||
Must(New("workflow-aggregator:2.6")).String(): {
|
Must(New("workflow-aggregator:2.6")).String(): {
|
||||||
Must(New("ace-editor:1.1")),
|
Must(New("ace-editor:1.1")),
|
||||||
Must(New(ApacheComponentsClientPlugin)),
|
Must(New(apacheComponentsClientPlugin)),
|
||||||
Must(New("authentication-tokens:1.3")),
|
Must(New("authentication-tokens:1.3")),
|
||||||
Must(New("branch-api:2.1.2")),
|
Must(New("branch-api:2.1.2")),
|
||||||
Must(New("cloudbees-folder:6.7")),
|
Must(New(cloudBeesFolderPlugin)),
|
||||||
Must(New("credentials-binding:1.17")),
|
Must(New("credentials-binding:1.17")),
|
||||||
Must(New("credentials:2.1.18")),
|
Must(New(credentialsPlugin)),
|
||||||
Must(New("display-url-api:2.3.0")),
|
Must(New(displayURLAPIPlugin)),
|
||||||
Must(New("docker-commons:1.13")),
|
Must(New("docker-commons:1.13")),
|
||||||
Must(New("docker-workflow:1.17")),
|
Must(New("docker-workflow:1.17")),
|
||||||
Must(New("durable-task:1.28")),
|
Must(New(durableTaskPlugin)),
|
||||||
Must(New("git-client:2.7.6")),
|
Must(New(gitClientPlugin)),
|
||||||
Must(New("git-server:1.7")),
|
Must(New("git-server:1.7")),
|
||||||
Must(New("handlebars:1.1.1")),
|
Must(New("handlebars:1.1.1")),
|
||||||
Must(New(Jackson2ADIPlugin)),
|
Must(New(jackson2ADIPlugin)),
|
||||||
Must(New("jquery-detached:1.2.1")),
|
Must(New("jquery-detached:1.2.1")),
|
||||||
Must(New("jsch:0.1.55")),
|
Must(New(jschPlugin)),
|
||||||
Must(New("junit:1.26.1")),
|
Must(New(junitPlugin)),
|
||||||
Must(New("lockable-resources:2.3")),
|
Must(New("lockable-resources:2.3")),
|
||||||
Must(New("mailer:1.23")),
|
Must(New(mailerPlugin)),
|
||||||
Must(New("matrix-project:1.13")),
|
Must(New(matrixProjectPlugin)),
|
||||||
Must(New("momentjs:1.1.1")),
|
Must(New("momentjs:1.1.1")),
|
||||||
Must(New("pipeline-build-step:2.7")),
|
Must(New("pipeline-build-step:2.7")),
|
||||||
Must(New("pipeline-graph-analysis:1.9")),
|
Must(New("pipeline-graph-analysis:1.9")),
|
||||||
|
|
@ -64,48 +80,46 @@ var BasePluginsMap = map[string][]Plugin{
|
||||||
Must(New("pipeline-stage-step:2.3")),
|
Must(New("pipeline-stage-step:2.3")),
|
||||||
Must(New("pipeline-stage-tags-metadata:1.3.4.1")),
|
Must(New("pipeline-stage-tags-metadata:1.3.4.1")),
|
||||||
Must(New("pipeline-stage-view:2.10")),
|
Must(New("pipeline-stage-view:2.10")),
|
||||||
Must(New("plain-credentials:1.5")),
|
Must(New(plainCredentialsPlugin)),
|
||||||
Must(New("scm-api:2.3.0")),
|
Must(New(scmAPIPlugin)),
|
||||||
Must(New("script-security:1.50")),
|
Must(New(scriptSecurityPlugin)),
|
||||||
Must(New("ssh-credentials:1.14")),
|
Must(New(sshCredentialsPlugin)),
|
||||||
Must(New("structs:1.17")),
|
Must(New(structsPlugin)),
|
||||||
Must(New("workflow-api:2.33")),
|
Must(New(workflowAPIPlugin)),
|
||||||
Must(New("workflow-basic-steps:2.13")),
|
Must(New("workflow-basic-steps:2.13")),
|
||||||
Must(New("workflow-cps-global-lib:2.12")),
|
Must(New("workflow-cps-global-lib:2.12")),
|
||||||
Must(New("workflow-cps:2.61.1")),
|
Must(New("workflow-cps:2.61.1")),
|
||||||
Must(New("workflow-durable-task-step:2.27")),
|
Must(New("workflow-durable-task-step:2.27")),
|
||||||
Must(New("workflow-job:2.31")),
|
Must(New("workflow-job:2.31")),
|
||||||
Must(New("workflow-multibranch:2.20")),
|
Must(New("workflow-multibranch:2.20")),
|
||||||
Must(New("workflow-scm-step:2.7")),
|
Must(New(workflowSCMStepPlugin)),
|
||||||
Must(New("workflow-step-api:2.17")),
|
Must(New(workflowStepAPIPlugin)),
|
||||||
Must(New("workflow-support:3.0")),
|
Must(New(workflowSupportPlugin)),
|
||||||
},
|
},
|
||||||
Must(New("git:3.9.1")).String(): {
|
Must(New("git:3.9.1")).String(): {
|
||||||
Must(New(ApacheComponentsClientPlugin)),
|
Must(New(apacheComponentsClientPlugin)),
|
||||||
Must(New("credentials:2.1.18")),
|
Must(New(credentialsPlugin)),
|
||||||
Must(New("display-url-api:2.3.0")),
|
Must(New(displayURLAPIPlugin)),
|
||||||
Must(New("git-client:2.7.6")),
|
Must(New(gitClientPlugin)),
|
||||||
Must(New("jsch:0.1.55")),
|
Must(New(jschPlugin)),
|
||||||
Must(New("junit:1.26.1")),
|
Must(New(junitPlugin)),
|
||||||
Must(New("mailer:1.23")),
|
Must(New(mailerPlugin)),
|
||||||
Must(New("matrix-project:1.13")),
|
Must(New(matrixProjectPlugin)),
|
||||||
Must(New("scm-api:2.3.0")),
|
Must(New(scmAPIPlugin)),
|
||||||
Must(New("script-security:1.50")),
|
Must(New(scriptSecurityPlugin)),
|
||||||
Must(New("ssh-credentials:1.14")),
|
Must(New(sshCredentialsPlugin)),
|
||||||
Must(New("structs:1.17")),
|
Must(New(structsPlugin)),
|
||||||
Must(New("workflow-api:2.33")),
|
Must(New(workflowAPIPlugin)),
|
||||||
Must(New("workflow-scm-step:2.7")),
|
Must(New(workflowSCMStepPlugin)),
|
||||||
Must(New("workflow-step-api:2.17")),
|
Must(New(workflowStepAPIPlugin)),
|
||||||
},
|
},
|
||||||
Must(New("job-dsl:1.71")).String(): {
|
Must(New("job-dsl:1.71")).String(): {
|
||||||
Must(New("script-security:1.50")),
|
Must(New(scriptSecurityPlugin)),
|
||||||
Must(New("structs:1.17")),
|
Must(New(structsPlugin)),
|
||||||
},
|
},
|
||||||
Must(New("jobConfigHistory:2.19")).String(): {},
|
|
||||||
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.1")).String(): {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasePlugins returns map of plugins to install by operator
|
// BasePlugins returns map of plugins to install by operator
|
||||||
|
|
|
||||||
|
|
@ -40,26 +40,22 @@ func Must(plugin *Plugin, err error) Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyDependencies checks if all plugins have compatible versions
|
// VerifyDependencies checks if all plugins have compatible versions
|
||||||
func VerifyDependencies(values ...map[string][]Plugin) bool {
|
func VerifyDependencies(values ...map[Plugin][]Plugin) bool {
|
||||||
// key - plugin name, value array of versions
|
// key - plugin name, value array of versions
|
||||||
allPlugins := make(map[string][]Plugin)
|
allPlugins := make(map[string][]Plugin)
|
||||||
valid := true
|
valid := true
|
||||||
|
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
for rootPluginNameAndVersion, plugins := range value {
|
for rootPlugin, plugins := range value {
|
||||||
if rootPlugin, err := New(rootPluginNameAndVersion); err != nil {
|
allPlugins[rootPlugin.Name] = append(allPlugins[rootPlugin.Name], Plugin{
|
||||||
valid = false
|
Name: rootPlugin.Name,
|
||||||
} else {
|
Version: rootPlugin.Version,
|
||||||
allPlugins[rootPlugin.Name] = append(allPlugins[rootPlugin.Name], Plugin{
|
rootPluginNameAndVersion: rootPlugin.String()})
|
||||||
Name: rootPlugin.Name,
|
|
||||||
Version: rootPlugin.Version,
|
|
||||||
rootPluginNameAndVersion: rootPluginNameAndVersion})
|
|
||||||
}
|
|
||||||
for _, plugin := range plugins {
|
for _, plugin := range plugins {
|
||||||
allPlugins[plugin.Name] = append(allPlugins[plugin.Name], Plugin{
|
allPlugins[plugin.Name] = append(allPlugins[plugin.Name], Plugin{
|
||||||
Name: plugin.Name,
|
Name: plugin.Name,
|
||||||
Version: plugin.Version,
|
Version: plugin.Version,
|
||||||
rootPluginNameAndVersion: rootPluginNameAndVersion})
|
rootPluginNameAndVersion: rootPlugin.String()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,90 +1,88 @@
|
||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestVerifyDependencies(t *testing.T) {
|
func TestVerifyDependencies(t *testing.T) {
|
||||||
data := []struct {
|
|
||||||
basePlugins map[string][]Plugin
|
|
||||||
extraPlugins map[string][]Plugin
|
|
||||||
expectedResult bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
basePlugins: map[string][]Plugin{
|
|
||||||
"first-root-plugin:1.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
basePlugins: map[string][]Plugin{
|
|
||||||
"first-root-plugin:1.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
"second-root-plugin:1.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
basePlugins: map[string][]Plugin{
|
|
||||||
"first-root-plugin:1.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraPlugins: map[string][]Plugin{
|
|
||||||
"second-root-plugin:2.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
basePlugins: map[string][]Plugin{
|
|
||||||
"first-root-plugin:1.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
"first-root-plugin:2.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.2")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
basePlugins: map[string][]Plugin{
|
|
||||||
"first-root-plugin:1.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.1")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraPlugins: map[string][]Plugin{
|
|
||||||
"first-root-plugin:2.0.0": {
|
|
||||||
Must(New("first-plugin:0.0.2")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
basePlugins: map[string][]Plugin{
|
|
||||||
"invalid-plugin-name": {},
|
|
||||||
},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
debug := false
|
debug := false
|
||||||
log.SetupLogger(&debug)
|
log.SetupLogger(&debug)
|
||||||
|
|
||||||
for index, testingData := range data {
|
t.Run("happy, single root plugin with one dependent plugin", func(t *testing.T) {
|
||||||
t.Run(fmt.Sprintf("Testing %d data", index), func(t *testing.T) {
|
basePlugins := map[Plugin][]Plugin{
|
||||||
result := VerifyDependencies(testingData.basePlugins, testingData.extraPlugins)
|
Must(New("first-root-plugin:1.0.0")): {
|
||||||
assert.Equal(t, testingData.expectedResult, result)
|
Must(New("first-plugin:0.0.1")),
|
||||||
})
|
},
|
||||||
}
|
}
|
||||||
|
got := VerifyDependencies(basePlugins)
|
||||||
|
assert.Equal(t, true, got)
|
||||||
|
})
|
||||||
|
t.Run("happy, two root plugins with one depended plugin with the same version", func(t *testing.T) {
|
||||||
|
basePlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("first-root-plugin:1.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
Must(New("second-root-plugin:1.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := VerifyDependencies(basePlugins)
|
||||||
|
assert.Equal(t, true, got)
|
||||||
|
})
|
||||||
|
t.Run("fail, two root plugins have different versions", func(t *testing.T) {
|
||||||
|
basePlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("first-root-plugin:1.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
Must(New("first-root-plugin:2.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := VerifyDependencies(basePlugins)
|
||||||
|
assert.Equal(t, false, got)
|
||||||
|
})
|
||||||
|
t.Run("happy, no version collision with two sperate plugins lists", func(t *testing.T) {
|
||||||
|
basePlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("first-root-plugin:1.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
extraPlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("second-root-plugin:2.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := VerifyDependencies(basePlugins, extraPlugins)
|
||||||
|
assert.Equal(t, true, got)
|
||||||
|
})
|
||||||
|
t.Run("fail, dependent plugins have different versions", func(t *testing.T) {
|
||||||
|
basePlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("first-root-plugin:1.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
Must(New("first-root-plugin:2.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.2")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := VerifyDependencies(basePlugins)
|
||||||
|
assert.Equal(t, false, got)
|
||||||
|
})
|
||||||
|
t.Run("fail, root and dependent plugins have different versions", func(t *testing.T) {
|
||||||
|
basePlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("first-root-plugin:1.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.1")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
extraPlugins := map[Plugin][]Plugin{
|
||||||
|
Must(New("first-root-plugin:2.0.0")): {
|
||||||
|
Must(New("first-plugin:0.0.2")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := VerifyDependencies(basePlugins, extraPlugins)
|
||||||
|
assert.Equal(t, false, got)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ func TestConfiguration(t *testing.T) {
|
||||||
|
|
||||||
verifyJenkinsMasterPodAttributes(t, jenkins)
|
verifyJenkinsMasterPodAttributes(t, jenkins)
|
||||||
client := verifyJenkinsAPIConnection(t, jenkins)
|
client := verifyJenkinsAPIConnection(t, jenkins)
|
||||||
verifyBasePlugins(t, client)
|
verifyPlugins(t, client, jenkins)
|
||||||
|
|
||||||
// user
|
// user
|
||||||
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
||||||
|
|
@ -90,28 +90,48 @@ func verifyJenkinsMasterPodAttributes(t *testing.T, jenkins *v1alpha1.Jenkins) {
|
||||||
t.Log("Jenkins pod attributes are valid")
|
t.Log("Jenkins pod attributes are valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyBasePlugins(t *testing.T, jenkinsClient *gojenkins.Jenkins) {
|
func verifyPlugins(t *testing.T, jenkinsClient *gojenkins.Jenkins, jenkins *v1alpha1.Jenkins) {
|
||||||
installedPlugins, err := jenkinsClient.GetPlugins(1)
|
installedPlugins, err := jenkinsClient.GetPlugins(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for rootPluginName, p := range plugins.BasePluginsMap {
|
requiredPlugins := []map[string][]string{plugins.BasePlugins(), jenkins.Spec.Master.Plugins}
|
||||||
rootPlugin, err := plugins.New(rootPluginName)
|
for _, p := range requiredPlugins {
|
||||||
if err != nil {
|
for rootPluginName, dependentPlugins := range p {
|
||||||
t.Fatal(err)
|
rootPlugin, err := plugins.New(rootPluginName)
|
||||||
}
|
if err != nil {
|
||||||
if found, ok := isPluginValid(installedPlugins, *rootPlugin); !ok {
|
t.Fatal(err)
|
||||||
t.Fatalf("Invalid plugin '%s', actual '%+v'", rootPlugin, found)
|
}
|
||||||
}
|
if found, ok := isPluginValid(installedPlugins, *rootPlugin); !ok {
|
||||||
for _, requiredPlugin := range p {
|
t.Fatalf("Invalid plugin '%s', actual '%+v'", rootPlugin, found)
|
||||||
if found, ok := isPluginValid(installedPlugins, requiredPlugin); !ok {
|
}
|
||||||
t.Fatalf("Invalid plugin '%s', actual '%+v'", requiredPlugin, found)
|
for _, pluginName := range dependentPlugins {
|
||||||
|
plugin, err := plugins.New(pluginName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if found, ok := isPluginValid(installedPlugins, *plugin); !ok {
|
||||||
|
t.Fatalf("Invalid plugin '%s', actual '%+v'", rootPlugin, found)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Log("Base plugins have been installed")
|
t.Log("All plugins have been installed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPluginValid(plugins *gojenkins.Plugins, requiredPlugin plugins.Plugin) (*gojenkins.Plugin, bool) {
|
||||||
|
p := plugins.Contains(requiredPlugin.Name)
|
||||||
|
if p == nil {
|
||||||
|
return p, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !p.Active || !p.Enabled || p.Deleted {
|
||||||
|
return p, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, requiredPlugin.Version == p.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyJenkinsSeedJobs(t *testing.T, client *gojenkins.Jenkins, jenkins *v1alpha1.Jenkins) {
|
func verifyJenkinsSeedJobs(t *testing.T, client *gojenkins.Jenkins, jenkins *v1alpha1.Jenkins) {
|
||||||
|
|
@ -150,16 +170,3 @@ func verifyJenkinsSeedJobs(t *testing.T, client *gojenkins.Jenkins, jenkins *v1a
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPluginValid(plugins *gojenkins.Plugins, requiredPlugin plugins.Plugin) (*gojenkins.Plugin, bool) {
|
|
||||||
p := plugins.Contains(requiredPlugin.Name)
|
|
||||||
if p == nil {
|
|
||||||
return p, false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !p.Active || !p.Enabled || p.Deleted {
|
|
||||||
return p, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, requiredPlugin.Version == p.Version
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,10 @@ func createJenkinsCR(t *testing.T, namespace string) *v1alpha1.Jenkins {
|
||||||
Master: v1alpha1.JenkinsMaster{
|
Master: v1alpha1.JenkinsMaster{
|
||||||
Image: "jenkins/jenkins",
|
Image: "jenkins/jenkins",
|
||||||
Annotations: map[string]string{"test": "label"},
|
Annotations: map[string]string{"test": "label"},
|
||||||
|
Plugins: map[string][]string{
|
||||||
|
"audit-trail:2.4": {},
|
||||||
|
"simple-theme-plugin:0.5.1": {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
//TODO(bantoniak) add seed job with private key
|
//TODO(bantoniak) add seed job with private key
|
||||||
SeedJobs: []v1alpha1.SeedJob{
|
SeedJobs: []v1alpha1.SeedJob{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue