mirror of
https://github.com/jenkinsci/kubernetes-operator.git
synced 2026-10-03 14:44:23 +02:00
Improve plugins management
This commit is contained in:
@@ -106,7 +106,7 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
|
||||
}
|
||||
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 {
|
||||
return reconcile.Result{}, nil, err
|
||||
}
|
||||
@@ -187,7 +187,7 @@ func (r *ReconcileJenkinsBaseConfiguration) waitForVolumes() (reconcile.Result,
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins, basePlugins map[string][]plugins.Plugin) (bool, error) {
|
||||
func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) {
|
||||
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
||||
if err != nil {
|
||||
return false, stackerr.WithStack(err)
|
||||
@@ -201,46 +201,16 @@ func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsc
|
||||
}
|
||||
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
|
||||
allRequiredPlugins := []map[string][]plugins.Plugin{basePlugins, userPlugins}
|
||||
allRequiredPlugins := [][]v1alpha2.Plugin{r.jenkins.Spec.Master.BasePlugins, r.jenkins.Spec.Master.Plugins}
|
||||
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))
|
||||
for _, plugin := range requiredPlugins {
|
||||
if found, ok := isPluginInstalled(allPluginsInJenkins, plugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Missing plugin '%s', actual '%+v'", plugin, 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for rootPluginName, p := range userPlugins {
|
||||
rootPlugin, _ := plugins.New(rootPluginName)
|
||||
if found, ok := isPluginVersionCompatible(allPluginsInJenkins, *rootPlugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Incompatible plugin '%s' version, actual '%+v'", rootPlugin, found.Version))
|
||||
status = false
|
||||
}
|
||||
for _, requiredPlugin := range p {
|
||||
if found, ok := isPluginInstalled(allPluginsInJenkins, requiredPlugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Incompatible plugin '%s' version, actual '%+v'", requiredPlugin, found.Version))
|
||||
if found, ok := isPluginVersionCompatible(allPluginsInJenkins, plugin); !ok {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Incompatible plugin '%s' version, actual '%+v'", plugin, found.Version))
|
||||
status = false
|
||||
}
|
||||
}
|
||||
@@ -249,7 +219,7 @@ func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsc
|
||||
return status, nil
|
||||
}
|
||||
|
||||
func isPluginVersionCompatible(plugins *gojenkins.Plugins, plugin plugins.Plugin) (gojenkins.Plugin, bool) {
|
||||
func isPluginVersionCompatible(plugins *gojenkins.Plugins, plugin v1alpha2.Plugin) (gojenkins.Plugin, bool) {
|
||||
p := plugins.Contains(plugin.Name)
|
||||
if p == nil {
|
||||
return gojenkins.Plugin{}, false
|
||||
@@ -262,7 +232,7 @@ func isValidPlugin(plugin gojenkins.Plugin) bool {
|
||||
return plugin.Active && plugin.Enabled && !plugin.Deleted
|
||||
}
|
||||
|
||||
func isPluginInstalled(plugins *gojenkins.Plugins, requiredPlugin plugins.Plugin) (gojenkins.Plugin, bool) {
|
||||
func isPluginInstalled(plugins *gojenkins.Plugins, requiredPlugin v1alpha2.Plugin) (gojenkins.Plugin, bool) {
|
||||
p := plugins.Contains(requiredPlugin.Name)
|
||||
if p == nil {
|
||||
return gojenkins.Plugin{}, false
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
|
||||
"github.com/bndr/gojenkins"
|
||||
@@ -167,19 +166,67 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
pluginsInJenkins := &gojenkins.Plugins{
|
||||
Raw: &gojenkins.PluginResponse{},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("happy, not empty base and user plugins", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
BasePlugins: []v1alpha2.Plugin{{Name: "plugin-name1", Version: "0.0.1"}},
|
||||
Plugins: []v1alpha2.Plugin{{Name: "plugin-name2", Version: "0.0.1"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := ReconcileJenkinsBaseConfiguration{
|
||||
logger: log.Log,
|
||||
jenkins: jenkins,
|
||||
}
|
||||
pluginsInJenkins := &gojenkins.Plugins{
|
||||
Raw: &gojenkins.PluginResponse{
|
||||
Plugins: []gojenkins.Plugin{
|
||||
{
|
||||
ShortName: "plugin-name1",
|
||||
Active: true,
|
||||
Deleted: false,
|
||||
Enabled: true,
|
||||
Version: "0.0.1",
|
||||
},
|
||||
{
|
||||
ShortName: "plugin-name2",
|
||||
Active: true,
|
||||
Deleted: false,
|
||||
Enabled: true,
|
||||
Version: "0.0.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("happy, not empty base and empty user plugins", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{}
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
BasePlugins: []v1alpha2.Plugin{{Name: "plugin-name", Version: "0.0.1"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := ReconcileJenkinsBaseConfiguration{
|
||||
logger: log.Log,
|
||||
jenkins: jenkins,
|
||||
@@ -197,15 +244,12 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{
|
||||
"plugin-name:0.0.1": {},
|
||||
}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, got)
|
||||
@@ -214,7 +258,7 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
Plugins: map[string][]string{"plugin-name:0.0.1": {}},
|
||||
Plugins: []v1alpha2.Plugin{{Name: "plugin-name", Version: "0.0.1"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -235,19 +279,24 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("happy, plugin version doesn't matter for base plugins", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{}
|
||||
t.Run("happy, plugin version matter for base plugins", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
BasePlugins: []v1alpha2.Plugin{{Name: "plugin-name", Version: "0.0.1"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := ReconcileJenkinsBaseConfiguration{
|
||||
logger: log.Log,
|
||||
jenkins: jenkins,
|
||||
@@ -265,24 +314,21 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{
|
||||
"plugin-name:0.0.1": {},
|
||||
}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, got)
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("plugin version matter for user plugins", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
Plugins: map[string][]string{"plugin-name:0.0.2": {}},
|
||||
Plugins: []v1alpha2.Plugin{{Name: "plugin-name", Version: "0.0.2"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -303,46 +349,21 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("missing base plugin", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{}
|
||||
r := ReconcileJenkinsBaseConfiguration{
|
||||
logger: log.Log,
|
||||
jenkins: jenkins,
|
||||
}
|
||||
pluginsInJenkins := &gojenkins.Plugins{
|
||||
Raw: &gojenkins.PluginResponse{
|
||||
Plugins: []gojenkins.Plugin{},
|
||||
},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{
|
||||
"plugin-name:0.0.2": {},
|
||||
}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("missing user plugin", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
Plugins: map[string][]string{"plugin-name:0.0.2": {}},
|
||||
BasePlugins: []v1alpha2.Plugin{{Name: "plugin-name", Version: "0.0.2"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -355,13 +376,39 @@ func TestReconcileJenkinsBaseConfiguration_verifyPlugins(t *testing.T) {
|
||||
Plugins: []gojenkins.Plugin{},
|
||||
},
|
||||
}
|
||||
basePlugins := map[string][]plugins.Plugin{}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient, basePlugins)
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("missing user plugin", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
Plugins: []v1alpha2.Plugin{{Name: "plugin-name", Version: "0.0.2"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := ReconcileJenkinsBaseConfiguration{
|
||||
logger: log.Log,
|
||||
jenkins: jenkins,
|
||||
}
|
||||
pluginsInJenkins := &gojenkins.Plugins{
|
||||
Raw: &gojenkins.PluginResponse{
|
||||
Plugins: []gojenkins.Plugin{},
|
||||
},
|
||||
}
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
jenkinsClient := client.NewMockJenkins(ctrl)
|
||||
jenkinsClient.EXPECT().GetPlugins(fetchAllPlugins).Return(pluginsInJenkins, nil)
|
||||
|
||||
got, err := r.verifyPlugins(jenkinsClient)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, got)
|
||||
|
||||
@@ -94,7 +94,9 @@ def remove = { list ->
|
||||
remove(jenkins.getExtensionList(RootAction.class))
|
||||
remove(jenkins.actions)
|
||||
|
||||
jenkins.getDescriptor("jenkins.CLI").get().setEnabled(false)
|
||||
if (jenkins.getDescriptor("jenkins.CLI") != null) {
|
||||
jenkins.getDescriptor("jenkins.CLI").get().setEnabled(false)
|
||||
}
|
||||
|
||||
jenkins.save()
|
||||
`
|
||||
|
||||
@@ -255,17 +255,11 @@ chmod +x {{ .JenkinsHomePath }}/scripts/*.sh
|
||||
{{- $installPluginsCommand := .InstallPluginsCommand }}
|
||||
|
||||
echo "Installing plugins required by Operator - begin"
|
||||
{{- range $rootPluginName, $plugins := .OperatorPlugins }}
|
||||
echo "Installing required plugins for '{{ $rootPluginName }}'"
|
||||
{{ $jenkinsHomePath }}/scripts/{{ $installPluginsCommand }} {{ $rootPluginName }} {{ range $index, $plugin := $plugins }}{{ . }} {{ end }}
|
||||
{{- end }}
|
||||
{{ $installPluginsCommand }} {{ range $index, $plugin := .BasePlugins }}{{ $plugin.Name }}:{{ $plugin.Version }} {{ 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 }}
|
||||
{{ $installPluginsCommand }} {{ range $index, $plugin := .UserPlugins }}{{ $plugin.Name }}:{{ $plugin.Version }} {{ end }}
|
||||
echo "Installing plugins required by user - end"
|
||||
|
||||
/sbin/tini -s -- /usr/local/bin/jenkins.sh
|
||||
@@ -284,12 +278,12 @@ func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) {
|
||||
InitConfigurationPath string
|
||||
InstallPluginsCommand string
|
||||
JenkinsScriptsVolumePath string
|
||||
OperatorPlugins map[string][]string
|
||||
UserPlugins map[string][]string
|
||||
BasePlugins []v1alpha2.Plugin
|
||||
UserPlugins []v1alpha2.Plugin
|
||||
}{
|
||||
JenkinsHomePath: jenkinsHomePath,
|
||||
InitConfigurationPath: jenkinsInitConfigurationVolumePath,
|
||||
OperatorPlugins: jenkins.Spec.Master.OperatorPlugins,
|
||||
BasePlugins: jenkins.Spec.Master.BasePlugins,
|
||||
UserPlugins: jenkins.Spec.Master.Plugins,
|
||||
InstallPluginsCommand: installPluginsCommand,
|
||||
JenkinsScriptsVolumePath: jenkinsScriptsVolumePath,
|
||||
|
||||
@@ -42,7 +42,7 @@ func (r *ReconcileJenkinsBaseConfiguration) Validate(jenkins *v1alpha2.Jenkins)
|
||||
}
|
||||
}
|
||||
|
||||
if !r.validatePlugins(jenkins.Spec.Master.OperatorPlugins, jenkins.Spec.Master.Plugins) {
|
||||
if !r.validatePlugins(plugins.BasePlugins(), jenkins.Spec.Master.BasePlugins, jenkins.Spec.Master.Plugins) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -215,36 +215,60 @@ func (r *ReconcileJenkinsBaseConfiguration) validateJenkinsMasterPodEnvs() bool
|
||||
return valid
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) validatePlugins(pluginsWithVersionSlice ...map[string][]string) bool {
|
||||
func (r *ReconcileJenkinsBaseConfiguration) validatePlugins(requiredBasePlugins []plugins.Plugin, basePlugins, userPlugins []v1alpha2.Plugin) bool {
|
||||
valid := true
|
||||
allPlugins := map[plugins.Plugin][]plugins.Plugin{}
|
||||
|
||||
for _, pluginsWithVersions := range pluginsWithVersionSlice {
|
||||
for rootPluginName, dependentPluginNames := range pluginsWithVersions {
|
||||
rootPlugin, err := plugins.New(rootPluginName)
|
||||
if err != nil {
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Invalid root plugin name '%s'", rootPluginName))
|
||||
valid = false
|
||||
}
|
||||
for _, jenkinsPlugin := range basePlugins {
|
||||
plugin, err := plugins.NewPlugin(jenkinsPlugin.Name, jenkinsPlugin.Version)
|
||||
if err != nil {
|
||||
r.logger.V(log.VWarn).Info(err.Error())
|
||||
valid = false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if plugin != nil {
|
||||
allPlugins[*plugin] = []plugins.Plugin{}
|
||||
}
|
||||
}
|
||||
|
||||
if valid {
|
||||
return plugins.VerifyDependencies(allPlugins)
|
||||
for _, jenkinsPlugin := range userPlugins {
|
||||
plugin, err := plugins.NewPlugin(jenkinsPlugin.Name, jenkinsPlugin.Version)
|
||||
if err != nil {
|
||||
r.logger.V(log.VWarn).Info(err.Error())
|
||||
valid = false
|
||||
}
|
||||
|
||||
if plugin != nil {
|
||||
allPlugins[*plugin] = []plugins.Plugin{}
|
||||
}
|
||||
}
|
||||
|
||||
if !plugins.VerifyDependencies(allPlugins) {
|
||||
valid = false
|
||||
}
|
||||
|
||||
if !r.verifyBasePlugins(requiredBasePlugins, basePlugins) {
|
||||
valid = false
|
||||
}
|
||||
|
||||
return valid
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) verifyBasePlugins(requiredBasePlugins []plugins.Plugin, basePlugins []v1alpha2.Plugin) bool {
|
||||
valid := true
|
||||
|
||||
for _, requiredBasePlugin := range requiredBasePlugins {
|
||||
found := false
|
||||
for _, basePlugin := range basePlugins {
|
||||
if requiredBasePlugin.Name == basePlugin.Name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
valid = false
|
||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Missing plugin '%s' in spec.master.basePlugins", requiredBasePlugin.Name))
|
||||
}
|
||||
}
|
||||
|
||||
return valid
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/api/core/v1"
|
||||
@@ -16,62 +18,117 @@ import (
|
||||
)
|
||||
|
||||
func TestValidatePlugins(t *testing.T) {
|
||||
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
|
||||
log.SetupLogger(true)
|
||||
baseReconcileLoop := New(nil, nil, log.Log,
|
||||
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)
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
var basePlugins []v1alpha2.Plugin
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("valid user plugin", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
var basePlugins []v1alpha2.Plugin
|
||||
userPlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("invalid user plugin name", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
var basePlugins []v1alpha2.Plugin
|
||||
userPlugins := []v1alpha2.Plugin{{Name: "INVALID", Version: "0.0.1"}}
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("invalid user plugin version", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
var basePlugins []v1alpha2.Plugin
|
||||
userPlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "invalid"}}
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("valid base plugin", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("invalid base plugin name", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "INVALID", Version: "0.0.1"}}
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("invalid base plugin version", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "invalid"}}
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("valid user and base plugin version", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
userPlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("invalid user and base plugin version", func(t *testing.T) {
|
||||
var requiredBasePlugins []plugins.Plugin
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
userPlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.2"}}
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.False(t, got)
|
||||
})
|
||||
t.Run("required base plugin set with the same version", func(t *testing.T) {
|
||||
requiredBasePlugins := []plugins.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("required base plugin set with different version", func(t *testing.T) {
|
||||
requiredBasePlugins := []plugins.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
basePlugins := []v1alpha2.Plugin{{Name: "simple-plugin", Version: "0.0.2"}}
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.True(t, got)
|
||||
})
|
||||
t.Run("missign required base plugin", func(t *testing.T) {
|
||||
requiredBasePlugins := []plugins.Plugin{{Name: "simple-plugin", Version: "0.0.1"}}
|
||||
var basePlugins []v1alpha2.Plugin
|
||||
var userPlugins []v1alpha2.Plugin
|
||||
|
||||
got := baseReconcileLoop.validatePlugins(requiredBasePlugins, basePlugins, userPlugins)
|
||||
|
||||
assert.False(t, got)
|
||||
})
|
||||
}
|
||||
|
||||
func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
|
||||
|
||||
@@ -262,15 +262,15 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
|
||||
FailureThreshold: int32(12),
|
||||
}
|
||||
}
|
||||
if len(jenkins.Spec.Master.OperatorPlugins) == 0 {
|
||||
if len(jenkins.Spec.Master.BasePlugins) == 0 {
|
||||
logger.Info("Setting default operator plugins")
|
||||
changed = true
|
||||
jenkins.Spec.Master.OperatorPlugins = plugins.BasePlugins()
|
||||
jenkins.Spec.Master.BasePlugins = basePlugins()
|
||||
}
|
||||
if len(jenkins.Status.OperatorVersion) > 0 && version.Version != jenkins.Status.OperatorVersion {
|
||||
logger.Info("Setting default operator plugins after Operator version change")
|
||||
changed = true
|
||||
jenkins.Spec.Master.OperatorPlugins = plugins.BasePlugins()
|
||||
jenkins.Spec.Master.BasePlugins = basePlugins()
|
||||
}
|
||||
if len(jenkins.Status.OperatorVersion) == 0 {
|
||||
logger.Info("Setting operator version")
|
||||
@@ -279,7 +279,7 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
|
||||
}
|
||||
if len(jenkins.Spec.Master.Plugins) == 0 {
|
||||
changed = true
|
||||
jenkins.Spec.Master.Plugins = map[string][]string{"simple-theme-plugin:0.5.1": {}}
|
||||
jenkins.Spec.Master.Plugins = []v1alpha2.Plugin{{Name: "simple-theme-plugin", Version: "0.5.1"}}
|
||||
}
|
||||
if isResourceRequirementsNotSet(jenkins.Spec.Master.Resources) {
|
||||
logger.Info("Setting default Jenkins master container resource requirements")
|
||||
@@ -365,3 +365,10 @@ func isResourceRequirementsNotSet(requirements corev1.ResourceRequirements) bool
|
||||
|
||||
return !limitCPUSet || !limitMemorySet || !requestCPUSet || !requestMemporySet
|
||||
}
|
||||
|
||||
func basePlugins() (result []v1alpha2.Plugin) {
|
||||
for _, value := range plugins.BasePlugins() {
|
||||
result = append(result, v1alpha2.Plugin{Name: value.Name, Version: value.Version})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,180 +1,29 @@
|
||||
package plugins
|
||||
|
||||
const (
|
||||
aceEditorPlugin = "ace-editor:1.1"
|
||||
apacheComponentsClientPlugin = "apache-httpcomponents-client-4-api:4.5.5-3.0"
|
||||
authenticationTokensPlugin = "authentication-tokens:1.3"
|
||||
branchAPIPlugin = "branch-api:2.5.2"
|
||||
cloudBeesFolderPlugin = "cloudbees-folder:6.8"
|
||||
configurationAsCodePlugin = "configuration-as-code:1.17"
|
||||
configurationAsCodeSupportPlugin = "configuration-as-code-support:1.17"
|
||||
credentialsBindingPlugin = "credentials-binding:1.18"
|
||||
credentialsPlugin = "credentials:2.1.19"
|
||||
displayURLAPIPlugin = "display-url-api:2.3.1"
|
||||
dockerCommonsPlugin = "docker-commons:1.15"
|
||||
dockerWorkflowPlugin = "docker-workflow:1.18"
|
||||
durableTaskPlugin = "durable-task:1.29"
|
||||
gitClientPlugin = "git-client:2.7.7"
|
||||
configurationAsCodePlugin = "configuration-as-code:1.19"
|
||||
configurationAsCodeSupportPlugin = "configuration-as-code-support:1.19"
|
||||
gitPlugin = "git:3.10.0"
|
||||
gitServerPlugin = "git-server:1.7"
|
||||
handlebarsPlugin = "handlebars:1.1.1"
|
||||
jackson2ADIPlugin = "jackson2-api:2.9.9"
|
||||
jobDslPlugin = "job-dsl:1.74"
|
||||
jqueryDetachedPlugin = "jquery-detached:1.2.1"
|
||||
jschPlugin = "jsch:0.1.55"
|
||||
junitPlugin = "junit:1.28"
|
||||
kubernetesCredentialsPlugin = "kubernetes-credentials:0.4.0"
|
||||
kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:0.12.1"
|
||||
kubernetesPlugin = "kubernetes:1.15.5"
|
||||
lockableResourcesPlugin = "lockable-resources:2.5"
|
||||
mailerPlugin = "mailer:1.23"
|
||||
matrixProjectPlugin = "matrix-project:1.14"
|
||||
momentjsPlugin = "momentjs:1.1.1"
|
||||
pipelineBuildStepPlugin = "pipeline-build-step:2.9"
|
||||
pipelineGraphAnalysisPlugin = "pipeline-graph-analysis:1.10"
|
||||
pipelineInputStepPlugin = "pipeline-input-step:2.10"
|
||||
pipelineMilestoneStepPlugin = "pipeline-milestone-step:1.3.1"
|
||||
pipelineModelAPIPlugin = "pipeline-model-api:1.3.8"
|
||||
pipelineModelDeclarativeAgentPlugin = "pipeline-model-declarative-agent:1.1.1"
|
||||
pipelineModelDefinitionPlugin = "pipeline-model-definition:1.3.8"
|
||||
pipelineModelExtensionsPlugin = "pipeline-model-extensions:1.3.8"
|
||||
pipelineRestAPIPlugin = "pipeline-rest-api:2.11"
|
||||
pipelineStageStepPlugin = "pipeline-stage-step:2.3"
|
||||
pipelineStageTagsMetadataPlugin = "pipeline-stage-tags-metadata:1.3.8"
|
||||
pipelineStageViewPlugin = "pipeline-stage-view:2.11"
|
||||
plainCredentialsPlugin = "plain-credentials:1.5"
|
||||
scmAPIPlugin = "scm-api:2.4.1"
|
||||
scriptSecurityPlugin = "script-security:1.59"
|
||||
sshCredentialsPlugin = "ssh-credentials:1.16"
|
||||
structsPlugin = "structs:1.19"
|
||||
variantPlugin = "variant:1.2"
|
||||
kubernetesPlugin = "kubernetes:1.15.7"
|
||||
workflowAggregatorPlugin = "workflow-aggregator:2.6"
|
||||
workflowAPIPlugin = "workflow-api:2.34"
|
||||
workflowBasicStepsPlugin = "workflow-basic-steps:2.16"
|
||||
workflowCpsGlobalLibPlugin = "workflow-cps-global-lib:2.13"
|
||||
workflowCpsPlugin = "workflow-cps:2.69"
|
||||
workflowDurableTaskStepPlugin = "workflow-durable-task-step:2.30"
|
||||
workflowJobPlugin = "workflow-job:2.32"
|
||||
workflowMultibranchPlugin = "workflow-multibranch:2.21"
|
||||
workflowSCMStepPlugin = "workflow-scm-step:2.7"
|
||||
workflowStepAPIPlugin = "workflow-step-api:2.19"
|
||||
workflowSupportPlugin = "workflow-support:3.3"
|
||||
)
|
||||
|
||||
// BasePluginsMap contains plugins to install by operator
|
||||
var BasePluginsMap = map[string][]Plugin{
|
||||
Must(New(kubernetesPlugin)).String(): {
|
||||
Must(New(apacheComponentsClientPlugin)),
|
||||
Must(New(cloudBeesFolderPlugin)),
|
||||
Must(New(credentialsPlugin)),
|
||||
Must(New(durableTaskPlugin)),
|
||||
Must(New(jackson2ADIPlugin)),
|
||||
Must(New(kubernetesCredentialsPlugin)),
|
||||
Must(New(plainCredentialsPlugin)),
|
||||
Must(New(structsPlugin)),
|
||||
Must(New(variantPlugin)),
|
||||
Must(New(workflowStepAPIPlugin)),
|
||||
},
|
||||
Must(New(workflowJobPlugin)).String(): {
|
||||
Must(New(scmAPIPlugin)),
|
||||
Must(New(scriptSecurityPlugin)),
|
||||
Must(New(structsPlugin)),
|
||||
Must(New(workflowAPIPlugin)),
|
||||
Must(New(workflowStepAPIPlugin)),
|
||||
Must(New(workflowSupportPlugin)),
|
||||
},
|
||||
Must(New(workflowAggregatorPlugin)).String(): {
|
||||
Must(New(aceEditorPlugin)),
|
||||
Must(New(apacheComponentsClientPlugin)),
|
||||
Must(New(authenticationTokensPlugin)),
|
||||
Must(New(branchAPIPlugin)),
|
||||
Must(New(cloudBeesFolderPlugin)),
|
||||
Must(New(credentialsBindingPlugin)),
|
||||
Must(New(credentialsPlugin)),
|
||||
Must(New(displayURLAPIPlugin)),
|
||||
Must(New(dockerCommonsPlugin)),
|
||||
Must(New(dockerWorkflowPlugin)),
|
||||
Must(New(durableTaskPlugin)),
|
||||
Must(New(gitClientPlugin)),
|
||||
Must(New(gitServerPlugin)),
|
||||
Must(New(handlebarsPlugin)),
|
||||
Must(New(jackson2ADIPlugin)),
|
||||
Must(New(jqueryDetachedPlugin)),
|
||||
Must(New(jschPlugin)),
|
||||
Must(New(junitPlugin)),
|
||||
Must(New(lockableResourcesPlugin)),
|
||||
Must(New(mailerPlugin)),
|
||||
Must(New(matrixProjectPlugin)),
|
||||
Must(New(momentjsPlugin)),
|
||||
Must(New(pipelineBuildStepPlugin)),
|
||||
Must(New(pipelineGraphAnalysisPlugin)),
|
||||
Must(New(pipelineInputStepPlugin)),
|
||||
Must(New(pipelineMilestoneStepPlugin)),
|
||||
Must(New(pipelineModelAPIPlugin)),
|
||||
Must(New(pipelineModelDeclarativeAgentPlugin)),
|
||||
Must(New(pipelineModelDefinitionPlugin)),
|
||||
Must(New(pipelineModelExtensionsPlugin)),
|
||||
Must(New(pipelineRestAPIPlugin)),
|
||||
Must(New(pipelineStageStepPlugin)),
|
||||
Must(New(pipelineStageTagsMetadataPlugin)),
|
||||
Must(New(pipelineStageViewPlugin)),
|
||||
Must(New(plainCredentialsPlugin)),
|
||||
Must(New(scmAPIPlugin)),
|
||||
Must(New(scriptSecurityPlugin)),
|
||||
Must(New(sshCredentialsPlugin)),
|
||||
Must(New(structsPlugin)),
|
||||
Must(New(workflowAPIPlugin)),
|
||||
Must(New(workflowBasicStepsPlugin)),
|
||||
Must(New(workflowCpsGlobalLibPlugin)),
|
||||
Must(New(workflowCpsPlugin)),
|
||||
Must(New(workflowDurableTaskStepPlugin)),
|
||||
Must(New(workflowJobPlugin)),
|
||||
Must(New(workflowMultibranchPlugin)),
|
||||
Must(New(workflowSCMStepPlugin)),
|
||||
Must(New(workflowStepAPIPlugin)),
|
||||
Must(New(workflowSupportPlugin)),
|
||||
},
|
||||
Must(New(gitPlugin)).String(): {
|
||||
Must(New(apacheComponentsClientPlugin)),
|
||||
Must(New(credentialsPlugin)),
|
||||
Must(New(displayURLAPIPlugin)),
|
||||
Must(New(gitClientPlugin)),
|
||||
Must(New(jschPlugin)),
|
||||
Must(New(junitPlugin)),
|
||||
Must(New(mailerPlugin)),
|
||||
Must(New(matrixProjectPlugin)),
|
||||
Must(New(scmAPIPlugin)),
|
||||
Must(New(scriptSecurityPlugin)),
|
||||
Must(New(sshCredentialsPlugin)),
|
||||
Must(New(structsPlugin)),
|
||||
Must(New(workflowAPIPlugin)),
|
||||
Must(New(workflowSCMStepPlugin)),
|
||||
Must(New(workflowStepAPIPlugin)),
|
||||
},
|
||||
Must(New(jobDslPlugin)).String(): {
|
||||
Must(New(scriptSecurityPlugin)),
|
||||
Must(New(structsPlugin)),
|
||||
},
|
||||
Must(New(configurationAsCodePlugin)).String(): {
|
||||
Must(New(configurationAsCodeSupportPlugin)),
|
||||
},
|
||||
Must(New(kubernetesCredentialsProviderPlugin)).String(): {
|
||||
Must(New(credentialsPlugin)),
|
||||
Must(New(structsPlugin)),
|
||||
Must(New(variantPlugin)),
|
||||
},
|
||||
// basePluginsList contains plugins to install by operator
|
||||
var basePluginsList = []Plugin{
|
||||
Must(New(kubernetesPlugin)),
|
||||
Must(New(workflowJobPlugin)),
|
||||
Must(New(workflowAggregatorPlugin)),
|
||||
Must(New(gitPlugin)),
|
||||
Must(New(jobDslPlugin)),
|
||||
Must(New(configurationAsCodePlugin)),
|
||||
Must(New(configurationAsCodeSupportPlugin)),
|
||||
Must(New(kubernetesCredentialsProviderPlugin)),
|
||||
}
|
||||
|
||||
// BasePlugins returns map of plugins to install by operator
|
||||
func BasePlugins() (plugins map[string][]string) {
|
||||
plugins = map[string][]string{}
|
||||
|
||||
for rootPluginName, dependentPlugins := range BasePluginsMap {
|
||||
plugins[rootPluginName] = []string{}
|
||||
for _, pluginName := range dependentPlugins {
|
||||
plugins[rootPluginName] = append(plugins[rootPluginName], pluginName.String())
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
// BasePlugins returns list of plugins to install by operator
|
||||
func BasePlugins() []Plugin {
|
||||
return basePluginsList
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package plugins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
@@ -20,18 +21,52 @@ func (p Plugin) String() string {
|
||||
return fmt.Sprintf("%s:%s", p.Name, p.Version)
|
||||
}
|
||||
|
||||
var (
|
||||
namePattern = regexp.MustCompile(`^[0-9a-z-]+$`)
|
||||
versionPattern = regexp.MustCompile(`^[0-9\\.]+$`)
|
||||
)
|
||||
|
||||
// New creates plugin from string, for example "name-of-plugin:0.0.1"
|
||||
func New(nameWithVersion string) (*Plugin, error) {
|
||||
val := strings.SplitN(nameWithVersion, ":", 2)
|
||||
if val == nil || len(val) != 2 {
|
||||
return nil, errors.Errorf("invalid plugin format '%s'", nameWithVersion)
|
||||
}
|
||||
name := val[0]
|
||||
version := val[1]
|
||||
|
||||
if err := validatePlugin(name, version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Plugin{
|
||||
Name: val[0],
|
||||
Version: val[1],
|
||||
Name: name,
|
||||
Version: version,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPlugin creates plugin from name and version, for example "name-of-plugin:0.0.1"
|
||||
func NewPlugin(name, version string) (*Plugin, error) {
|
||||
if err := validatePlugin(name, version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Plugin{
|
||||
Name: name,
|
||||
Version: version,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func validatePlugin(name, version string) error {
|
||||
if ok := namePattern.MatchString(name); !ok {
|
||||
return errors.Errorf("invalid plugin name '%s:%s', must follow pattern '%s'", name, version, namePattern.String())
|
||||
}
|
||||
if ok := versionPattern.MatchString(version); !ok {
|
||||
return errors.Errorf("invalid plugin version '%s:%s', must follow pattern '%s'", name, version, versionPattern.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Must returns plugin from pointer and throws panic when error is set
|
||||
func Must(plugin *Plugin, err error) Plugin {
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user